ESP8266 Projects Blog
Home of CBDB / MPDMv4 /SmartMon Development boards (ESP-12/ESP-07).
Guidelines and ESP8266 programming examples using LUA, Eclipse and Arduino IDE, ESP Basic and many more!
2 Resistors for the voltage divider, R1=105.6k, R2=24.08k. I am using here precision resistors and the values are measured values with a proper calibrated bench meter.
Voltage divider schematic and Vout (ADC input voltage) formula
How do we do it :
1. Measure your Max desired input voltage In my case, Max Input Voltage (Vmax) = 5.1919 (measured)
2. Measure Resistors values: R1 = 105.6k R2 = 24.08k 3. Check if Full Scale Value at the voltage divider output is inside the ADC defined domain:
Calculated : Vout = (R2/(R1+R2))*Vin = 0.964072733 V
Measured = 0.96038V
Good enough for the precision we are looking for. ESP8266 ADC is 10bit only and not exactly the most accurate in town
4. Calculate Voltage Divider Ratio:
Vdivider Ratio= Max Input Voltage/Fullscale value = 5.405976676
5. Read ADC value :
adcr = adc.read(0) print(" ReadADC : "..adcr)
Average result for adcr = 1017
THIS IS IMPORTANT !! It tell us that we are inside the ADC domain as adcr < 1024 !
IF adcr > 1023 then you need to adjust your voltage divider resistors to fit inside ADC domain!
6. Calculate LSB in 2 ways to cross check that we have the right value:
LSB = Input Voltage read by multimeter/ADC readed Value =
= 5.1919 / 1017 = 0.005105113 V
OR
LSB = (ADC Input pin read Voltage by multimeter/ADC readed Value/)*Vdivider Ratio =
= (0.96038/1017)*5.405976676 = 0.005105113 V
It looks that we have the right LSB Value for our exercise!
If you want to know also the ADC LSB, then
LSB = ADC Input pin read Voltage by multimeter/ADC readed Value = = 0.96038/1017 = 0.000944346 V
Guess what's happening if you multiply ADC LSB with Vdivider ratio :)
7. Software Implementation for the ADC read function:
function readADC() ad = 0 LSB = 0.005105113 --calibrate based on your voltage divider AND Vref! adcr = adc.read(0) ad= adcr*LSB print(" ReadADC : "..adcr) print(" Read Voltage : "..ad) return ad end
As you might read already in my previous ESP8266 Battery Monitor System post I was using Thingspeak.com, because of it's flexibility, as a logger for live data uploading.
In the latest week I was exploring deeper Thigspeak capabilities.
What I was interested for was to check the possibility to build/configure and use a standalone Thingspeak Server that can run independently of Internet infrastructure on a small footprint, low power consumption platform.
The interesting part regarding the Thingspeak Server deployment is the chosen platform, the new RASPBERRY PI 2 Board!
I will present you below the step-by-step process to install your own
RPI Thingspeak Server that can be tailored on your own needs and
ofcourse, not affected by Internet connection availability and uptime if
installed in the same physical location/LAN as your ESP8266 BMS or any sensor grid/array you might want to use with!
INSTALLATION PROCESS:
1. Install a Raspberry Pi Operating System image on SD card
4. MySQL Database configuration pi@RPIMON1~$mysql --user=root mysql -p useyourpasswd here pi@RPIMON1~$mysql> CREATE USER 'thing'@'localhost' IDENTIFIED BY 'speak’; pi@RPIMON1~$mysql> GRANT ALL PRIVILEGES ON *.* TO 'thing'@'localhost' WITH GRANT OPTION; pi@RPIMON1~$mysql> commit; pi@RPIMON1~$mysql> exit;
================== W A R N I N G ! ! =================
Li-Ion batteries are very dangerous if not handled properly.
Use them only with proper protection circuits and chargers.
DO NOT OVER CHARGE / BURN / OPEN Li-Ion Bats
Using any of the informations available on esp8266-projects.com
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: http://dirtypcbs.com/view.php?share=5876&accesskey=3d0fd70d53d6dc20c0bf0255f67cde65
------------------------------------------------------------------------------------------------------------------
function sendDataTh() print("Sending data to thingspeak.com") conn=net.createConnection(net.TCP, 0) conn:on("receive", function(conn, payload) print(payload) end) conn:connect(80,'184.106.153.149') conn:send("GET /update?key=YOURKEYHERE&field1="..adcV.."&field2="..adcI.."& field3="..pwr.."&field4="..cpct.."HTTP/1.1\r\n") conn:send("Host: api.thingspeak.com\r\n") conn:send("Accept: */*\r\n") conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n") conn:send("\r\n") conn:on("sent",function(conn) print("Closing connection") conn:close() end) conn:on("disconnection", function(conn) print("Got disconnection...") end) end
5. MAIN program
If you have a new ESP module or is the first time when using it on a new WIFI network, don't forget to do the WIFI setup:
-- One time ESP Setup -- wifi.setmode(wifi.STATION) wifi.sta.config ( "YOUR_WIFI_SSID" , "PASSWORD" ) print(wifi.sta.getip())
-- Read ADC data every 10s, print values on local Web interface and send them to thingspeak.com tmr.alarm(0, 10000, 1, function() readUI() sendDataTh() end)
For testing, just save the code on ESP as 'blmsweb.lua', restart ESP and run: dofile("blmsweb.lua") -- Start the Battery Live Monitoring System print(wifi.sta.getip()) --print your BMS WebServer IP address
BLMS - First RUN
If you want the BLMS software to start automatically when your CBDBv2 Evo Board
starts or reboots, then you neet to create and add some lines in your
'init.lua' file: dofile("blmsweb.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.
Open your favorite Web browser and type your new BLMS Web Server IP address. If all ok, it should look like below :
BLMS - Web Server interface - 20ohm Load
Thingspeak data upload
I will not insist on the Thingspeak.com account setup, it's a pretty simple process:
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 10x200 = 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)
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 haveVmaxIN=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.
INA21x Features: • Wide Common-Mode Range: –0.3 V to 26 V • Offset Voltage: ±35 μV (Max, INA210) (Enables Shunt Drops of 10-mV Full-Scale) • Accuracy: – ±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 Current - add your favourite Current Monitor but don't forget about the VmaxIN for ESP8266 ADC of about 1V!
BLMS Software For programming CBDBv2 Board and uploading the drivers and the software we will continue to use the LuaUploader as before.
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.
Software Implementation 1. Define used GPIO pins and variables:
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
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 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.
That's all for today, next time we will continue with Web Interface and online logging system for the BLMS!
Finished Board with headers and some EXT modules in place:
CBDB Evolution - bottom view
EXT Modules
CBDB Evolution - top view
First thing to see is how easy is the process to configure and start using CBCBv2 (code name Evolution) Board. It will come preconfigured with NodeMCU, so, if LUA is your desired programming language you can just start using it.
In
case of firmware update needed or if you want to change the
environment, it is a very easy process, similar with the one used for
MPSM Board.
connect CBDB Module with the USB Adapter (Tx, Rx, 3v3, GND), Set the PROG jumper in the Programming mode position (closed) and power on
CBDBv2 - Firmware Programming mode enabled
Start NodeMCU Flasher. Choose you USB adapter corresponding port
Add from Config Menu latest previously downloaded firmware. It must start from 0x0000. Disable anything else.
Go back on Operation tab. Power off your CBDB Module. Press FLASH
Button. power ON quick CBDB module. It will be recognised and will start
flashing. Give it a second try if necessary.
When finished succesfully A green OK checkmark will appear
Power Off CBDB Module, Remove yellow jumper. Power back ON. Your
CBDBv2 Board should be now programmed with the new NodeMCU Firmware.
If you change very often the firmware or want a easier way to use CBDBv2 DevBoard with Arduino IDE or direct GCC/Eclipse programming then maybe you will prefer the second available procedure for uploading your firmware:
2. Using the Auto reset/bootloading mode:
Another great tool for uploading new firmware for your CBDBv2 DevBoard is esptool.
I want to thank you themadinventor for such a great utility program and also want to thank for the received improvements from several
members of the ESP8266 community, including pfalcon, tommie, 0ff and
george-hopkins. Great job!
We will use in this example the CK version (thank you Christian) but any version of esptool that is supporting the RTS/DTR reset/bootloading mode must work ok. If you want to avoid compiling yourself the program you can download the binary file from here: esptool-bin.zip
Upload procedure:
connect CBDB Module with the USB Adapter (Tx, Rx, RTS, DTR, 3v3, GND) and power on
Auto reset/bootloading mode configuration
In Command Prompt Start esptool.exe program:
D:\ESPTool>esptool.exe -cp COM34 -cd ck -cf nodemcu_latest.bin
cp - Select the serial port device to use for communicating with the ESP. cd - Select the reset method to use for resetting the board. cf - Select the firmware file that you want to flash memory
For further programming in LUA, it might be possible to do it directly
in your Serial Terminal Program but I will recomend you to use a more
dedicated program for that, like LuaLoader or LuaUploader. I will stay with the latest one, for it's great flexibility and simplicity.
To run a quick test, you can just use the code snippets provided by LuaUploader
at start-up. Select the piece of code that you want to run and press
"Execute Selection" button.
To quick setup your WIFI network :
-- One time ESP Setup -- wifi.setmode(wifi.STATION) wifi.sta.config ( "YOUR_WIFI_SSID" , "PASSWORD" ) print(wifi.sta.getip())
For the Blinky test, just use a prepared LED as in the picture,
insert it on previously used yellow jumper place (GPIO0) and run the code from below
Arduino IDE first test for direct programming and firmware uploading on the new ESP8266 CBDBv2 Evolution DevBoard. No manual reset needed , no buttons to press, just press Upload and that's it!
Running Blinky LED program on GPIO15:
// the setup function runs once when you press reset or power the board void setup() { // initialize digital pin 15 as an output. pinMode(15, OUTPUT); }
// the loop function runs over and over again forever void loop() { digitalWrite(15, HIGH); // turn the LED on (HIGH is the voltage level) delay(500); // wait for a second digitalWrite(15, LOW); // turn the LED off by making the voltage LOW delay(500); // wait for a second }