WIFI Battery Monitor System – ESP8266

Step 1: What we will need:

Step 2: Schematic & Wiring

As the CBDBv2 Evo DevBoard has already Voltage and Current measurements capabilities onboard, the only thing that we will need to do is to connect the battery module that we want to measure to the board:

WIFI Battery Monitor System - ESP8266


  • GREEN – V+
  • BLUE – GND
  • RED – SH_IN+
  • WHITE – SH_IN-

For that ones of you that want to use a different Board or just want to add these functions to a ESP8266 Module, you just need:

  • for Voltage – add and size on your needs the voltage divider as explained in details in the previous article about ESP8266 Internal ADC.
  • for Current – add your favourite Current Monitor but don’t forget about the VmaxIN for ESP8266 ADC of about 1V!

Step 3: How to Measure Battery parameters

When measuring the real battery capacity what we are interested in is the amount of energy stored in a battery since it is this energy we need to power our devices. Stored energy is measured in Watt-hours – the same unit used to measure our domestic electricity consumption (where 1,000Wh = 1kWh = 1 unit of electricity).

In order to measure the stored energy in a battery a power resistor is used as the load, and a fully charged battery is fully discharged through it. By measuring the voltage across this resistor at regular intervals during the discharge process it is simple to calcuate the total energy dissipated and therefore the total energy which had been stored in the battery.Using Ohm’s Law (I=U/R) we can then calculate the current flowing through the load since we know the voltage across it. Instantaneous power is given by multiplying the measured voltage by the calculated current (P=U*I).By taking readings for a certain amount of time until the battery is completly discharged, and adding up the energy dissipated in each time interval, we can calculate the total energy taken from the battery and dissipated in the resistor and therefore the total energy that was stored in the fully charged battery.

Step 4: Software implementation

For programming CBDBv2 Evo Board and uploading the drivers and the software we will continue to use the LuaUploader as before.

1. Define used GPIO pins and variables:

ADC_SRC = 5                    -- GPIO14 - select Voltage Divider / Current Input
sda=2                          -- GPIO4  - SDA
scl=1                          -- GPIO5  - SCL 
gpio.mode(ADC_SRC,gpio.OUTPUT, gpio.PULLUP)
gpio.write(ADC_SRC,1)      -- Voltage Measurement - Voltage Divider Source selected
gpio.write(ADC_SRC,0)      -- Current Measurement - Current Shunt Monitor output selected
voltdiv= 0.00412           -- Voltage reading calibration
dival = 0.00096            -- ADC volt/div value - CALIBRATE !!  
resdiv = 4.31447           -- Voltage Divider Ratio - CALIBRATE!! 
divalI = 0.9425            -- Current volt/div ratio - CALIBRATE!!
cpct = 0                   -- Calculated Delivered Energy
adcI = 0                   -- ADC readings -  Curent
adcV = 0                   -- ADC readings - Voltage
pwr = 0                    -- Calculate Power
t=0                        -- time

2. READ ADC – Voltage

function readADC_Voltage()
      adcV = 0
      advr = 0
      print("\nADCV Step   : " ..string.format("%g",advr).." steps")
      print("Voltage     : " ..string.format("%g",adcV).." V")
      return adcV

3. READ ADC – Current

function readADC_Current()
      adcI = 0
      adcr = 0
      print("ADCI Step   : " ..string.format("%g",adcr).." steps")
      print("Current     : " ..string.format("%g",adcI).." mA")
      return adcI

4. READ ADC Process function and instantaneous Power consumtion calculation

function readUI()
   gpio.write(ADC_SRC,1)         --select source
   adcV = readADC_Voltage()
   gpio.write(ADC_SRC,0)         --select source
   adcI = readADC_Current()
   pwr = adcI*adcV
   print("Power       : " ..string.format("%g",pwr).." mW")

5. Number format function for proper LCD printing

nr_format = function (fnr,unit)
   if (fnr > 1000) then fnri=fnr/1000
                        uniti=string.sub(unit, 2)  
                        nrf=string.format(" %.3f%s ",fnri, uniti)
   if (fnr < 100) then
                    if (fnr < 10) then
                                   nrf = string.format("  %.1f%s ",fnr, unit)
                      else nrf = string.format(" %.1f%s ",fnr,unit)
    else nrf = string.format("%.1f%s ",fnr,unit)
   return nrf

6. LCD Print – > Voltage / Current / Energy / Power

For more details about the I2C LCD Driver , please take a look at the ST7032i LCD Driver Article

function readUI()
   gpio.write(ADC_SRC,1)         --select source
   adcV = readADC_Voltage()
   gpio.write(ADC_SRC,0)         --select source
   adcI = readADC_Current()
   pwr = adcI*adcV
   print("Power       : " ..string.format("%g",pwr).." mW")

7. MAIN program

st7032i:lcd_print(1,1,string.format("Battery Monitor"))
st7032i:lcd_print(3,2,string.format("Starting ...")) 
tmr.alarm(0, 10000, 1, function() readUI() LCDout() tmr.delay(1000) end)

Step 5: First RUN

For testing, just save the code on ESP as ‘blms.lua‘, restart ESP and run:

dofile(“blms.lua“) — Start the Battery Live Monitoring System

If you want the BLMS software to start automatically when your CBDB module starts or reboots, then you neet to create and add some lines in your ‘init.lua‘ file:

dofile(“blms.lua“) — Start the Battery Live Monitoring System

Save the code on ESP as ‘init.lua’, restart ESP.
It should reboot and restart automatically the program .

About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us: