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 esp – Jaromanda X May 25 '16 at 12:29

There are two things you need to measure the battery of the system that is doing the measuring of the battery:

  1. An analog-to-digital converter
  2. 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.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.