Build a complete battery monitoring system for your off-grid solar setup! This Arduino-based project measures battery voltage, load current, and temperature in real-time, displaying data on an LCD while automatically protecting your batteries from deep discharge and overheating. Perfect for renewable energy enthusiasts and off-grid living.
This project demonstrates how to design and build a beginner-friendly system to monitor and protect an off-grid solar battery bank using Arduino. It is intended for students, hobbyists, and educators starting with renewable energy projects.
The system uses sensors connected to an Arduino microcontroller. Battery voltage is measured using a voltage divider module, current is measured using a Hall-effect sensor, and temperature is measured using a digital temperature sensor. A relay automatically disconnects the load when unsafe conditions are detected.
Ensure all connections are secure and fused. Use this guide to wire the sensors to your Arduino:
| Peripheral | Device Pin | Arduino Pin | Notes |
|---|---|---|---|
| Voltage Sensor | S (Signal) | Analog A0 | 0-25V Range |
| Current Sensor | OUT | Analog A1 | ACS712 Output |
| Temp Sensor | DQ (Data) | Digital 2 | DS18B20 Data |
| Relay Module | IN / SIG | Digital 7 | Load Control |
| LCD Display | SDA | Analog A4 | I2C Data |
| LCD Display | SCL | Analog A5 | I2C Clock |
The system architecture connects all sensors to the Arduino, which processes the data and controls the relay based on protection logic.
Battery Bank → Voltage Sensor → Arduino → LCD Display
Battery Bank → Current Sensor → Arduino → Relay Control
Battery Bank → Temperature Sensor → Arduino → Protection Logic
The system implements automatic protection to safeguard your battery bank from damage:
Low Voltage Cut-Off: Disconnect load when battery drops below 11.5V
Recovery Voltage: Reconnect load when battery rises above 12.0V
Over-Temperature Cut-Off: Disconnect load when temperature exceeds 50°C
Always use an inline fuse between the battery and your circuit. Disconnect power before making any wiring changes. Test with low-power loads first before connecting to your main system.
Open Arduino IDE and install the following libraries via Library Manager: LiquidCrystal_I2C for the LCD display, OneWire and DallasTemperature for the DS18B20 sensor.
Connect the 0-25V voltage sensor module to your battery terminals. The module uses a resistor divider (30kΩ / 7.5kΩ) to scale 0-25V down to 0-5V for Arduino's analog input. Connect the signal pin to A0.
Place the ACS712 current sensor in series with your load. This Hall-effect sensor measures current without passing it through the Arduino. Connect the output to A1.
Attach the DS18B20 temperature sensor directly to your battery surface using thermal tape. Connect its data pin to digital pin 2 with a 4.7kΩ pull-up resistor.
Wire the I2C LCD to A4 (SDA) and A5 (SCL). Connect the relay module control pin to digital pin 7. The relay will control load power based on protection logic.
Upload the code below, then compare voltage readings with a multimeter. Adjust the calibration factor if needed. Test protection by simulating low voltage conditions.
// Off-Grid Solar Battery Monitor // MakersDeck Arduino Project #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <OneWire.h> #include <DallasTemperature.h> // Pin definitions #define VOLTAGE_PIN A0 #define CURRENT_PIN A1 #define TEMP_PIN 2 #define RELAY_PIN 7 // Protection thresholds #define LOW_VOLTAGE_CUTOFF 11.5 #define RECOVERY_VOLTAGE 12.0 #define MAX_TEMP 50.0 // Initialize components LiquidCrystal_I2C lcd(0x27, 16, 2); OneWire oneWire(TEMP_PIN); DallasTemperature sensors(&oneWire); bool loadEnabled = true; void setup() { Serial.begin(9600); lcd.init(); lcd.backlight(); sensors.begin(); pinMode(RELAY_PIN, OUTPUT); digitalWrite(RELAY_PIN, HIGH); lcd.setCursor(0, 0); lcd.print("Solar Monitor"); lcd.setCursor(0, 1); lcd.print("Initializing..."); delay(2000); } void loop() { // Read voltage (0-25V sensor) int voltageRaw = analogRead(VOLTAGE_PIN); float voltage = voltageRaw * (25.0 / 1023.0); // Read current (ACS712 20A) int currentRaw = analogRead(CURRENT_PIN); float current = (currentRaw - 512) * (20.0 / 512.0); // Read temperature sensors.requestTemperatures(); float temp = sensors.getTempCByIndex(0); // Calculate power float power = voltage * abs(current); // Protection logic String status = "NORMAL"; if (temp > MAX_TEMP) { loadEnabled = false; status = "OVER TEMP!"; } else if (voltage < LOW_VOLTAGE_CUTOFF) { loadEnabled = false; status = "LOW BATT!"; } else if (voltage > RECOVERY_VOLTAGE && temp < MAX_TEMP) { loadEnabled = true; status = "NORMAL"; } // Control relay digitalWrite(RELAY_PIN, loadEnabled ? HIGH : LOW); // Update LCD lcd.clear(); lcd.setCursor(0, 0); lcd.print(voltage, 1); lcd.print("V "); lcd.print(current, 1); lcd.print("A "); lcd.print(temp, 0); lcd.print("C"); lcd.setCursor(0, 1); lcd.print(status); delay(1000); }
Once you've mastered this basic system, consider these upgrades: