IoT based Battery Monitoring System using NodeMCU and ThingSpeak

IoT based Battery Monitoring System using NodeMCU and ThingSpeak

Battery is the most important component for any device as it powers the whole system. And it is important to monitor the voltage level of the battery as improper charging and discharging of a lithium battery may lead to a big safety issue. There is a separate system in electric vehicles, called Battery Management System (BMS) which monitors all the properties of the battery pack like voltage, current, temperature, etc. and ensures the safety and handling of Lithium batteries.

Previously Battery Monitoring System only monitors the condition of the battery and alarms the user via battery indicator inside the vehicle. Due to the advancement in technology, now Internet of Things (IoT) can be used to notify the manufacturer and users remotely regarding the battery status. They can check the battery status of the car’s battery on their smartphones from anywhere in the world and this is considered as one of the maintenance support provided by the manufacturer.

So, in this project, we will also build an IoT based Battery Monitoring System where you can not only monitor the charging and discharging status of the battery but can also get an alert email when the battery is full or empty. Here we will use NodeMCU 12E to send the battery status data to ThingSpeak cloud and will use IFTTT to send the Email alerts on battery status.

 

Components Required:

  1. NodeMCU (ESP-12E)
  2. Lithium Polymer Battery
  3. LiPo Charger (TP4056)
  4. Resistors
  5. Any DC load like DC motors
  6. Jumper Wires

 

Calculating Battery Voltage

NodeMCU analog pin can withstand only 3.3v so we have to make an arrangement to convert high input voltage within the range of NodeMCU analog pin and then write code to compute the actual voltage being measured.

Now, the arrangement that will convert the voltage is Voltage divider circuit. The voltage divider decreases the voltage being measured within the range of the NodeMCU analog input which is 3.3v. We have to find the values of the required resistors for the circuit. The maximum input voltage will depend on the values of the resistors. So, I choose R1=44k and R2=10k (These are the printed value but actual value may be different so first measure the actual value using multimeter then use these values for further calculations). In my case, actual values are R1=47k and R2=9.5k

Voltage Divider Circuit

So by using the Voltage divider formula, the input voltage can be calculated as:

Vout (A0) = (VIN*R1) / (R1+R2)
Max Vin = Vout*(R1+R2) / R1

Consider Vout is 3.3v

After putting the resistor and Vout values Max Vin will be calculated 19v approx. But in practice, it is better to provide a voltage which is less than the max value so you can use 15v battery voltage safely.

 

Circuit Diagram

Circuit diagram for Battery Monitoring System is shown below. Output of the voltage divider circuit is given to the A0 pin of NodeMCU. A TP4056 charging module is used for charging the LiPo battery and a DC motor is used for discharging purpose which is connected to the output terminal of TP4056.

 IoT Battery Monitoring System Circuit Diagram using NodeMCU

 

IoT based Battery Monitoring Project Hardware Setup

 

Configuring ThingSpeak to plot Charging and Discharging Voltage

ThingSpeak provides a very good tool for IoT based projects. By using the ThingSpeak site, we can monitor our data and control our system over the Internet, using the Channels and webpages provided by ThingSpeak. ThingSpeak ‘Collects’ the data from the sensors, ‘Analyze and Visualize’ the data and ‘Acts’ by triggering a reaction.

Here we are briefly explaining to use ThingSpeak for this IoT Battery Monitoring Project. You can check various ThingSpeak based Iot projects here to learn more about it.

We will use ThingSpeak to monitor battery charging and discharging voltage. We will also use IFTTT platform to connect with ThingSpeak to send email/message alerts for a full or empty battery.

 

Step 1:- First of all, the user needs to Create an Account on ThingSpeak.com, then Sign In and click on Get Started.

 

Step 2:-  Now go to the ‘Channels’ menu and click on New Channel option on the same page for further process. You will see a form for creating the channel, fill in the Name and Description as per your choice. Then fill ‘Charging Voltage’, and ‘Discharging Voltage’ in Field 1 and Field 2 labels, tick the checkboxes for the Fields. Click on Save channel at bottom of the page. Now your new channel has been created.

ThingSpeak for IoT based Battery Monitoring System

 

Step 3:- Click on API Keys menu and copy the Write API key. This key will be used in the code to send the data on ThingSpeak.

ThingSpeak Configuration for IoT based Battery Monitoring System

 

Step 4:- Now, we will use ThingHTTP app of the server to trigger the IFTTT applet to send mail whenever the battery is full or empty. You can specify actions in ThingHTTP, which you want to trigger using other ThingSpeak apps such as React.

To make New ThingHTTP, we will need a URL for triggering which we can be obtained from IFTTT.

 

Configuring IFTTT for triggering Mail/SMS for Battery Monitoring

Here we are linking ThingSpeak with IFTTT via webhooks to automatically send the email when Battery is Full or Empty. To learn more about how IFTTT works, here are many tutorials and live IoT projects using IFTTT.

Step 1:- Login to IFTTT and search for Webhooks and click on it.

Configuring IFTTT for Triggering Mail

 

Step 2:- Click on Documentation.

Webhooks Setup for IoT based Battery Monitoring System

 

Step 3:- Type “bat_full” in the event box and copy the URL. This URL will be used in ThingHTTP.

Configuration to Trigger an Event

 

Now let’s make Applet to link ThingHTTP to Gmail to send an email. After that, we will jump to complete our ThingHTTP.

Step 4:- Click on New Applete in My Applete option.

IFTTT Configuration for IoT based Battery Monitoring System

 

 

Step 5:- Click on “+this” and search for Webhooks and click on it. Choose trigger as “Receive a web request”.

Now let’s make Applet to link ThingHTTP to Google sheet and to send email/SMS. After that, we will jump to complete our ThingHTTP.

 

Step 6:- Click on “+this” and search for Webhooks and click on it. Choose trigger as “Receive a web request”.

Trigger Setup for Battery Monitoring System

 

Step 7:- Type the Event Name which is the same as you write in the event box in webhooks URL. Click on Create Trigger.

 

Trigger Configuration for IoT based Battery Monitoring System

Step 8:- Click on “+that” and search for Gmail and click on it. Now, click on Send an email.

Email Configuration for IoT based Battery Monitoring System

 

Type the email addresses on which you wish to receive an email when there is an update regarding the battery.

IoT based Battery Monitoring System using NodeMCU

 

Type the body content you wish to send in the email and click on create action. Review it and finish.

IoT based Battery Monitoring System using NodeMCU

 

Similarly, make an applet for getting mail regarding battery empty alert.

We have made our applets to perform the tasks. Now, come back to ThingSpeak->Apps->ThingHTTP.

 

ThingHTTP for connecting ThingSpeak with IFTTT for Email Alerts

Step 1:- Click on New ThingHTTP. Give any name and Paste the URL that you copied from the webhooks documentation. Fill Remaining information as shown below.

ThingHTTP for connecting ThingSpeak with IFTTT for Email Alerts

In the same manner, we have to make ThingHTTP for “bat_empty”. Follow the same steps.

In URL, write bat_empty in place of bat_full. Body remains empty and all other information is same as in the previous ThingHTTP. Save it.

 

Now, we have to make React to trigger the URL.

React works with ThingHTTP app to perform actions when channel data meets a certain condition.

To make React, click on Apps -> React. Click on New React.

 

Step 2:- Give a name to your React. Condition type as Numeric and Test Frequency as on Data Insertion.

Choose the Condition on which you want to trigger the URL. Select your channel from the If Channel drop-down menu. Choose field 1 i.e. charging_volatge and make a condition of greater than and equal to 4.1. As shown

ThingHTTP for connecting ThingSpeak with IFTTT for Email Alerts

 

Choose ThingHTTP from Action drop-down menu and select the bat_full.

Select “Run action each time condition is met” and click on Save React.

Similarly, make react for bat_empty.

We have done with all the Web-based work. Now, we will see the code for our NodeMCU.

 

Code Explanation:

Complete code with a working video for this IOT based Battery Monitoring System is given at the end of this tutorial, here we are explaining the code in detail.

  1. First include all the required libraries. Also, initialize SSID and password of your Wi-Fi network and write API key that we had copied from ThingSpeak platform.
#include <ESP8266WiFi.h>
String apiKey = "***********";     
const char* ssid =  "********";     
const char* pass =  "********"; 
const char* server = "api.thingspeak.com";
  1. Now declare and initialize resistors values and some other variables and constants.
float volt =0.0;
float temp=0.0;
float r1=47000.0;    
float r2=9700.0;      
int flag = 1;
  1. In void setup() function, initialize serial communication and check for the Wi-Fi connection .
