ADC reading occasional non-zero with pull-down

I'm reading a battery pack voltage with a maximum possible value of 85V via voltage divider into an ADC input.

Voltage Range Potential: 0 - 85V
Divider Range: 0-5V

Ideal Ratio: 100k/6k25
Resistors used: 100k/(5k1 + 2k pot) (pot to tune out error)

With the battery pack disconnected, The bottom of the voltage divider should be pulling the input low for a reading of 0.

Most of the time, this is the case, but I'm getting occasional raw data reading as far up as 7.
(usually, it is 3 or less.)

Given the wide possible input range, each step is about 83mV.
A raw reading of 7 is 581mV - over 1/2 volt when it should be zero.

Here is a sample from the serial monitor:

VDischargeRAW: 3
VDischargeInmV: 249
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 3
VDischargeInmV: 249
VDischargeRAW: 1
VDischargeInmV: 83
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 5
VDischargeInmV: 415
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 0
VDischargeInmV: 0
VDischargeRAW: 3
VDischargeInmV: 249

the problem of fluctuating values continues with the battery connected, but it may be partially due to other factors (ie, power supply fluctuations), but I figured a zero value should be stable.

I've tried a few things trying to settle this down...

Added 0.1uF cap on each analog input.
double read (analogRead twice, throw out the first value)
change ADC Prescaler

I've considered doing an averaging of multiple readings, but it seems that I shouldn't need to when reading a battery that doesn't have a load - should be rock solid - or when trying to read zero.

Any help??

Thanks

Where in the resistor chain is the analog pin connected? Why do you think a floating pin should be reading zero? It is floating to the extent there is a resistor between the pin and ground What do you get when the pin is actually connected to ground?

Paul

Here is a section of the schematic showing the attachment...

The unlabeled wire going to the left is connected to the ADC input.

I don't believe a floating pin should read zero on its own. I do believe the extent the upper resistor in the Voltage divider acts as an antenna should be negligible compared to the pull-down effect of the lower resistor being tied to ground.

As the ADC is a high impedance input, I'm expecting the same results as if I used a pull-up or pull-down on its own.

Perhaps my thinking is flawed?

ADC Sch.jpg

I assume you're using an Uno.
Advice could be different for other Arduinos.

Loose the zener. It does not protect the way you think it will, and it adds non-linearity and temp dependency.
Use a resistor ratio of about 1:80, e.g. 2.2k:180k, both 1% metalfilm. NO pot.
Important to have C7 and R8 close to the Arduino pins, and to NOT share that ground with other sensors.

Use analogReference(INTERNAL); in setup, to select the internal 1.1volt Vref.
The maths line in your code to convert to voltage must reflect the true voltage of that Aref.
Leo..

Appreciate the suggestions, however, they don't really address the issue of sporadic non-zero readings with the input tied low.

  • Update ... I tried shorting the A0 pin to ground and it is still giving the sporadic readings.

Using the 1.1V Ref would require the signal to be no more than the reference, correct?

I'd like to try to keep the resolution up higher, at least 100mV ... it'd be about 400 mV/Div. with a 1.1V reference, if my (in the head) math is right.

As already stated, the board is a Pro-Mini.

The 'sensors' in this case are literally voltages of a battery.

The Pro-mini should return zero with it's analogue input shorted to ground.
Are you also using other analogue inputs?

Using 1.1volt Aref is no different, resolution wise, to what you're doing now. But readout should be more stable.
Resolution is still 1024 A/D steps, minus the small amount you loose from the 'wrong' ratio of the divider.
I don't see why you can't have a 0.1volt display with a bit of oversampling (multiple A/D readings and averaging).
Input voltage can still be 0-VCC with 1.1volt Aref enabled.
The A/D will just return 1023 when you input more than the Aref voltage.
The advantage of using 1.1volt Aref is that you can now input ~400volt into the divider before you reach 5volt on the tap.
Leo..

Wawa:
The Pro-mini should return zero with it's analogue input shorted to ground.
Are you also using other analogue inputs?

I am also reading:

  • a second Battery voltage - same setup
  • ACS712 Current measurement module.
    These aren't always active. (Whether running or not, the main issue still remains.)

I have also attempted programming a different Arduino board, just in case it was a faulty unit. No luck, same issue.

I'm starting to suspect it is something in the module/chip itself. Perhaps some housekeeping code that runs once in a while that leaves a small charge behind? Grasping at straws here. Just getting frustrated.

