🔋 Battery Advanced ⏱️ 8-10 Hours

Battery Management System (BMS)

Lithium batteries are high-performance but fragile. This DIY BMS project walks you through building a cell-level monitoring and balancing system. You'll learn to monitor individual cell voltages (in a 3S or 4S pack) and activate balancing resistors to prevent overcharging.

💰
$20 - $30
📊
Advanced
🧩
8 Parts
📝
Jan 2026

📖 Project Overview

A BMS serves three primary functions: Protection (disconnecting if a cell is too high/low), Monitoring (reporting state of charge), and Balancing (ensuring all cells stay at the same voltage). This project implements all three for a 3S (11.1V/12.6V) Lithium-Ion pack.

⚖️ Passive Balancing

The code detects if Cell A is higher than Cell B. If the difference exceeds 50mV, it activates a transistor that bleeds energy from the higher cell through a power resistor until they are equalized.

🧰 Components Required

Part Name Qty
Arduino Nano 1
ADS1115 16-bit High Res ADC 1
2N2222 NPN Transistors 3
10Ω 2W Shunt Resistors 3
10kΩ Voltage Dividers 3
5V Opto-isolated Relay 1
3S Lithium-Ion Pack (Test Pack) 1

🔌 Hardware Connections

Measuring multiple cells in series requires careful common-ground consideration. We use an external 16-bit ADC (ADS1115) for high precision.

🔍 Pin Mapping Guide

Peripheral Device Pin Arduino Pin Notes
ADS1115 ADC SDA / SCL A4 / A5 I2C Data Bus
Cell 1 Balancer Base Digital 3 Triggers Shunt 1
Cell 2 Balancer Base Digital 4 Triggers Shunt 2
Cell 3 Balancer Base Digital 5 Triggers Shunt 3
Master Relay IN Digital 7 Pack Cut-off

⚠️ Lithium Handling Safety

Lithium cells can catch fire if shorted or overcharged. Always perform initial testing with a power-limited supply, keep a sand bucket or fire extinguisher nearby, and never leave your DIY BMS unattended during the first few charge cycles.

💻 BMS Control Code

Arduino C++
#include <Adafruit_ADS1X15.h>

Adafruit_ADS1115 ads;
float cell1, cell2, cell3;

void setup() {
  ads.begin();
  pinMode(3, OUTPUT); // Balancer 1
  pinMode(4, OUTPUT); // Balancer 2
  pinMode(5, OUTPUT); // Balancer 3
  pinMode(7, OUTPUT); // Main Cut-off
  digitalWrite(7, HIGH); // Enable Load
}

void loop() {
  cell1 = ads.readADC_SingleEnded(0) * 0.1875 / 1000.0 * 2.0; 
  cell2 = (ads.readADC_SingleEnded(1) * 0.1875 / 1000.0 * 3.0) - cell1;
  cell3 = (ads.readADC_SingleEnded(2) * 0.1875 / 1000.0 * 4.0) - (cell1 + cell2);

  // Safety Cut-off
  if (cell1 < 3.0 || cell2 < 3.0 || cell3 < 3.0) digitalWrite(7, LOW);
  if (cell1 > 4.25 || cell2 > 4.25 || cell3 > 4.25) digitalWrite(7, LOW);

  // Simple Passive Balancing
  if (cell1 > cell2 + 0.05) digitalWrite(3, HIGH); else digitalWrite(3, LOW);
  if (cell2 > cell3 + 0.05) digitalWrite(4, HIGH); else digitalWrite(4, LOW);
  
  delay(1000);
}
← Back to All Projects