void setup()
{
   Serial.begin(115200);     
   WiFi.begin(ssid, pass);
      while (WiFi.status() != WL_CONNECTED) 
     {
            delay(100);
            Serial.print("*");}
  1. In void loop() function, we will take readings from an analog pin and will convert this value to actual voltage value as shown below.
int analog value = analogRead(A0);
    temp = (analogvalue * 3.3) / 1024.0;
    volt = temp / (r2/(r1+r2));  

 

Now, we will use a flag variable to track the status of the battery whether the battery is full or empty then accordingly send the voltage data to the respective graph on the ThingSpeak. Initially, we have taken the flag as 1 which means the battery is charging.

if (volt >= 4.1){
    flag=0;
    }
    if (volt <= 3.2){
      flag = 1;
      }

 

For sending voltage data to check for the flag and upload the data in the respective graph.

if(flag == 1) {
    if (client.connect(server,80))        { 
       String sendData = apiKey+"&field1="+String(volt)+"\r\n\r\n"; 
       client.print("POST /update HTTP/1.1\n");
       client.print("Host: api.thingspeak.com\n");
..
       }
Similarly for field 2.
Else if (flag == 0){
    if (client.connect(server,80))        { 
       String sendData = apiKey+"&field2="+String(volt)+"\r\n\r\n"; 
       client.print("POST /update HTTP/1.1\n");
       client.print("Host: api.thingspeak.com\n");
..

Reading will be updated every 10 seconds. For this, delay or timer function can be used. Here I am using the delay function.

Now, the coding part is done. Full code is given at the end of the tutorial. Upload this code to the NodeMCU and make sure to enter the credentials correctly.

You can check the reading on the serial monitor and ThingSpeak as shown below.

Readings of IoT based Battery Monitoring System

Graphical Readings of IoT based Battery Monitoring System using NodeMCU

The charging and discharging curves on ThingSpeak are shown in the above figure. The left figure shows the curve during charging and the right one shows the curve during the discharging of Lithium battery.

Now, whenever the battery is full or empty, the user will get an email notifying that battery is FULL or EMPTY.

Battery Status alert for IoT based Battery Monitoring System

 

So this is how a Battery voltage status can be monitored from anywhere in the world using ThingSpeak cloud and NodeMCU Wi-Fi module.

Also, check the video below.

Code

#include <ESP8266WiFi.h>

String apiKey = "************";     
const char* ssid =  "awesome";     // Enter your WiFi Network's SSID
const char* pass =  "awesome12"; // Enter your WiFi Network's Password
const char* server = "api.thingspeak.com";

WiFiClient client;
 
float volt =0.0;
float temp=0.0;
float r1=47000.0;    //r1 value 47k 
float r2=9700.0;      //r2 value 9.7 k
int flag = 1;
void setup()
{
   Serial.begin(115200);     
   Serial.println("Connecting to ");
   Serial.println(ssid);
   WiFi.begin(ssid, pass);
 
      while (WiFi.status() != WL_CONNECTED) 
     {
            delay(100);
            Serial.print("*");
     }
      Serial.println("");
      Serial.println("WiFi connected");
}

void loop()
{
    int analogvalue = analogRead(A0);
    temp = (analogvalue * 3.3) / 1024.0;       
volt = temp / (r2/(r1+r2));
if (volt < 0.1) 
   {
     volt=0.0;
   } 
   if (volt >= 4.1){
    flag=0;
    }
    if (volt <= 3.2){
      flag = 1;
      }
       Serial.print("Voltage: ");
       Serial.println(volt);
   if(volt>=3.2 && volt<=4.2 && flag == 1) {
    if (client.connect(server,80))         { 
       
       String sendData = apiKey+"&field1="+String(volt)+"\r\n\r\n"; 
       client.print("POST /update HTTP/1.1\n");
       client.print("Host: api.thingspeak.com\n");
       client.print("Connection: close\n");
       client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
       client.print("Content-Type: application/x-www-form-urlencoded\n");
       client.print("Content-Length: ");
       client.print(sendData.length());
       client.print("\n\n");
       client.print(sendData);

       Serial.println("%. Connecting to Thingspeak.");
       }
      
      client.stop();
       Serial.println("Sending....");
   }
 else if(volt>=3.2 && volt < 4.2 && flag == 0){
    if (client.connect(server,80))   //   "184.106.153.149" or api.thingspeak.com
      { 
     
       String sendData = apiKey+"&field2="+String(volt)+"\r\n\r\n"; 
       client.print("POST /update HTTP/1.1\n");
       client.print("Host: api.thingspeak.com\n");
       client.print("Connection: close\n");
       client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
       client.print("Content-Type: application/x-www-form-urlencoded\n");
       client.print("Content-Length: ");
       client.print(sendData.length());
       client.print("\n\n");
       client.print(sendData);
     
       Serial.println("Connecting to Thingspeak.");
       }
      
      client.stop();
      Serial.println("Sending....");
 }
 delay(10000);
}
 

Video