Hi I am super confused with reading my lipo battery voltage.
I WANT TO CREATE A FUNCTION TO READ MY 3.7~4.2V,1200mAH BATTERY VOLTAGE THROUGH A MICROCONTROLLER (ARDUINO OR ATTINY44).
THEN I WANT TO CALL THE CREATED BATTERY FUNCTION IN THE FORMULA TO READ PRECISE SENSOR VALUE:
int voltage = ((CALLING BATTERY FUNCTION) * (READ SENSOR VALUE)) / 1023;
I AM USING INTERNAL REFERENCE VOLTAGE 1.1V.
NOTE: I want the whole system to run on lithium battery ( i am just creating a prototype on Arduino, if it works, ill be editing the code for my attiny44 using 8mhz external crystal).
Unfortunately, i tried almost all codes available on the internet but i could not read the right voltage. I believe that there is some issue with my connections.
`void setup() {
Serial.begin(9600);
Serial.println("Setup completed.");
}
void loop() {
// Read external battery VCC voltage
Serial.print("Bat: ");
uint16_t batVolts = getBatteryVolts();
Serial.print(batVolts);
Serial.print(" - ");
Serial.println(getBatteryVolts2());
delay(500);
}
// One way of getting the battery voltate without any double or float calculations
unsigned int getBatteryVolts() {
//http://www.gammon.com.au/adc
// Adjust this value to your boards specific internal BG voltage x1000
const long InternalReferenceVoltage = 1100L; // <-- change this for your ATMEga328P pin 21 AREF value
// REFS1 REFS0 --> 0 1, AVcc internal ref. -Selects AVcc external reference
// MUX3 MUX2 MUX1 MUX0 --> 1110 1.1V (VBG) -Selects channel 14, bandgap voltage, to measure
ADMUX = (0 << REFS1) | (1 << REFS0) | (0 << ADLAR) | (1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (0 << MUX0);
// Let mux settle a little to get a more stable A/D conversion
delay(50);
// Start a conversion
ADCSRA |= _BV( ADSC );
// Wait for conversion to complete
while ( ( (ADCSRA & (1 << ADSC)) != 0 ) );
// Scale the value - calculates for straight line value
unsigned int results = (((InternalReferenceVoltage * 1024L) / ADC) + 5L) / 10L;
return results;
}
}
Yes i made reference voltage to be 1.1V and it should provide me constant voltage right? but unfortunately as the battery deplete the voltage value changes too. Idk how do i use it in my sensor formula
No need to shout, on a forum using all uppercase is considers shouting.
Now if you are using a 1.1 V reference, then it needs to be specified in the code. Your code does nothing to make this happen.
Also once on a 1.1V reference, the A/D will measure no more that 1.1V. That means the direct measurement of your battery will only ever give a reading of 1023, no more no less.
You have to have a voltage divider between the battery source and the analogue input in order to ensure that even at full battery voltage the analogue input pin sees no more that about 1V.
Only then can you measure the actual voltage of the battery, by measuring the voltage on A0 and then compensating for the voltage divider on the input to calculate what the battery voltage must be.
I am also not sure why there is a capacitor between the Vref pin and ground because if you are using the internal reference I am not sure it is doing any good.
Armed with that knowledge look at those links again and see if you have missed the bit about the voltage divider. If the links make no mention of them then they are bad links or you are misunderstanding what context they apply to.
OK but the big thing is the missing voltage divider.
It might be but there is a better way and that is to use the Arduino codes designed to do just that:
Note that the thing that makes this work is having an internal reverence voltage in the Arduino in the first place. Look at the list of processors that has one in that link.
The "schematic" on post 8:-
Why have you connected the Analogue reference voltage to the +ve of the battery?
Do you want to damage your Arduino or what?
Read your posts again. What information have you not given that would help us to help you. Right now, all we know is that it is not doing what you want it to do.
I need to read constant voltage from my lithium battery and use that voltage in the sensor formula which is as follows:
int voltage = ((CALLING BATTERY FUNCTION) * (READ SENSOR VALUE)) / 1024;
That is all, all i want is constant voltage from my battery and that is why i am using 1.1v internal reference.
It should not be connected to anything. What don't you understand about the word internal?
Did you actually read the link I posted in post #7? It said:-
Don’t use anything less than 0V or more than 5V for external reference voltage on the AREF pin! If you’re using an external reference on the AREF pin, you must set the analog reference to EXTERNAL before calling analogRead().** Otherwise, you will short together the active reference voltage (internally generated) and the AREF pin, possibly damaging the microcontroller on your Arduino board.
I just did ,okay, i have removed AREF pin physical connection (now it is internally set to 1.1V) and i have used voltage divider to reduce the voltage below 1.1V (1k & 4.7K) respectively from the divider mid point one pin goes to pin A0 and i get the following output
External reference voltage should not be less than 0v or more than 5v. but i am internal reference not external and therefore my AREF should not be connected to anything.
Good now please post the code, in your next post because it seems you have a bit of an issue with your calculations. After a few readings it settles down to being quite constant, does it not.
Yes, and if you do this, that is, connect a external voltage to AREF while using an internal reference you will :-
Which is what you did according to your diagram in post #7.
This is not Arduino code. Directly accessing the MCU's internal registers like this is prone to error and may not work when you move to another chip like attiny44. Use standard Arduino functions to avoid these problems
Use analogRead().
If the readings are still changing, you could try connecting a 0.1uF capacitor between A0 and ground.