Arduino ADC Readings Innacurate due to Hardware and Software?

Hello, Arduino Community!

I wasn't able to provide the circuit schematics on my last post (last, last week) and I think that updating it would make it more convoluted. I really wanted to put things to an end for this particular matter. So again, I'm trying to design a wireless fire alarm prototype using ZigBee and Arduino Pro Mini. My circuit is as follows in the attached image.

My problem is that despite using some calibration and software filtering techniques, my ADC readings for monitoring the battery voltage are still inaccurate. I believe it comes from the hardware and the software as well from all that I've read online.

I've been using bypass caps on every other component and on the power lines for the Arduino but the noise still persists. I kind of gave up and removed every cap I have on the circuit. Readings were quite good (+-0.02-0.06 V diff. vs. multimeter) the first time but after a few days of testing and by charging the battery simultaneously while measuring, readings have become even worse. I have little to no electronics background and have no oscilloscope. Kind of sucks. Sorry

I've read about filters (RC) online and tried them by doing slight calculations and random choice of caps from the smallest ones and seeing which one had the best result. However, I really wanted to know how to use them on any circuit. I've also read the software also affects the RC values as well. Too bad I don't have an oscilloscope with me. :frowning:

So my questions are:

  1. How do I choose the component values of my RC circuit?
  2. What frequencies do I have to take in mind? The sampling frequency of my ADC or the noise which I want to cut off? If both, how should I implement the solution?
  3. How does software affect ADC measurements? (I've read ones like digitalWrite particularly at high frequencies do some serious noise)
  4. What are my possible approaches to this?

Thank you very much. I'm sorry but it obviously seems I am asking for much but I really have a lot of questions in mind.

Photos are in my drive on high resolution. :slight_smile:

...wireless fire alarm...

To be sold or for personal use? If it is to be sold, I suggest you check into the building code requirements for fire alarm systems.

It’s for a prototype I was trying to design for a project. I understand that I’m just a newb and by any means I have no intention for doing that because it’s a risk and it’s not going to be reliable as commercial fire alarms.

Despite that, I’m adapting standards/protocols in my code from NFPA72, UL268 and UL251 just to show that it somehow “works”. :slight_smile:

Perhaps I may have missed your point, but there's nothing there that specified much about the hardware except the functional delays, reboots, alarm deactivation, low power trouble alerts, etc.

What sensor are you reading that is "providing" the noise? Do you know it is the Arduino or is it the sensor? What is the frequency of the signal you are trying to measure? You measure battery, which is DC (0Hz). You can filter out a lot of frequencies if your signal is so slow as to be considered DC. The problem will be response time. The more frequencies you cut off, the slow the filter will be to respond to slight changes in the signal.

Without an oscilloscope it is going to be difficult to identify the source, frequency, and amplitude of the noise as well as after you have made changes to see if they had any effect, positive or negative.

What signals besides the battery are you looking at? That will also help determine how often you will need to sample (it is not always necessary to take a sample because you can). If it is just the battery, can you take infrequent samples far enough apart that you can stop the outputs from changing while taking the same (assuming the DI pins changes are a source of your problems).

The ADC could be accurate and stable +/- 1 count as long as the reference is accurate and stable. The default reference is 5V (Vcc) which is powering your Arduino. If your 5V is not stable, you can use the optional internal 1.1V reference and scale-down the voltage you're measuring with a voltage divider (2 resistors).

If the voltage you're trying to measure is noise (maybe from the charging circuit or maybe because something is switching) the real meter may react differently to the noise than the Arduino.

Hey, thank you for your replies. I’m measuring the temperature and battery voltage so far. Another input is the manual fire alarm button, where the Arduino should count up to 3 seconds or more to generate an alarm. Ten readings are sampled and averaged for the temp readings with some delays in between, while I only sample once for measuring battery voltage using the 15 ms ADC noise reduction mode after 30 counts with no delays, so it isn’t really much fast. I only need very small delays because timing is essential for input especially for the button, since I noticed that any delay in the input affects the “counting” my buzzer produces.

Soon, I’ll be integrating a smoke detector circuit using the HIS-07 ionization smoke sensor and A5368 IC with some caps and resistors thrown in. The circuit will be outputting a digital signal whenever it detects smoke, and I dunno if it’s gonna generate pulses at very short intervals, which may cause additional noise.

Yeah, it feels kind of blinded not having any electronic tool to help you out in your project, except the multimeter I brought with me. They (scopes) are just so expensive and not just everyone lends you those.

I could see that my XBee provides a noise of about +0.05 V or 0.5V. I think it’s the latter and that’s something to be worried about. I’m using a room thermometer to compare with my LM35 readings, and that happens usually whenever I try to plug the XBee into the board. Have you seen my diagram in the link? I think I have found a way to make it smaller, so here it is attached.

Do you want to see the summary of my code? It has a lot of functions in it and goes through a lot of them.

I used a lot of libraries, such as the Battery Sense and Voltage Reference (I also followed the calibration tutorial with the multimeter on the GitHub page). I have included a ResponsiveAnalog library but I didn't find it compatible with the two. I dunno if combining functions of different libraries would make it any better.

Okay. I'll try to use the 1.1 V reference but is it any better than the 5 V reference? I already have a 0.9-5V Step Up boost converter like here:

And won't your voltage divider resistors tolerance affect accuracy? I'll try about that. Thank you

Chinese boost converters (and buck converters too) are notoriously noisy and are not suitable for analog applications. The schematic is missing any ground connection to the Nano and the multiple earth symbols leads me to believe that proper wiring is not present which adds yet more noise.

Start with batteries or clean analog power supplies for the required voltages, wire the grounds properly in a star fashion, not some haphazard series chain and then get back to us about analog inaccuracies...

Oh, one more thing. Add a resistor in series with your annunciatior led before you destroy the Nano.

Thank you very much ;D But I would like to ask, can you suggest anything where I could learn more about designing the circuit or the breadboard phase? I'm already looking for sources online but do you have any recommendations?

A useful rule of thumb is to connect all earths separately to a single point - don't 'daisy chain' earth connections.


I'll try to use the 1.1 V reference but is it any better than the 5 V reference?

Yes! The 5V line has every bit of noise induced into the power rail.

Do you have an RC lowpass filter between 5V and the AVcc pin? Probably not. It is recommended in the datasheet for the AVR, but the Arduino was designed without it.

Do you have a bypass capacitor from the Aref pin to ground? You should, whether you use the default Vcc for a reference or the internal reference. Again, recommended in the datasheet, not included in the Arduino.

The internal 1.1V reference is not very accurate, but it is stable. In other words, it is not exactly 1.1V and will vary from AVR to AVR, but it will stay the same. You have to calibrate anyway, and it won't change with changes in the 5V rail.

You need a good quality linear regulator generating the 5V rail if using that as the analog reference, not
a boost converter, which can have far worse regulation. At the very least something with a datasheet you
can consult for the regulation accuracy figure.

I'd suggest monitoring the 5V rail with the multimeter over time to check this hypothesis - the ADC only
measures the voltage ratio between the analog pin and AREF, and for the ATmega328 in my experience
its very good.