Strange analogread behavior

My project runs off a single LiPo battery, which is connected to my ATMEGA328P's A6 pin with a 100Meg / 330 Meg voltage divider.

batteryvolts = map( a, 0, 1023, 0, 3300)  / .767; // R1=100K; R2=330K

And this all worked fine on my handmade boards.

Now I have an assembly company building these boards. And the voltage divider is now implemented with surface mount resistors, where formerly I hand-soldered in a pair of normal resistors.(Same resistance of course.)

Now the behavior is different in two ways:

  1. The reading is 4x lower. It's as if it were using a 12-bit range (0-4096) instead of a 10-bit range (0-1024). But the chip used is still an ATMEGA328P, which doesn't have a 12-bit range (does it?). The markings on the ATMEGA328 chip are exactly the same as on my handmade boards. Is there some kind of setup is have to do? fuses? configuration? bootloader?

  2. The readings are erratic. sometimes the reading is very low like 20 or 30, where (with a fully charged LiPo battery) it should be about 230. I am indeed doing the trick of discarding the first reading and waiting 10 ms before the second reading, which I then use. I've tried upping the delay to 500 ms, no joy.)

Does anybody have advice for me? Thanks in advance.

Oops, 100K / 330K, not 100/330 Meg.

I wrote a tiny script:

long v;
int a;

