Voltage Divider/Meter not giving correct readings

I’m using this really nice volt meter circuit/voltage divider for my project to check the voltage of the 18V lithium battery.
I’m using 2 resistors for the voltage divider, just like they do. 7.5K and 30K. You can see my schematic in the one photo attached, and the actual layout of my board in the other. I’m using 0603 resistors. I even removed them, and put new ones on, measuring them with my Fluke 117 meter before I installed them. The actual values were 29.93K & 7.49K. So I changed my code to match, as follows:

void readVoltage() {
  float vout = 0.0;
  float R1 = 29930.0; //
  float R2 = 7490.0; //
  int value = analogRead(voltageSensePin);
  vout = (value * 4.996) / 1024.0;
  theVoltage = vout / (R2 / (R1 + R2));

But it still gives me pretty much the same result. For a battery that’s fully charged (19.11 Volt reading from my meter), the Arduino gives a value of 24.94 volts. I tried another battery that was run down (13.91 volts) and the Arduino says it is about 20.94 volts.
Is there something I’m doing wrong?

const int voltageSensePin = A4;     //Monitor the 18 volts
float theVoltage = 0.0;

void setup() {
  Serial.begin(115200);
}

void loop() {
  float vout = 0.0;
  float R1 = 29930.0; //
  float R2 = 7490.0; //
  int value = analogRead(voltageSensePin);
  vout = (value * 4.996) / 1024.0;
  theVoltage = vout / (R2 / (R1 + R2));
  Serial.println(theVoltage);
  delay(200);
}

I made this test code, and it gives the same results. I'm using an Atmega328P-AU, 3.3V 8Mhz crystal. But everything else works on the chip -- delay() is correct time, Serial works, etc.

Your divider is based on 5 volts. for 3.3 volts you need a 33 k and 5.1 k

vout = (value * 3.3) / 1024.0;

Hmm, I don't have those value and I hate to have to rework that SMD board again. It seems like there would be a way to make adjustments in the formula to make allowance for that?

Just a quick enter of 18V in, 30K on the upper and 7.5K on the lower resister gives me a Vout of 3.6V in Electrodroid app. Little much for a 3V setup. Shooting for a target of 3V @ 20Vinput shows about 5.23K on the lower resister.

tinman13kup:
Just a quick enter of 18V in, 30K on the upper and 7.5K on the lower resister gives me a Vout of 3.6V in Electrodroid app. Little much for a 3V setup. Shooting for a target of 3V @ 20Vinput shows about 5.23K on the lower resister.

And I could keep the 30K on the upper?
The fact that I've already had this circuit hooked up -- possibly giving over 3.3 volts to the analog pin -- will that have damaged the Atmega chip? Probably not since it could be running on 5 volts?
I'll swap out the lower resistor. I don't have any 1% tolerance type, but if I measure the actual resistor before installing it, I should be fine, if I change that value in the sketch, correct?

You could use a 6.8 k and 1 k and change code to match and the vout = (value * 3.3) / 1024.0;

Leave the 30 and you need 4.6 k and change the code to match and you should work.

On hand I have a 5.1K.

5.1K on lower, and 30K on upper?

So I'd only have to change the one value if I go with this.

Yes, 30K and 5.1K would get you where you need to be. That puts roughly 2.9V out @20V input.

The 5.1 make's you out of spec on the adc your inputting at 25 volts 3.7 to the pin as long as you stay 22 volts or lower you'll be ok

You got change this vout = (value * 3.3) / 1024.0;
your using 4.996

As far as it goes that's the only reason it's giving wrong value
but you can't read a full swing with the divider

As long as you don't need over 16.5 volts it would of worked up to that with just a math change

The value you read depends on the voltage divider - at best made with 1% resistors - and the voltage reference - +-/3% ?

So you could easily be several percent out.

You need to calibrate against a known good meter for accurate resuilts.

Allan

I got it:

void readVoltage() {
  float vout = 0.0;
  float R1 = 29950.0; //
  float R2 = 5096.0; //
  int value = analogRead(voltageSensePin);
  vout = (value * 3.3) / 1024.0;
  theVoltage = vout / (R2 / (R1 + R2));
  float battery[4] = {19.8, 18.8, 18.5, 17.5}; //100%, 75%, 50%, 25% battery life
  if (theVoltage > battery[0]) LEDflashes = 1;
  if (theVoltage > battery[1]) LEDflashes = 2;
  if (theVoltage > battery[2]) LEDflashes = 3;
  if (theVoltage > battery[3]) LEDflashes = 4;
}

I thought the 5 in this line:
vout = (value * 5) / 1024.0;
was referring to the ratio of the divider. As in 30K & 7.5K, it IS a 5:1 ratio. But that was just coincidental. I figured out it needs to be 3.3, and I see why now that I think about it.
This is now showing 19.06, and my meter shows 19.11 :). Hurray.
Thanks everyone. And I learned better how it works which I like!
Cheers.

He has his code using 4.996 But he is using a 3.3 volt arduino so you change that to 3.3 volts or what your good meter reads and then the divider he has can read 0 to 16.5 volts.

But to get 25 volts it be better to make better divider 6.8 k and 1 k would work. 30 and 4.6k would work
but that's really to big if you want fast readings the 6.8 and 1 would be better.

According to my voltage divider calculator, using 30K & 5.1K (29.95K & 5.096K actual measured), with a 20 volt input, I would only read 2.91 volts on the analog pin, so I should be fine. I'm getting the correct reading now. only 0.05 volts off from my meter.

be80be-
He's only reading 20, well 19.11V fully charged. His initial arduino setup indicated it was 25V when it was only 19.11V.

I know what he's reading Like I said the divider was for 5 volts it was the 7.5 is to high it was.

5.1 will work if you don't need 25 volts and it does

Oh and if you want this to work change the 4.996 to 3.3 and he did.

What did I not say that was wrong??

What did I not say that was wrong??

I'm not sure you did. Think it's more just a 'lost in translation" thing. It's all good.

SouthernAtHeart:
Hmm, I don’t have those value and I hate to have to rework that SMD board again. It seems like there would be a way to make adjustments in the formula to make allowance for that?

Just rework the SMD board, and make sure to know in advance (in future) what full-scale voltage is equal to for the particular board being used.

Normally I'd aim to make the lower resistor 10k (the maximum impedance recommended if using
more than one analog pin), and here an upper resistor of 56k. Easier to work out the ratios (6.6:1)

In micropower circuits much higher resistances can be used, so long as a capacitor is added across the
lower resistor to keep the impedance low enough for when switching analog inputs.