Forum Rule: Always post complete source code & details to reproduce any issue!

1. ## ADC Troubles (inaccurate and moving around a lot)

I'm just trying to get a simple reading from an ADC pin. However, the value seems to both be wrong and moving around much more than it should be.

ON TOP:
const int batteryPin = 16;

IN SETUP:
pinMode(batteryPin, INPUT);
analogReference(DEFAULT);

IN LOOP:

I have 2.92 volts on the ADC pin. So I should get a reading of 2.92V/3.3V*1024 = 906. Instead, I'm getting in readings that vary between 580 and 700 constantly. Why is this happening?

I double checked with an oscilloscope and the voltage is very stable. There are no fluctuations on it to speak of. Bypass capacitor is already there.

Schematically, I have two lithium ion batteries. They have a max voltage of about 4.2V. I have a divider coming off of them - series 500kohm and 1,500kohm. The connection is 4.2V to 500kohm to 1500kohm to ground. The ADC pin is hooked up between the two resistors.

I have no idea what the problem is. This should be so simple. I'm just trying to read battery voltage so that I can estimate how much charge it has left. Help?

2. Is it possible you have connected your voltage divider to a different pin than you are actually reading? Which physical pin are you using? Is it the one marked 16 (A2) with reference to http://www.pjrc.com/teensy/pinout.html ?

3. ## testing ADC in 10-bit mode

OH- I just noticed your resistor values, I think that is the issue here.

I just tried a test, using two 2k resistors as a voltage divider from 3.3V to GND.
Fluke 179 meter says "3.3V" pin is 3.271 V and ADC input (16 / A2) is 1.632 V.

Code:
```const int batteryPin = 16;

void setup() {
delay(2000);
Serial.begin(115200);
pinMode(batteryPin, INPUT);
analogReference(DEFAULT);
}

void loop() {
delay(100);
}```

Here is some sample output from above code:
Code:
```2x 2k resistor divider output:
514
514
513
514
513
514
514
514
514
513
513
514
514
514
513
513
514
513
514
514
513
514
514
514```
Now I try the same thing again but with a pair of much larger resistors, 2x 1 Megohm. Fluke meter hasn't changed much, at 1.563 V, but the Teensy3 says something quite different, see below. I think the maximum recommended impedance on the ADC input is probably 10k or less. When you go to very high value resistors, you get more noise, and more DC offset due to loading. I'm guessing you want high value R to avoid constant current drain on the battery. One solution is to use small resistors like the 2k values I tried first, but power-switch your battery divider (use a series N-channel FET in between the bottom resistor and ground, and turn it off whenever you are not actively reading it.) That approach is usually cheaper than high-value resistors and an op-amp buffer.

Code:
```2x 1Meg resistor divider output:
412
362
327
358
375
353
403
354
377
389
332
367
403
416
367
391
342
410
380
342
426
382
361
352
342
342
392```

4. Wow, very interesting. That leaves no doubt about what the problem is. Thank you very much!

5. I wonder... would a 1uF cap on the ADC pin to ground help? The idea would be to charge the cap. Since I'm only wanting to detect battery voltage, I only sample that pin once every few minutes at most. Doing the math with RC time constants (500kohm resistor into 1uF cap), it would be 86% charged in 1 second. A 100nF cap would be basically 100% charged in 1 second. I'll try this and see if that works...

edit: need to leave. will try this tomorrow and update you guys.

6. Originally Posted by kingforger
I wonder... would a 1uF cap on the ADC pin to ground help?
I'd go with something even smaller... 0.1uF should be fine. The main issue is that you're trying to read a high-impedance load with a SAR-type ADC, which starts by charging a small capacitor (5-10pF) inside the Teensy ADC. Depending on the resolution, consistency, etc. desired, you may need as many as 31 time constants (at 16 bits) to achieve happiness... I'd guess that adding a small external capacitor (0.1uF or 0.01uF) should be fine in this application, provided the signal does not change quickly and you sample infrequently (i.e. allowing the external cap to recharge)

IIRC, my calculations for 16 bit resolutions indicated a maximum source impedance of around 25kOhm to allow 16 bit measurements at a 6MHz ADC clock rate. So nothing wrong with using large resistors to limit current flow through the resistors, just use a external cap to help charge the SAR ADC sample and hold capacitor.

7. Yup, a 0.1uF cap did it! Thanks.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•