Hey everyone - I have a fairly simple question. One of my project objectives is to log the voltage on an automotive battery. I'm using a voltage divider the drop the current, reading it in to an Arduino Nano, and then calculating the voltage from the analog input value.
Ok this works fine. But I'm getting a fairly unstable reading. It's 12.55 then 12.80 then 12.60.. It's a different value every time it's read. This isn't very useful.
Must be noise in the ADC then. Ok - so I buy a 16 bit adafruit ADS1115 module.
Things get better. But.. it's still noisy. 12.24, 12.26, 12.26, 12.27, 12.26.. But it's far from my goal of 5 (or so) digit precision. I can hardly get 1 digit of precision.
Let me add - the battery is not connected to anything. Except for the 2 resistor voltage divider.
What gives? I'm able to get a stable reading with a multimeter. Why can't I get any precision with a MCU? I've reached the limits of my expertise here and it's kind of driving me nuts.
I am aware that I could simply take some readings over time and average them out. But that would slow down the response time and it would increase power usage. I'd like to find a direct way to get stable reading.
Its in the nature of an automotive battery that the voltage will vary a little especially if a current is flowing.
12.24, 12.26, 12.26, 12.27, 12.26.. But it's far from my goal of 5 (or so) digit precision. I can hardly get 1 digit of precision.
12.24 IS 4 digits of precision. I dont see why you want to achieve more than the 10 bit resolution you can get with the nano, as it wont tell you anything useful about the battery.
NANO: It's 12.55 then 12.80 then 12.60.. It's a different value every time it's read.
You dont say what reference you used on the NANO to measure the voltage.
The only reason the ADS board is giving less variable readings is because the ADC is a sigma-delta conversion which is a much slower conversion process so "smooths out" the noise.
You can do the same with the nano by time-averaging the readings.
But that would slow down the response time
and
it would increase power usage.
What time interval do you propse to log samples? And what will you do with all that data?
In use the battery will be supplying current, or charging from the alternator, and the voltage will change a LOT.
Basically the reason you cant achieve your expectations is because they are unrealistic.
You could be picking up interference, for example mains hum, in your input circuit. Please post full schematics and complete images of your wiring. All we know now is "a voltage divider".
I am aware that I could simply take some readings over time and average them out. But that would slow down the response time and it would increase power usage. I'd like to find a direct way to get stable reading.
This statement implies the OP has some misconceptions. One, while a rolling average does have an initial delay for the first measurement but it them becomes the sample time. Old sample falls of the end, new is added, average calculated and you have a new reading at the sample rate.
Two, power usage? What power usage? The OP needs to explain this as it makes no sense in the context of what he’s doing.
This is not a ADC noise
The first thing is; put your arduino in metal box, connect arduino A0 pin through 1 or 10k resistor to battery using shielded wire. Also connect capacitors A0 to ground.
5 cm of no shielded wire can pick up the noise,
If you are using the default Vcc/5V reference, power supply noise/variations will give you noise/variations in the ADC reading.
The Adafruit ADC has a built-in reference. (The Arduino has an optional internal reference and it's super-stable but but not necessarily accurate so you might have to calibrate it.)
Higher input impedance is more prone to noise pick-up (EMI interference) so higher value voltage-divider resistors will allow for more noise.
Longer wires and unshielded wires are also more prone to noise pick-up.
But it's far from my goal of 5 (or so) digit precision.
That's asking a lot! I have two Fluke multimeters that I use at work. One is 4-digits and one is 5 digits.* There is almost always some instability in the readings and I'm sure they are not guaranteed accurate to the last digit.
That might not be completely true... The most significant digit might only be "1' or "0". They call that a "3.5" digit" or "4.5 digit" meter.
I think it's important to note that precision in this context is synonymous with accuracy. We can select a multimetrer as a known truth with a stable reading of 2 decimal places. Every time you connect the multimeter, you get exactly the same reading.
Granted - the multimeter could have some margin of error too. It probably does. But that doesn't mater. It's our reference truth since the value is stable each time a sample is taken.
The difference with the MCU is that I'll get readings of 12.55 then 12.80 then 12.60 - etc. It's not possible that the battery voltage can vary that much every 1000ms. A multimeter on the same battery will have a stable measurement every time. So you can come to the conclusion that there must be some error in the MCU measurement.
WattsThat:
This statement implies the OP has some misconceptions. One, while a rolling average does have an initial delay for the first measurement but it them becomes the sample time. Old sample falls of the end, new is added, average calculated and you have a new reading at the sample rate.
Two, power usage? What power usage? The OP needs to explain this as it makes no sense in the context of what he’s doing.
A 10 sample average will only be a 10 sample average once it has 10 samples of data. 2 samples of data will have much more noise relative to 10 samples.
I suppose it's helpful to add that this is a MCU which will be connected to a battery for days/months at a time. It will take a sample and go to sleep. Wake up, take another sample, and go back to sleep. Every second the MCU stays awake sampling the battery, processing the results, saving them, and leaving the divider in the battery circuit considerably affects the drain on the battery. The intention is not to drain the battery but monitor the state over time.
I see that you are ignoring some suggestions. You very likely have a hardware noise problem and all the code in the world won't really address that properly. As you add layers of filtering, etc., you may just be obscuring a permanent error.
aarg:
I see that you are ignoring some suggestions. You very likely have a hardware noise problem and all the code in the world won't really address that properly. As you add layers of filtering, etc., you may just be obscuring a permanent error.
I'm at work. I can't spend all day on forums Which suggestions am I ignoring?
There are a few things I'll need to take time to look in to before responding to everything.
I have tried a couple different variations on voltage dividers. Assembling normal resistors on circuits in various configs. They give similar results. One of the paths I also explored is using a SMD divider to reduce the length of traces. https://www.amazon.com/gp/product/B07L81QJ75
I'm visualizing a voltage divider with very high R1/R2 resistance values to lower long term battery drain.
As a result, I'm visualizing noise and stray voltage pickup in your circuit.
What I'm not visualizing is a 1µF capacitor from the divider junction to GND.
However, I am visualizing a similar capacitor installed on the PCB of your multimeter.
EDIT: Note that the capacitor will lower the effective input impedance seen by the ADC input. On an AVR, this should bring it within the <=10K recommended minimum.
Metal box you need it when you are in the car, In you code put Serial Println(your value) and you see on serial plotter haw noise is changing when you try a new approach, connect input to the ground using short/long jumper, connect to the ground by capacitor, different # of samples (averaging ) .......
One of my project objectives is to log the voltage on an automotive battery = battery is in the car ?
@hcf- you have changed the parameters you gave initially.
objectives is to log the voltage on an automotive battery.
Which - not unreasonably - led us to suppose it would be used in an automotive context - ie in a vehicle in "normal" use.
The leakage on a traditional lead-acid automotive battery is huge compared to any minor drain imposed by a voltage divider.
I suppose it's helpful to add that this is a MCU which will be connected to a battery for days/months at a time. It will take a sample and go to sleep. Wake up, take another sample, and go back to sleep. Every second the MCU stays awake sampling the battery, processing the results, saving them, and leaving the divider in the battery circuit considerably affects the drain on the battery. The intention is not to drain the battery but monitor the state over time.
Dramatically changes the context.
I'm at work. I can't spend all day on forums
Perhaps if you were to explain your real objectives we could be more help, and not waste OUR valuable time?
I'd suggest you should use your multimeter - or better still an oscilloscope - AC Coupled - to determine the noise on the voltage you are reading.
Unlike the arduino ADC you dont know how your multimeter responds to a changing signal.
I think it's important to note that precision in this context is synonymous with accuracy.
Only if you dont understand the meaning of the terms. Look, you take a metre rule to measure the height of a box. The rule has 1mm graduations so you have a potential PRECISION of 1/1000 = 0.1%
Unbeknownst to you some idiot has cut 18cm off the bottom of the ruler. Your reading of 997mm is "reasonably" precise - but in error by 180mm. Its not ACCURATE.
hcf-:
I think it's important to note that precision in this context is synonymous with accuracy. We can select a multimetrer as a known truth with a stable reading of 2 decimal places. Every time you connect the multimeter, you get exactly the same reading.
Granted - the multimeter could have some margin of error too. It probably does. But that doesn't mater. It's our reference truth since the value is stable each time a sample is taken.
The difference with the MCU is that I'll get readings of 12.55 then 12.80 then 12.60 - etc. It's not possible that the battery voltage can vary that much every 1000ms.
Not necessarily true, if the load is fluctuating the battery voltage will be fluctuating due to the IR loss across
the internal resistance of the battery. And in practice there will also be IR losses across the wiring between
the battery and the point the voltage is sampled, in fact this could be a larger effect if the battery is
in good condition with low internal resistance.
A multimeter is designed to average and most will not show rapid fluctuations at all.
However normally the scale of the voltage fluctuations does suggest noise pickup in the sampling,
especially if the battery is in good condition without heavy loads.
Some low-pass filtering would be good for this, which can be as simple as adding a capacitor to ground
across the lower end of the resistor divider.
A multimeter on the same battery will have a stable measurement every time. So you can come to the conclusion that there must be some error in the MCU measurement.
As I said above, no, this is not actuall a valid conclusion. Typical multimeters have measurement bandwidths
less than 1Hz, a MCU might be sampling at kHz rates and the ADC itself might have 10's of kHz of measurement
bandwidth.