I'm using an Arduino pro mini, powered by a 3.7v Li ion battery. I connected battery to the raw pin and i'd like to measure its voltage decay.As this board has no ARef pin accesible, I have a TL431 ref voltage soldered to pin 20 in the atmega, so i have a fixed 2.5v external reference. I soldered a cable from raw pin to A3 analog input,to measure voltage with good accuracy.
Now the problem is, that board runs to 3.3v, so i can,t measure as much as 3.7v volts in raw pin, because is outside the max value , 3.3v, the board can measure. But,if i solder to A3 the voltage after arduino board regulator (which is 3.3v) to measure regulated voltage, i think it could happen that being battery still at ,lets say, 3.4v there is no room in regulator to work with only 0.1v left, so maybe that being the battery at 3.4 the board shuts off...so i can never read the proper battery state. Before regulator level is too high. After it, when the voltage drops enough to be below 3.3v maybe is too late for the board to work.
Should i just build a resistor divider such that when battery is at full 3.7v i can still read a voltage below 3.3v so it can be read with an analog pin?
Also, i read abou the internal 1.1V reference, but is not clear to me if it has good accuracy or how should i calibrate the "magic" number that appears in all sketches.
Sorry for the long descriptions and thanks any idea or acclarations.
Maybe you could open the supply/regulator jumper,
and run the board (VCC) straight from the ~3.7volt battery.
Then you can measure battery voltage internally, with code only.
If you must run on 3.3volt, then the TL431 is a poor solution for battery power.
Minimum idle current is almost half a mA (there are low power versions).
Dividing down to 1volt with high value resistors, a 100n cap from pin to ground, and 1.1volt Aref is a 'better' option. 1.1volt Aref is stable but not factory calibrated, so you must calibrate yourself.
Leo..
Recomendo usar um BUCK-BOOST converter de 3.3V para alimentar o Arduíno e fazer um divisor de tensão, por exemplo 2 resistências de 10K para fazer a leitura, assim a tensão máxima será de 2.1V.
This is the way to go. Here is the code to measure the battery voltage, using the internal 1.1V reference (each Arduino needs to be individually calibrated).
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
while (!Serial);
Serial.print("Vcc is ");
Serial.print(readVcc());
Serial.println(" mV");
}
long readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
// read it a second time
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high<<8) | low;
//calibrate the Arduino by changing the number below so that the reading agrees with your multimeter
result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1024*1000
return result; // Vcc in millivolts
}
void loop() {}
This measures humidity and temperature at soil surface and at 60cm below ir.It uses two bme280 with spi and then sends data by radio using a 433Mhz emitter to an esp8266 at 50m.
TL431 uses up to 800uA, and all should be powered with a 150mA solar powered battery.Total current used is up to 8mA when emitter kicks in once each minute.
The idea of using TL431 is to read with an analog input its 2.5V and compare that with the raw (resistor divided) readings in another analog input to apply a simple ratio measurement and deduce battery voltage.
I know there are better voltage reference devices,but TL431 is all i have.
Thanks for the suggestion.
Is safe to connect a battery directly to the Vcc pin? I think fully charged a battery can reach 4.2V.
Also, my digital voltmeter is not very accurate ( i think it changes too much from a measurement to other) so calibration can be problematic.
Yes, as long as the battery voltage never exceeds 5.5V.
my digital voltmeter is not very accurate
No need to calibrate, especially if you can't trust your multimeter. The result of using the code as it is should be within 10% of the correct value, and probably, within 5% of correct.
Ok, i tried this method of the internal reference.But with the 1125300L constant, my arduino reads 2.820 mV when multimeter says 3.29V. Should i now change the constant so much that it matches the 3.29V ? I think is a too big difference.I would expect change in constan to be not so big.
That was the factor i used. Whatever it is, the readings seemed consistent for the first decimal point. But now, I've changed to a different battery and again they are off by 0.5v.
If i can fix that, the method seems good enough for me.
Some cheaper DMM get inaccurate when the internal 9volt battery drops below a certain voltage.
I have learned to lways use a branded alkaline battery in a DMM.
Leo..
The thought occurred to me that the battery might be at fault, but if the meter doesn't complain that the battery is low, that meter is hardly worth the trouble.