is on your own risk !!
For any new CBDBv2 Evo orders/requests please feel free to use as usual:
tech at esp8266-projects.com.
If you want for your own experiments to order CBD v2 EVO bare PCBs only, you can also do it directly at Dirty PCBs, our preferred PCB House:
One of the main problem in battery powered projects is to choose/use the proper battery size/model/type. As market is flooded now with a lot of low quality batteries claiming thousands of mAh ( Ultrafire fakes stories is just an example) the only way to proper check them is to run a set of tests.
A simple basic capacity test / loading / discharging time values can give you valuable informations about the parameters and health of the battery. And of course also you can see how are looking the numbers against the datasheet claims :).
Few general considerations that I want to bring to your attention:
- The capacity of a battery tells you how much charge it can store. This means that they can theoretically provide a current of 2A for one hour, 1A for two hours, or 200mA for ten hours. In reality a 2,000mAh battery would not provide 20mA for 100 hours, nor 2A for one hour.
- Discharge load – this is a tricky one and most of the time not clear explained by battery manufacturers in their datasheets. Mostly of them are using a discharge load of 0.1C, that means one-tenth of current capacity when rating their batteries. Therefore, a battery which can provide 200mA for 10 hours would be rated at 10×200 = 2,000mAh !!
A faster discharge rate would result in less energy being extracted from the battery, and
therefore the measured capacity would be lower. If you are using batteries in energy-hungry
devices that need more than 0.1C, the real capacity will be lower than that published.
A “good-to-have” add-in for a battery powered project is a system that will be able to monitor over the entire battery lifetime at least few parameters like, voltage, current, power consumption and stored energy between charges.
What we will need:
- CBDB Board ( or any other ESP8266 Board you may like but who has voltage/current measurement capabilities)
- INA214 – Current shunt monitor
- USB adapter (take a look on Part 1 for details about the USB Adapter
- Li-Ion Battery Module
- 20 Ω / 5W resistor (or 2 x 10 Ω /5 W in series – even better )
- Connection wires – various colors
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:
GREEN – V+
BLUE – GND
RED – SH_IN+
WHITE – SH_IN-
By default the CBDBv2 Evo Board comes prepared for Li-Ion batteries voltage range, with the onboard default voltage divider values and Rshunt you have VmaxIN=4.3V and ImaxIN = 1A. If you need a different Voltage/Current range just change/ask for different default values.
|CBDB v2 Evolution DevBoard with INA21x Current monitor|
The Current shunt monitor used for this project is a INA21x family one.
The INA210, INA211, INA212, INA213, INA214, and INA215 are voltage-output, current-shunt monitors that can sense drops across shunts at common-mode voltages from –0.3 V to 26 V, independent of the supply voltage.
Five fixed gains are available: 50 V/V, 75 V/V, 100 V/V, 200 V/V, 500 V/V, or 1000 V/V.
The low offset of the zero-drift architecture enables current sensing with maximum drops across the shunt as low as 10-mV full-scale.
These devices operate from a single 2.7-V to 26-V power supply, drawing a maximum of 100 μA of supply current. All versions are specified over the extended operating temperature range (–40°C to 125°C), and offered in an SC70 package. The INA210, INA213, and INA214 are also offered in a thin UQFN package.
• Wide Common-Mode Range: –0.3 V to 26 V
• Offset Voltage: ±35 μV (Max, INA210) (Enables Shunt Drops of 10-mV Full-Scale)
– ±1% Gain Error (Max over Temperature)
– 0.5-μV/°C Offset Drift (Max)
– 10-ppm/°C Gain Drift (Max)
• Choice of Gains:
– INA210: 200 V/V
– INA211: 500 V/V
– INA212: 1000 V/V
– INA213: 50 V/V
– INA214: 100 V/V
• Quiescent Current: 100 μA (max)
For any new CBDBv2 Evo orders/requests please feel free to use as usual: tech at esp8266-projects.com.
If you want for your own experiments to order CBDBv2 EVO bare PCBs only, you can also do it directly at the PCB House:
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!
How to Measure Battery Capacity
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 completely 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.
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 advr=adc.read(0) print("\nADCV Step : " ..string.format("%g",advr).." steps") adcV=advr*dival*resdiv print("Voltage : " ..string.format("%g",adcV).." V") return adcV end
2. READ ADC – Current
function readADC_Current() adcI = 0 adcr = 0 adcr=adc.read(0) adcI=adcr*divalI print("ADCI Step : " ..string.format("%g",adcr).." steps") print("Current : " ..string.format("%g",adcI).." mA") return adcI end
2. READ ADC Process function and instantaneous Power consumtion calculation
function readUI() gpio.write(ADC_SRC,1) --select source adcV = readADC_Voltage() tmr.delay(10000) gpio.write(ADC_SRC,0) --select source adcI = readADC_Current() pwr = adcI*adcV print("Power : " ..string.format("%g",pwr).." mW") end
3. 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) else if (fnr < 100) then if (fnr < 10) then nrf = string.format(" %.1f%s ",fnr, unit) else nrf = string.format(" %.1f%s ",fnr,unit) end else nrf = string.format("%.1f%s ",fnr,unit) end end return nrf end
4. LCD Print – > Voltage / Current / Energy / Power
For more details about the I2C LCD Driver , please take a look at the ST7032i LCD Driver Article
LCDout = function() if (t==0) then st7032i:lcd_clear() end if (adcV > 1) then st7032i:lcd_print(1,1,string.format("%.3fV",adcV)) adci = nr_format(adcI,"mA") st7032i:lcd_print(8,1,adci) pwrp = nr_format(pwr,"mW") st7032i:lcd_print(0,2,pwrp) cpct=cpct+pwr*0.002778 --every 10 sec readings cpctp = nr_format(cpct,"mWh") t = t +1 st7032i:lcd_print(8,2,cpctp) else tmr.stop(0) dtime = t/360 st7032i:lcd_print(0,1,string.format("Disc.Time:%.2fh ",dtime)) st7032i:lcd_print(0,2,"Energy: ") end end
5. MAIN program
require('st7032i') st7032i:init_i2c(sda,scl) st7032i:init_LCD() st7032i:lcd_clear() 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)
For testing, just save the code on ESP as ‘blms.lua‘, restart ESP and run:
dofile(“blms.lua“) — Start the Battery Live Monitoring System
|Running BLMS program|
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.