ATMEGA328 and battery meausre: don't want magic numbers but understand :)

As title topic,
I did read several tutorials, but I don't have the ideas clear.

I have an ATMEGA328P 8mhz no BOD barebone. I feed it with 2XAA battery (~ 2.74 volt when full charged).

I have also a step up to 3.3v to feed a DHT22.

Now, I want to read the battery voltage.

I know that I need to read BEFORE the Step up (direct the 2.74V).

I know that I need to use a voltage divider.

I want to use INTERNAL REF (1,1v)

But, How I can get the formula to use in sketch?

E.g. I know that to obtain 1.1v in voltage divider from an input of 2.74 I Need to use R1 = 2K and R2 =~ 1300 (I did try here: Voltage Dividers - learn.sparkfun.com ).

I did not understand If I need to pick the start voltage at full charged (in my example the 2.74v) and divide to the 1.1V, to perform the reference.

For example, I did found a sketch that say (for the 3.3v):

int sensorValue = analogRead(A0);
float battery_Voltage  = sensorValue * 0.003363075;

Where the magic number coming from a voltage divider made from

R1 = 1M and R2 = 470K

and formula =

((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
3.44/1023 = Volts per bit = 0.003363075

So, I mean, I need to reduce every voltage input to the 1.1 when full charged?

Thank you

I did not understand If I need to pick the start voltage at full charged (in my example the 2.74v) and divide to the 1.1V, to perform the reference.

You have some (maximum = 2.74V) voltage that you feed to a voltage divider. You want some maximum voltage (1.1V) out.

You don't change the voltage divider because the battery is going dead, so it must be fixed to handle the largest possible input and not exceed the required output.

Google “Arduino secret voltmeter” or something like that.

Most of the time an ADC is used to convert an unknown input voltage based on a known reference voltage. The allegedly “secret voltmeter” does the opposite. It converts a known input voltage (the 1.1V reference can be used as the ADC reference or an input) against an unknown reference (VCC). The formula requires some small rearranging, but that’s trivial algebra.

First, convert the analog input value [0, 1023] to the actual input voltage on pin A0, [0V, 1.1V]. This is relatively easy:

int analogInputValue = analogRead(A0);
float A0Voltage = analogInputValue * 1.1 / 1023.0;

Then you have to take into account the voltage divider.

Vin = VA0 · (R1 + R2) / R2 (1)

Where Vin is the input voltage from the batteries [0V, 2.74V], VA0 is the voltage on pin A0, [0V, 1.1V].
R1 is the value of the resistor between the positive battery terminal and pin A0, R2 is the value of the resistor between pin A0 and ground.
This formula can be deduced from Kirchhoff’s laws.

const float R1 = 100;
const float R2 =  47;
const float voltageDividerRatio = (R1 + R2) / R2;
float inputVoltage = A0Voltage * voltageDividerRatio;

To determine the values of R1 and R2, you start from equation 1.
You want to map the battery voltage [0V, 2.74V] to the range of the analog input [0V, 1.1V].
So you get two new equations:

0V = 0V · (R1 + R2) / R2 (2)
2.74V = 1.1V · (R1 + R2) / R2 (3)

Equation 2 doesn’t tell us anything useful about R1 and R2, because it’s always true.
Equation 3 can be used to calculate the ratio between R1 and R2, but it is an underdetermined system (2 variables and only one 1 meaningful equation) so it has infinitely many solutions.
This means that you don’t have a single answer for R1 and R2, but if you choose either R1 or R2, the other one will be known.

R2 = 1.1V · R1 / (2.74V - 1.1V) (4)

Then you have to pick R1 and R2. You are limited to values of the E12 series (10n/12). You probably won’t find a pair of E12 values that fits equation 4 perfectly. It’s a good idea to have some kind of margin, for example, if you use alkaline batteries instead of Ni-MH, the voltage will be higher. So round up R1 (use a higher value) and round down R2 (use a lower value).

Pieter

Jiggy-Ninja:
Google “Arduino secret voltmeter” or something like that.

Most of the time an ADC is used to convert an unknown input voltage based on a known reference voltage. The allegedly “secret voltmeter” does the opposite. It converts a known input voltage (the 1.1V reference can be used as the ADC reference or an input) against an unknown reference (VCC). The formula requires some small rearranging, but that’s trivial algebra.

I did see some time ago, and I did retrieve, is this? Secret Arduino Voltmeter – Measure Battery Voltage

But, referring to my example, and to undesrstand If I did understand (!) :slight_smile: … The base of first method is to port the “unknown” (in reality you know what’s the voltage, at least at full charge, it’s 2.74V) to a known 1.1v… or no?

PaulS:
You have some (maximum = 2.74V) voltage that you feed to a voltage divider. You want some maximum voltage (1.1V) out.

You don’t change the voltage divider because the battery is going dead, so it must be fixed to handle the largest possible input and not exceed the required output.

Same… I did not understand you. I need to carefully select the resistors value at the start, to accomodate the input voltage (max will be 2.74 in my example) in a 1.1V? Or no?

Thank you to both, and sorry if I repeat me…

This link should provide the code you need.

…R