Build Your Own Smart Solar Battery Voltage Monitor with NodeMCU

Solar Battery Voltage Monitor with reverse protection

In the world of renewable energy, knowledge is power. As solar power systems become a staple for home automation, backup power solutions, and off-grid living, the health of your battery bank remains the single most critical factor for reliability.

A dead or damaged battery can render your entire solar setup useless.

Overcharging can destroy a battery’s internal chemistry, while deep discharge can permanently reduce its capacity. So, how do you keep a constant eye on your power storage without standing there with a multimeter 24/7?

The answer is automation. In this comprehensive guide, we will walk you through building a Solar Battery Voltage Monitor using NodeMCU, a 16×2 LCD display, and a 0-25V voltage sensor. This DIY project not only displays real-time voltage but also detects charging status and integrates essential protection circuits to ensure your battery lasts for years.

Why Every Solar User Needs a Battery Voltage Monitor

Before diving into the wiring and code, it’s important to understand the “why.” A 12V Lead-Acid or Lithium battery—common in solar setups—has a specific operating window.

  • Sulfation: If a lead-acid battery sits at a low voltage (below 11.8V) for extended periods, sulfate crystals form, reducing capacity.
  • Thermal Runaway: Overcharging causes excessive heat and gas release, which can be dangerous.

By implementing a real-time battery monitoring system, you can intervene early, adjust your power consumption, or simply trust that your automatic cutoff circuit is working correctly.

System Overview: How the Solar Charging Monitor Works

This project is more than just a voltage reader; it’s a complete monitoring station. The architecture ensures that the energy flowing from the solar panel to the battery is stable, safe, and well-documented.

Here is the flow of energy and data:

image

Solar Panel → Voltage Regulation → Reverse Polarity Protection → Overvoltage Auto Cutoff → NodeMCU Monitoring → Battery → LCD Display

  1. Power Stage: The solar panel generates electricity. It passes through an LM317 voltage regulator to ensure stable output.
  2. Protection Stage: Reverse polarity diodes prevent wiring mistakes from frying your circuit. An automatic cutoff circuit (using a relay) disconnects the solar panel when the battery hits full charge.
  3. Monitoring Stage: The NodeMCU reads the battery voltage via a voltage sensor and displays the data on an LCD. It also detects whether the battery is charging or discharging.
IMG 2413 edited

Components Required for the DIY Solar Monitor

To build this project, you will need the following components. These are readily available and inexpensive, making this a perfect weekend project.

Microcontroller & Display

  • NodeMCU ESP8266: The brain of the operation, featuring WiFi (for future IoT upgrades).
  • 16×2 LCD Display: For visual output.
  • I2C LCD Adapter: Reduces wiring clutter (only needs two data pins).

Sensors & Power Components

  • 0-25V Voltage Sensor Module: The interface between the high-voltage battery and the 3.3V NodeMCU.
  • Solar Panel: Any small panel suitable for charging a 12V battery.
  • 12V Battery: Lead-acid or Lithium.
  • Voltage Regulator IC (LM317): To regulate solar panel output.
  • 7805 Voltage Regulator IC: To step down battery power to 5V for the NodeMCU.

Protection & Passive Components

  • Diodes: 1N4007 and 1N5408 (for reverse polarity protection).
  • Relay Module & Transistor (BC547): For the automatic cutoff circuit.
  • Resistors, Capacitors, and a Potentiometer.

Circuit Design and Protection Layers

A reliable solar system requires robust hardware. Let’s break down the three main hardware blocks that ensure safe charging.

1. Voltage Regulator with Reverse Polarity Protection

Solar panels are fickle; their voltage fluctuates with cloud cover and sun intensity. An LM317-based regulator circuit smooths this out. We integrate high-current diodes on the input lines to provide reverse polarity protection. If you accidentally swap the positive and negative wires from the panel, the diodes block the current, saving the rest of the electronics.

Solar Battery Voltage Monitor

2. Automatic Overvoltage Cutoff Circuit

Overcharging is the #1 killer of batteries. This circuit uses a relay controlled by a BC547 transistor. You set a threshold (e.g., 14.4V for a 12V lead-acid battery) using a potentiometer.

  • When the voltage hits the limit, the relay activates and disconnects the solar panel.
  • When the voltage drops slightly, the relay reconnects to resume charging.
  • LED Indicators: A Green LED shows “Charging,” while a Red LED indicates “Full/Cutoff.”
  • Note: Connect R1 10k input + side to change output + side connection for continuous cuttoff protection
Solar Battery Voltage Monitor

3. NodeMCU Power Supply

The NodeMCU operates at 5V, but your battery is 12V. We use a 7805 voltage regulator to step down the battery voltage to a stable 5V supply for the microcontroller.

Wiring the NodeMCU, LCD, and Voltage Sensor

Connecting the components is straightforward. The use of an I2C LCD adapter simplifies the connections significantly.

LCD I2C Connections (Only 2 Wires!)

  • D1 (GPIO5) on NodeMCU → SCL on LCD
  • D2 (GPIO4) on NodeMCU → SDA on LCD
  • Vin & GND: Connect to 5V and Ground.

Voltage Sensor Connection

The 0-25V sensor module uses a voltage divider to step down the input voltage.

  • Voltage Sensor (S pin) → A0 (Analog Pin) on NodeMCU.
  • Voltage Sensor (+ & -): Connect across the battery terminals.

Charging Detection

  • A digital pin (e.g., D6) is connected to the charging circuit to detect if the relay is active (charging) or inactive (cutoff).

Programming Logic: From Analog Reads to Battery Health

The magic happens in the code. The NodeMCU reads the analog voltage and converts it into meaningful data.

The Voltage Calculation Formula

The NodeMCU’s analog pin reads voltages from 0 to 3.3V. Since our battery is 12V, the sensor divides the voltage by a factor of 5. The code reverses this math.

Battery Voltage = (ADC Value / 1023.0) * Reference Voltage * Voltage Divider Ratio

We use a calibration factor in the code to fine-tune the accuracy.

Battery Level Detection Logic

Raw voltage numbers (like 12.3V) don’t mean much to the average user. We translate them into plain English on the LCD:

  • >= 12.5V:  Full Battery
  • 12.3V – 12.5V: Good Level
  • 12.1V – 12.3V: Average Charge
  • 11.9V – 12.1V: Low Battery
  • < 11.7V:  Critical/Poor Health

Charging Animation

When the D6 pin detects that the charging circuit is active, the LCD displays an animated charging symbol. When charging stops, it reverts to showing the static battery health status. This visual feedback is excellent for at-a-glance monitoring.

Advantages of a NodeMCU-Based Solar Monitor

Why choose the NodeMCU over a simple analog voltmeter?

  1. Real-Time Precision: It provides a digital readout, eliminating the guesswork of analog needles.
  2. Safety Integration: It works in tandem with the hardware cutoff circuit.
  3. IoT Ready: The NodeMCU has built-in WiFi. While this basic project focuses on the LCD, the infrastructure is there to upload data to a WiFi battery monitoring dashboard in the future.
  4. Cost-Effective: It is cheaper and more customizable than commercial battery monitors.

Future Upgrades: Turning it into a Smart IoT System

The beauty of using an ESP8266 is the potential for expansion. Once you have the basic voltage monitor working, you can upgrade it with software features:

  • Remote Monitoring: Use platforms like Blynk or Home Assistant to view your battery voltage from your smartphone anywhere in the world.
  • Push Notifications: Get an alert on your phone when the battery is full or if the voltage drops to a critical level.
  • Data Logging: Track daily voltage fluctuations to analyze your power consumption patterns over time.
  • Automatic Load Control: Program the NodeMCU to turn off non-essential loads via a relay if the battery gets too low.

Real-World Applications

This solar battery monitoring system isn’t just a learning tool; it’s a practical device for:

  • RV and Campervans: Keep track of your leisure battery without leaving your bunk.
  • Cabin/Off-Grid Homes: Essential for remote locations where grid power is unavailable.
  • Solar-Powered Sheds and Workshops:
  • Backup UPS Systems: Monitor the health of your emergency power supply.

Source Code

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

const int voltageSensorPin = A0;
const int chargingDetectPin = 12;

float batteryVoltage = 0.0;
bool isCharging = false;
int batteryLevel = 0; // 0-5 for battery bars

// Better looking battery icons
byte batteryEmpty[] = {
  0b01110,
  0b11011,
  0b10001,
  0b10001,
  0b10001,
  0b10001,
  0b10001,
  0b11111
};

byte batteryBar1[] = {
  0b01110,
  0b11011,
  0b10001,
  0b10001,
  0b10001,
  0b10001,
  0b11111,
  0b11111
};

byte batteryBar2[] = {
  0b01110,
  0b11011,
  0b10001,
  0b10001,
  0b10001,
  0b11111,
  0b11111,
  0b11111
};

byte batteryBar3[] = {
  0b01110,
  0b11011,
  0b10001,
  0b10001,
  0b11111,
  0b11111,
  0b11111,
  0b11111
};

byte batteryBar4[] = {
  0b01110,
  0b11011,
  0b10001,
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11111
};

byte batteryFull[] = {
  0b01110,
  0b11011,
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11111
};

byte chargingBattery[] = {
  0b01110,
  0b11011,
  0b10101,
  0b10001,
  0b10101,
  0b10001,
  0b10101,
  0b11111
};

void setup() {
  Serial.begin(115200);
  
  lcd.init();
  lcd.backlight();
  
  // Changed from INPUT_PULLUP to INPUT (no pullup resistor)
  pinMode(chargingDetectPin, INPUT_PULLUP);
  
  // Create custom characters
  lcd.createChar(0, batteryEmpty);
  lcd.createChar(1, batteryBar1);
  lcd.createChar(2, batteryBar2);
  lcd.createChar(3, batteryBar3);
  lcd.createChar(4, batteryBar4);
  lcd.createChar(5, batteryFull);
  lcd.createChar(6, chargingBattery);
  
  lcd.clear();
  lcd.setCursor(4, 0);
  lcd.print("Solar Charger");
  lcd.setCursor(3, 1);
  lcd.print("With Reverse Prt");
  delay(2000);
}

