With the rise of IoT (Internet of Things) applications, monitoring battery levels remotely has become a crucial requirement in many industries. An IoT-based battery level indicator allows users to monitor battery voltage in real time through a cloud-based platform or a mobile application. This system is particularly useful for battery-powered IoT devices, electric vehicles, solar energy storage, and remote sensors.
Components Required
- ESP8266 NodeMCU
- TP4056 Battery Charging Protection Module
- 18650 Battery
- 100k ohm Resistors
- Breadboard
- Jumper/Connecting Wires
Working Principle
The IoT based battery level indicator continuously measures the battery voltage and transmits the data to Arduino IoT Cloud. The voltage divider circuit scales down the battery voltage to a safe level that the ESP8266 NodeMCU can read. The microcontroller then processes the data and sends it to the cloud via Wi-Fi. Users can access the battery level information through a mobile app(IOT Remote), receiving alerts when the battery reaches critical levels.
Understanding the Components
ESP8266 NodeMCU
-
A Wi-Fi-enabled microcontroller that reads the battery voltage and transmits data to the Arduino IoT Cloud.
-
Provides easy integration with IoT cloud platforms.
TP4056 Battery Charging Protection Module
-
Ensures safe charging and discharging of the 18650 battery.
-
Protects against overcharging, over-discharging, and short circuits.
Arduino IoT Cloud for Monitoring
-
A cloud platform where the voltage and battery percentage can be visualized.
-
Provides an easy-to-use dashboard accessible from mobile devices or web browsers.
IoT Battery Charging Level Monitor Circuit Diagram


Connections:
Battery (BAT1)
- Positive (+) terminal → B+ of TP4056
- Negative (-) terminal → B- of TP4056
TP4056 Module (TP1)
- B+ → Battery positive terminal
- B- → Battery negative terminal
- OUT+ → Positive output (can be used to power a load)
- OUT- → Negative output (ground)
Voltage Divider (R1 & R2)
-
R1 (100kΩ)
- One end connected to OUT+ of TP4056
- Other end connected to the junction of R2 and A0 of ESP8266
-
R2 (100kΩ)
- One end connected to the junction of R1 and A0 of ESP8266
- Other end connected to OUT- (GND) of TP4056
ESP8266 NodeMCU (U1)
- VIN → Not connected in this circuit
- GND → Connected to OUT- (GND) of TP4056
- A0 → Connected to the voltage divider junction (between R1 & R2)

Note: IOT Implementation: Please refer the video for integrating ESP8266 Node MCU with Arduino Cloud.
Code Explanation
include "thingProperties.h"
- This includes the
thingProperties.h
file, which is automatically generated by Arduino IoT Cloud. - It contains cloud-related settings, including the variables and functions needed to interact with the Arduino IoT Cloud Dashboard.
int analogInPin = A0;
int sensorValue;
-
analogInPin = A0;
→ Defines A0 as the input pin where the battery voltage is read. -
sensorValue;
→ Stores the raw ADC value from the ESP8266's 10-bit ADC.
Serial.begin(9600);
delay(1500);
- Starts the serial communication at 9600 baud rate.
- The
delay(1500);
allows the Serial Monitor to initialize before the program continues.
initProperties();
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
-
initProperties();
initializes the cloud variables (voltage
andpercentage
). -
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
starts the Arduino IoT Cloud connection.
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
-
setDebugMessageLevel(2);
sets the debug level to 2, which provides detailed debugging info. -
ArduinoCloud.printDebugInfo();
prints the connection status and error details.
void loop()
The loop()
function:
- Reads the analog voltage from the battery.
- Converts the ADC reading into voltage.
- Maps the voltage to a percentage.
- Ensures the percentage is within a valid range.
- Prints the values to the Serial Monitor.
- Updates the Arduino IoT Cloud.
sensorValue = analogRead(analogInPin);
- Reads the analog voltage from A0.
- Since ESP8266 uses a 10-bit ADC (0-1023),
sensorValue
will be a value between 0 and 1023.
voltage = (((sensorValue * 3.3) / 1023) * 2 );
- The ESP8266 ADC reference voltage is 3.3V.
- The ADC value is converted to voltage using:
- The
×2
factor is due to the voltage divider circuit (two 100kΩ resistors) which halves the input voltage before measuring.
percentage = mapfloat(voltage, 2.8, 4.2, 0, 100);
- The function
mapfloat()
maps the battery voltage range (2.8V - 4.2V) to 0% - 100% battery level. - 2.8V → 0% (Battery low)
- 4.2V → 100% (Battery full)
percentage = constrain(percentage, 1, 100);
- Ensures
percentage
stays within 1% - 100% (prevents negative or unrealistic values).
Serial.print("Analog Value = ");
Serial.print(sensorValue);
Serial.print("\t Output Voltage = ");
Serial.print(voltage);
Serial.print("\t Battery Percentage = ");
Serial.println(percentage);
Displays:
- Raw ADC Value
- Calculated Voltage
- Battery Percentage
delay(1000);
- Adds a 1-second delay before the next reading.
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
- This function is similar to the Arduino
map()
function, but it works with floating-point values. - It scales the voltage reading (2.8V - 4.2V) to a percentage (0% - 100%).
Results:
After uploading the code to the ESP8266 and running the system, real-time battery voltage readings were displayed on the Dashboard. The output voltage was derived from the analog readings of the battery, and the charge percentage was mapped accordingly.
Code
#include "thingProperties.h"
int analogInPin = A0;
int sensorValue;
void setup() {
Serial.begin(9600);
delay(1500);
initProperties();
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
}
void loop() {
ArduinoCloud.update();
sensorValue = analogRead(analogInPin);
voltage = (((sensorValue * 3.3) / 1023) * 2 );
percentage = mapfloat(voltage, 2.8, 4.2, 0, 100);
percentage = constrain(percentage, 1, 100);
Serial.print("Analog Value = ");
Serial.print(sensorValue);
Serial.print("\t Output Voltage = ");
Serial.print(voltage);
Serial.print("\t Battery Percentage = ");
Serial.println(percentage);
delay(1000);
}
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}