void setup() {
  Serial.begin(115200); // 57600 needed for Bluetooth
  Serial.println(F("In setup..."));
  //pinMode(BATTERYPIN,INPUT);  // tried INPUT, INPUT_PULLUP, and even OUTPUT: no change

void loop() {
  a = analogRead(BATTERYPIN);   delay(10); // discard first reading
  a = analogRead(BATTERYPIN);
  Serial.print(F("analogread said ")); Serial.println(a);

And I see the reading decrease every iteration:

In setup...
analogread said 533
analogread said 506
analogread said 477
analogread said 450
analogread said 424
analogread said 397
analogread said 371
analogread said 347
analogread said 321
analogread said 298
analogread said 275
analogread said 252
analogread said 231
analogread said 210
analogread said 189

Does anybody have a guess as to what’s going on? I’m uncomfortable posting my circuit diagram, but the relevant part is attached.

The source impedance applied to the ADC pin must be less than 10K Ohms; in your case it is 77K. Add a 10 to 100nF cap to ground to reduce it.

Use your multimeter to measure the actual voltage at the ADC pin, and tell us what that is.

Hmm, thanks. I'll try reducing the impedance.

The old boards worked with the same resistance.
But they were manually connected with an inch or two of wire across the board to the ADC pin - maybe that added some capacitance?
Anyway, The voltage on the ADC pin is 2.70 V.

As expected, the ADC readings are too low. With high source impedance the ADC sampling cap does not have time to charge fully. This is discussed in the processor data sheet.

Can you show a schematic and a photo of the board ? So we can check where the decoupling capacitors are and if you have decoupled the AREF pin. An impedance of 77k is too much, but the values should not be that noisy, not even with 77k.

I added a 100nF capacitor between GND and the ADC pin (A6 in my case) - no change. I removed it.
Trying to reduce impedance, I substituted 10K and 33K resistors for the 100K and 330K resistors - the same thing happens but faster:

analogread said 500
analogread said 388
analogread said 266
analogread said 167
analogread said 92
analogread said 5

My schematic, attached, shows the AREF pin not connected.
Do the decoupling capacitors seem OK to you?

Your schematic has no decoupling capacitors. Below is a typical schematic for ATMega328, with the absolute minimum required decoupling capacitors C1, C2 and C3.

C1 and C3 should be positioned and connected as close to the associated IC pins as possible.

But the ADC value decreases to zero, which suggests an intermittent or open circuit somewhere.

analogReference(DEFAULT); ???

The 100:330 divider for a single LiPo cell is calculated for 1.1volt Aref (INTERNAL), which you should use.
Default Aref is the MCU supply, and is normally too noisy/unstable for battery measurements.
But, the printouts are too random for a coding problem.
Check the soldering (hope you didn't use gel/flux).

It seems you regulate down to 3.3volt.
Can't/shouldn't run the 328 on a 16Mhz clock on 3.3volt.
That chip is running out of specs (over-clocked/unreliable) below ~3.85volt.
Change to a 8Mhz crystal.

Change to a 8Mhz crystal.


Thanks all.

Decoupling capacitors: you're probably right but I've never had them and 20+ handmade boards have worked OK.

3.3V vs 16MHz: you're probably right, might try that in future. But would that explain the continually decreasing readings I see?

Wawa, the 100:330 divider reduces a fully charged Lipo's 4.2 V down to 3.2 V, what an ATMEGA pin can tolerate. Don't follow why you say "it's calculated for a 1.1V reference". But I tried that; I got different numbers of course but the same decreasing behavior.

In setup...
analogread said 1023
analogread said 990
analogread said 931
analogread said 875
analogread said 815
analogread said 736
analogread said 651
analogread said 605
analogread said 566
analogread said 523 ...

Jremington, "But the ADC value decreases to zero, which suggests an intermittent or open circuit somewhere." I'm with you there, I agree! Excuse the noob questions but how would I find that?

  • I tested Voltage at the ADC pin: It's 3.05 Volts, correct.
  • I tested resistance between the ADC pin and ground - it's open, infinite.
  • What else should I test? And what SHOULD I see if things were working right?

I've never had them and 20+ handmade boards have worked OK

You have been lucky so far (well, except for today)! No manufacturer would even think of leaving them off.

To find open or intermittent connections, use the continuity tester of a multimeter and probe all traces and wires. Flex the board while you do that.

Resolder all joints -- a "cold" solder joint can look complete but be intermittent or even open.

When you measure 3.05V at a analog pin and your sketch prints the value of analogRead() which decreases, then we have a real puzzle :o

Check AVCC. It powers the analog section of the chip.
Let the sketch read all 8 analog pins and write them all to the serial monitor.
Use a normal analog input pin, A0 ... A5. Perhaps you have a bootloader for the Arduino Uno or have compiled it for the Arduino Uno (which does not have A6 and A7).

do you have Arduino ground and voltage divider grounds connected together ?

What provides the power to the Arduino ? If you are not using the internal 328 reference then the A/D converter uses the power supply voltage as a reference .

Can you plot what your DVM reads when connected to the analog pin and what the Arduino gives and what the power supply reads at the same time .

As others have said , 16MHz and 3.3v is out of spec , try running the board from 5v

Wawa, the 100:330 divider reduces a fully charged Lipo's 4.2 V down to 3.2 V, what an ATMEGA pin can tolerate. Don't follow why you say "it's calculated for a 1.1V reference".

Ahhh, I assumed you had the 330k to the supply and the 100k to ground, which you should have,
Then you switch to 1.1volt Aref, and have stability and maximum resolution (~1000 A/D values across 4.2volt).

Wawa I could switch the 100/330 like you suggest, but that doesn't address the problem of the fading readings does it?

Koepel, I appreciate the advice!
I am using the Minicore bootloader for Board ATMega328, variant 328P/328PA.
AVCC reads 3.3 V.

I tried reading a different ADC pin, A1 instead of A6. I hooked up a AAA battery with 1.27V on it between ground and A1. My script reads A1 steadily, no fading, as 393, perfect for the 1.27 V.
But I notice that when I REMOVE the battery connection from A1, the script readings start fading, ie, decreasing, just the way A6 does while reading the voltage divider.

Now I'm guessing that A6 gets the correct voltage on it at first, but then that voltage gets removed. Yet I read 3.05 Volts with multimeter on A6 even while the script shows A6 readings fading from 480 down to 15.

Can the ATmega328 disconnect a pin internally?

No, but it can be broken. It is possible to blow a single pin or just a small part of the ATmega chip.
Pin A6 and A7 don't have the digital pin Input/Output hardware on the chip as A0 ... A5 have, so they are not 100% the same.

I don't know what to think of it. You have tried many thing, so it should be a blown pin. However, I have not heard before of a blown pin that has lowering values. I also have doubts with the hardware design and the MiniCore. The MiniCore is another thing that is not standard, and you have already a few other weird things.

Let's blame the MiniCore: A6/A7 mapping issue · Issue #12 · MCUdude/MiniCore · GitHub.

Decoupling capacitors: you're probably right but I've never had them and 20+ handmade boards have worked OK.

That's what you think. In fact they are all unreliable, possibly going to misbehave in odd ways when least expected. Decoupling capacitors are never optional for logic ICs. Fix this problem before anything else so you are not chasing phantoms. AREF needs decoupling too, not just the supply pins. The symptoms of
inadequate decoupling are many and varied and often non-sensical and very confusing.

Your link to the minicore issue says "Change A6 to 6" - I did that and it worked perfectly.


That'll get me going, but is there a different bootloader you could recommend for a barebones ATMEGA328P? I searched, I did, honest ...

The optiboot is het most used bootloader. But you don't have to generate a new optiboot bootloader for your ATmega328P.
With the newest Arduino 1.8.12, the file "boards.txt" contains the the new bootloader and the old bootloader for the Arduino Nano.

The new bootloader uses the optiboot:

So you can select the (new) Nano board in the menu and use a programmer to burn the bootloader with the Arduino IDE. That will set the fuses as well.

That hex file that will be used is: hardware/arduino/avr/bootloaders/optiboot/optiboot_atmega328.hex

After that you can select the (new) Nano board in the Arduino IDE to compile and upload (either via RX, TX or with a programmer).

Oops, I forgot you have it running a 3.3V and you need to change to 8MHz.
Then you can use the bootloader of the Pro Mini 8MHz.
It does not seem to use optiboot:
But at least you will be 100% compatible with a official Arduino board.