Wawa:
Using 1.1volt Aref is no different, resolution wise, to what you're doing now. But readout should be more stable.
Resolution is still 1024 A/D steps, minus the small amount you loose from the 'wrong' ratio of the divider.
I don't see why you can't have a 0.1volt display with a bit of oversampling (multiple A/D readings and averaging).
Input voltage can still be 0-VCC with 1.1volt Aref enabled.
The A/D will just return 1023 when you input more than the Aref voltage.
The advantage of using 1.1volt Aref is that you can now input ~400volt into the divider before you reach 5volt on the tap.
Leo..

So, if I use the 1.1 Aref I know I still get the same number of steps, but each step is proportionally larger.

I think I'm getting my terms mixed up here. I think this is right now...
It isn't the resolution (# of bits) I'm afraid will change, its the precision (Value per step).
< 100 mV Vs ~ 400mV. (I'd prefer to keep the smaller step size.)

Could be a hardware or code problem.
An ATmega328 should absolutely return zero with the analogue input grounded.
Try to measure that analogue input with minimal hardware and code.

With default Aref, 0-1023 is spread out over 5volt (~5mV/step).
With 1.1volt Aref, 0-1023 is spread out over ~1.1volt (~1mV/step).
The divider to ~1.1volt reduces the mV/volt, but the A/D set to 1.1volt Aref increases it again.
Resulting in the same number of A/D steps per measured volt.
85volt spread out over (almost) 1024 A/D values = ~83mV/A/D step.
So you can display with a human-readable 0.1volt.
Leo..

I'm making a breakout board for the Pro-Mini in an attempt to isolate the issue.

I'll be able to individually disconnect any pin and jumper it somewhere (ie, ground), without affecting the remainder of the circuit.

Any other suggestions in the meantime are still appreciated. :slight_smile:

Thanks

UPDATE:

I've completed my breakout board for my Arduino Module & after doing a bunch of testing, I've discovered the following:

** The Problem has something to do with my I2C Display.**


I haven't been able to 100% confirm if it's the Arduino's I2C, or the module I'm using.

I'm leaning towards the module. (See below)

Module: 0.91" I2C OLED display - 128x32 (SSD1306 based)

  • Generic module - no mfg. info
  • Module has integrated Pull-up resistors for I2C lines, so they are floating when the module is removed.
  • Module has an onboard linear reg, I believe, to make a 3.3V supply.

Library:
U8G2


Testing details: (Ignoring tests that didn't make any changes.)

  1. If I remove the OLED and power up, everything works fine with stable readings.

  2. If I re-install the module with Arduino running - Readings remain stable, and the screen stays off.
    Presumably, because the initialization code was not sent to the module.

  3. If I re-install the module (and reset), the unstable readings come back.

  4. If I remove the module with Arduino running, readings become stable again.

  5. Re-installing the Module after #4, results are the same as #2.

  6. Starting from #3, If I remove the I2C lines while running, Unstable readings continue

  • screen froze - as expected without communication lines).
  1. Powering up with I2C lines removed, but module installed - Stable readings
  • The screen remains off - Same as #2

8 ) Re-attaching I2C lines while running (From #7) - Same results as #2

  1. Reset after #8, Unstable results return.

My current Thinking:

The Module is causing the issues.

The problem only occurs when the module has been fully initialized

I'm not familiar with how the Arduino handles the display being installed after startup - presumably, it is still sending I2C commands.

  • If the above assumption is true, it's probably NOT the I2C lines (Arduino) that are causing the problem.

I have not had a chance to figure out anything else yet.

Next steps:

  • Try adding a 100nF Cap across module power for noise reduction. (I don't expect this to help)

  • Try larger Cap as well to help with any local power need spikes.

  • Try completely separate 2nd power supply (commoned ground) just for the display.

Making progress, but still searching.

Any more thoughts/advice is appreciated.

Thanks everyone.

Based on the behavior of your #6, it sounds like noise injected into the 5 volt Arduino supply causing the analog variance. This is because this 5 volt supply is the Vref of the A/D convertor and is why Wawa was suggesting using the internal 1V reference.

Powering the display from a separate supply should prove out the theory. If you have a scope, now would be a good time to turn it on...

Well, This is embarrassing ...

It seems I had forgotten to include a supply output Cap on the VCC line.

I had it in m design, but I must have gotten caught up in building everything else, I missed it. (I did manage the 0.1u filter caps, but not the more general LF filter/reservoir one)

IT seems, through testing, that 100uF prevented the vast majority of the bad readings. 150uF fixed them all. (My design now has a 330uF in it, just for fun. ;))


Some good came from it though ...

  1. It forced me to finally get a breakout board made for the Pro-Mini

  2. Good Troubleshooting practice

  3. A reminder of how important even the smallest things can be.

Thanks again for everyone's help

You have 100nF on AREF pin to ground of course?

MarkT:
You have 100nF on AREF pin to ground of course?

I believe that is standard on the module. (The ARef pin is not brought out to the module's leads)