void loop() {
  // Read sensors
  int adcValue = analogRead(voltageSensorPin);
  batteryVoltage = (adcValue * 3.3 / 1023.0) * 5.0; // Adjust multiplier as needed
  
  // Pin reads HIGH when charging
  // With external pull-down resistor, pin will be LOW by default
  // and HIGH when charging signal is active
  isCharging = digitalRead(chargingDetectPin) == HIGH;
  
  // Determine battery level (0-5)
  if (batteryVoltage >= 12.5) {
    batteryLevel = 5; // Full
  } else if (batteryVoltage >= 12.3) {
    batteryLevel = 4; // 80%
  } else if (batteryVoltage >= 12.1) {
    batteryLevel = 3; // 60%
  } else if (batteryVoltage >= 11.9) {
    batteryLevel = 2; // 40%
  } else if (batteryVoltage >= 11.7) {
    batteryLevel = 1; // 20%
  } else {
    batteryLevel = 0; // Empty
  }
  
  // Update display
  updateDisplay();
  
  Serial.print(batteryVoltage, 2);
  Serial.print("V | Level: ");
  Serial.print(batteryLevel);
  Serial.print(" | ");
  Serial.println(isCharging ? "CHARGING" : "DISCHARGING");
  
  delay(1000);
}

void updateDisplay() {
  lcd.clear();
  
  // Top line: Voltage
  lcd.setCursor(0, 0);
  lcd.print("Volt: ");
  lcd.print(batteryVoltage, 1);
  lcd.print("V");
  
  // Show charging indicator
  if (isCharging) {
    lcd.setCursor(12, 0);
    lcd.print("CHG");
  }
  
  // Bottom line: Battery icon and status
  lcd.setCursor(0, 1);
  
  // Select battery icon
  byte iconIndex;
  if (isCharging) {
    iconIndex = 6; // Charging battery
  } else {
    iconIndex = batteryLevel; // 0-5 based on battery level
  }
  
  // Display battery icon
  lcd.write(iconIndex);
  
  // Display status text
  lcd.setCursor(2, 1);
  
  if (isCharging) {
    lcd.print("Charging ");
    
    // Show animated dots
    static int dotCount = 0;
    lcd.setCursor(11, 1);
    for (int i = 0; i < 3; i++) {
      if (i < dotCount) {
        lcd.print(".");
      } else {
        lcd.print(" ");
      }
    }
    dotCount = (dotCount + 1) % 4;
  } else {
    // Show battery level text
    lcd.setCursor(2, 1);
    switch (batteryLevel) {
      case 5: lcd.print("FULL       "); break;
      case 4: lcd.print("GOOD       "); break;
      case 3: lcd.print("AVERAGE    "); break;
      case 2: lcd.print("LOW        "); break;
      case 1: lcd.print("VERY LOW   "); break;
      case 0: lcd.print("POOR HEALTH"); break;
    }
  }
}

Conclusion

Building a Solar Battery Voltage Monitor using NodeMCU bridges the gap between basic electronics and practical renewable energy management. By combining a robust hardware protection layer—complete with reverse polarity protection and an automatic over-voltage cutoff—with a smart microcontroller interface, you ensure your battery operates safely and efficiently.

You no longer have to wonder about the state of your charge. With a glance at the 16×2 LCD, you can see the exact voltage, the charging status, and the overall health of your battery.

This project is a perfect example of how DIY electronics can lead to a smarter, more resilient, and energy-independent lifestyle. Whether you plan to stop here or expand into full IoT-enabled solar monitoring, you’ve taken a crucial step in mastering your solar power system.

Disclaimer: Working with solar panels and 12V batteries involves electrical risks. Ensure you understand basic safety precautions and double-check your wiring before connecting power. Always fuse your connections appropriately.

Relative Projects: Embedded IoT Projects

  1. NodeMCU ESP8266 Official Documentation
    https://www.espressif.com/en/products/socs/esp8266
  2. LM317 voltage regulator Datasheet
    https://www.ti.com/product/LM317
  3. 7805 voltage regulator Datasheet
    https://www.st.com/en/power-management/l7805.html
  4. Solar Energy Learning Resource – U.S. Department of Energy
    https://www.energy.gov/eere/solar
  5. ESP8266 Arduino Core GitHub Repository
    https://github.com/esp8266/Arduino
  6. I2C communication protocol explanation
    https://www.nxp.com/docs/en/user-guide/UM10204.pdf

Article Information

Author: zealyen.it

Last Updated: March 10, 2026

This article is part of our practical learning series focused on embedded systems, STM32, Arduino, and IoT.

Leave a Reply

Your email address will not be published. Required fields are marked *