Arduino Battery Health Monitor DIY

Hello makers in this article i will show you how you can make arduino battery health monitor at your desk.
Being a hobbyist creator requires a lot of creativity and also lots of battery power!
Yes yes you heard it right the battery that powers your inventions, But have you ever thought to check on them?
Even batteries loose their backup time and we can call it as health and it is necessary to check that before you use them in any important project.
In this post i will make a battery health monitor and give all the necessary build steps to make them on your own.
Design of frame for battery health arduino monitor
I will be 3d printing the frame for this device and you can see the design that i will be making in the below visual.

There are only 2 parts that we will be requiring to make this monitoring device and you can use my design to 3d print this.
Design is simple and you can install all the components inside this.
After you have this design simply 3d print the parts and now you have the parts ready.
3D printing wont take any long time, and also there is no need to post process the parts after printing.
Circuit for Arduino Battery Health Monitor

Arduino Code for Battery Health Monitor
#include <Wire.h>
#include <Adafruit_INA219.h>
#include <Adafruit_NeoPixel.h>
#include <Adafruit_SSD1306.h>
#define LED_PIN 6
#define NUM_LEDS 8
Adafruit_INA219 ina219;
Adafruit_NeoPixel ring(NUM_LEDS, LED_PIN, NEO_RGB + NEO_KHZ800);
Adafruit_SSD1306 display(128, 64, &Wire);
float voltageFiltered = 0;
float alpha = 0.1;
bool systemReady = false;
int stableCount = 0;
int lastLevel = -1;
// -------- RAINBOW ANIMATION --------
void rainbowCycle(int wait) {
for(long j = 0; j < 256; j++) {
for(int i = 0; i < NUM_LEDS; i++) {
ring.setPixelColor(i, ring.gamma32(ring.ColorHSV((i * 65536 / NUM_LEDS) + j * 256)));
}
ring.show();
delay(wait);
}
}
// -------- SETUP --------
void setup() {
Wire.begin();
ina219.begin();
ring.begin();
ring.setBrightness(12);
ring.show();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.setTextColor(SSD1306_WHITE);
// -------- WELCOME --------
display.clearDisplay();
display.setTextSize(2);
display.setCursor(10, 10);
display.println("WELCOME");
display.display();
rainbowCycle(10);
display.clearDisplay();
display.setTextSize(1.5);
display.setCursor(10, 25);
display.println("Battery Checker");
display.display();
delay(1500);
// -------- BOOT --------
display.clearDisplay();
display.setCursor(20, 25);
display.println("BOOTING...");
display.display();
rainbowCycle(5);
// -------- INITIALIZING --------
display.clearDisplay();
display.setCursor(10, 25);
display.println("INITIALIZING...");
display.display();
// soft blue glow
for(int i=0;i<NUM_LEDS;i++) {
ring.setPixelColor(i, ring.Color(0,0,40));
}
ring.show();
delay(1500);
}
// -------- LOOP --------
void loop() {
float busV = ina219.getBusVoltage_V();
float shuntV = ina219.getShuntVoltage_mV() / 1000.0;
float loadV = busV + shuntV;
// Validate readings
if(loadV > 2.5 && loadV < 5.5) {
voltageFiltered = (alpha * loadV) + ((1 - alpha) * voltageFiltered);
if(abs(loadV - voltageFiltered) < 0.05) {
stableCount++;
} else {
stableCount = 0;
}
}
// -------- WAIT FOR LOAD --------
if(stableCount < 10) {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(10, 25);
display.println("CONNECT LOAD...");
display.display();
// breathing LED
static int b = 5;
static int dir = 1;
b += dir;
if(b > 25 || b < 5) dir = -dir;
for(int i=0;i<NUM_LEDS;i++) {
ring.setPixelColor(i, ring.Color(0,0,b));
}
ring.show();
delay(100);
return;
}
// -------- FINAL MODE --------
float v = voltageFiltered;
display.clearDisplay();
display.setTextSize(2);
display.setCursor(10, 0);
display.print(v, 2);
display.print("V");
display.setTextSize(1);
display.setCursor(0, 40);
uint32_t color;
if(v > 3.7) {
display.print("Battery: GOOD");
color = ring.Color(0,150,0);
}
else if(v > 3.4) {
display.print("Battery: OK");
color = ring.Color(150,80,0);
}
else {
display.print("Battery: LOW");
color = ring.Color(150,0,0);
}
display.display();
int level = map(v * 100, 330, 420, 1, NUM_LEDS);
level = constrain(level, 1, NUM_LEDS);
if(level != lastLevel) {
for(int i=0;i<NUM_LEDS;i++) {
if(i < level) ring.setPixelColor(i, color);
else ring.setPixelColor(i, ring.Color(0,0,5));
}
ring.show();
lastLevel = level;
}
delay(200);
}
This is the circuit that i made following the circuit diagram and you can expect the same too

This is the final assembly which you will be making and now after you cross check if everything is working fine close the 2 parts.
Before joining these two parts make sure if the circuit is working and no loose connection in wires.
To join these 2 parts use the super glue.
If you want to make this device more smaller you can use PCB and i would suggest JLCPCB

They have fast shipping with more affordable options, and now they have JLCONE which makes everything pretty much easier.
JLCONE is a application that is available for both desktop and mobile and you can manage your orders and other services in a single platform.

now assembly




