Is there a way to monitor the battery that feeds an esp8266 in a portable project?
I have been meaning to implement that feature into my project so that i can be warned when the battery runs low on juice but i don't know if the esp has some kind of onboard sensor to do that.
-
All ESP8266 have ADC, just not all of them have them "broken out" - in the ESP8266 the ADC can be in one of two modes, one of which allows you to read VCC - so, no external hardware required ... that's the good news, the bad news ... how to set the ADC to read VCC depends on how you are programming the espJaromanda X– Jaromanda X2016年05月25日 12:29:03 +00:00Commented May 25, 2016 at 12:29
1 Answer 1
There are two things you need to measure the battery of the system that is doing the measuring of the battery:
- An analog-to-digital converter
- Some form of fixed voltage reference to compare the battery voltage against.
Some ESP8266 modules have a single analog input available, and some don't. You need to check which module you have and which pins are available on it.
Then you need to use the ADC to measure the fixed known voltage. That could be from a small LDO voltage regulator that is below the voltage of the minimum voltage you will care about from your battery, or something like the forward voltage drop of a silicon diode (~0.7V) - something where you know what the voltage is.
From that reading you can then back-track what the supply voltage must be in order to give you the reading it has given you. As the battery voltage drops the voltage range the ADC will be measuring will be reduced, and so the fixed voltage will rise within that range giving you higher readings from the ADC.
Here is a snippet of code I use with the 1.1V internal voltage reference of the ATMega328P to calculate the supply voltage:
long readVcc() {
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1125300L / result; // Back-calculate AVcc in mV
return result;
}
Of course, you need to change that to use the analog input of the ESP8266 instead (probably just using analogRead()). And of course change the ADC-scaled voltage. The formula is basically:
Vref * ADCmax / ADCreading
So if you have the 1.1V reference as above, and the ADC can read 0-1023, then it's:
1.1 * 1023 / reading
Or, pre-calculate the first half of the sum:
1125.3 / reading
To keep it as integer mathematics work in millivolts instead of volts by multiplying the reference voltage by 1000:
1125300 / reading
And that, as you can see, is what is in the function above.