Arduino Li-Ion Battery Capacity Tester

 


In this modern and hi-tech world, we need lots of variety of power storage solutions and one of the most popular solution is battery (We all already know this) and also most popular battery is Li-Ion and Li-Po now days. For Modern world we need a battery which can provide high amps or current for long time and small in size which only possible with Li-ion Battery not Lead-Acid, Ni-Cd Battery nor Ni-MH Battery etc. But there are lots of cheap and non-branded Chinese Li-Ion Batteries available in the markets which promises more capacity but not actually yet. So in this post, I am goanna make one Arduino based Battery Capacity Tester which test the complete capacity of a battery and also can identify a faulty batteries.

So in this blog, we take a look on these steps are:-

>>Why Capacity Tester…?

>>Components Required

>>Circuit Diagram

>>Code for Arduino

Why Capacity Tester…?

Why do we use Capacity tester instead of any normal load test for Li-ion batteries …? Because Instead of any normal load test, Capacity Tester provide a complete information about your battery with safety and indications and If we use any normal test with simple load value this can be not accurate and heat up the battery which can be risky, but in this case we need to charge up the battery completely full for first time before we plug the battery on Capacity tester after we can use for different current timing test with adjusting the value of current on the tester with the push buttons.

Note: After we use any Li-Ion or Li-Po battery, First make sure you are using safe electronic because Li-Po and Li-Ion Battery is highly explosive and can be dangerous for you and also you can burn your hands, So please make sure everything you use is OK and good and if you already use these types of battery then fine or if you not know the complete information about these batteries then check first on internet or anywhere. This is only information blog post, I am not responsible for anything. Stay Safe.

Component Required

Arduino Nano x1

0’96 Inch OLED Display (SSD1306 OLED) x1

LM358 IC x1

IRFZ44 N Channel Mosfet Transistor x1

5 Ohms 5Watt Resistor x1

1M Resistor x1

470R Resistor x1

4.7K Resistor x2

100nF Capacitor x2

220uF Capacitor x1

Tactile Switch x3

18650 Battery Holder x1

Circuit Diagram



Here is the circuit diagram for the Battery Capacity Tester. In this diagram LM358 use as a OP-AMP IC which has connected with Arduino’s Digital Pin 3. Connect a Buzzer in Digital Pin 9 of Arduino and 2 pull-up switches with Arduino Digital Pin 11 and 12 for UP/Start and Down control. Analog A0 pin for battery input. After all simply connect an OLED Display to it with 5V to VCC, GND to GND, A4 to SDA and A5 to SCL pin.

Code

Now open Arduino IDE Copy the code paste into your IDE then compile and Upload. If you don’t have these libraries then first download it from here and install it into your Arduino IDE first with some few steps first go to the Sketch menu--> Include Library--> Add Zip Library now select where you put your files.

#include<JC_Button.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int Vo;
float R1 = 10000;
float logR2, R2, T;
const int Current [] = {0, 70, 100, 190, 350, 400, 500, 620, 700, 830, 910, 1000};
const int PWM_RES [] = {0, 1, 2, 4, 8, 9, 12, 15, 17, 20, 22, 24};
int l = 0;
const float Low_BAT_level = 3.4;
const byte PWM_Pin = 3;
const byte Buzzer = 9;
const int BAT_Pin = A0;
int PWM_Value = 0;
unsigned long Capacity = 0;
int ADC_Value = 0;
float Vcc = 5.04 ; // Voltage of Arduino 5V pin ( Mesured by Multimeter after connecting external 9V Supply )
float BAT_Voltage = 0;
float sample = 0;
byte Hour = 0, Minute = 0, Second = 0;
bool calc = false, Done = false;
Button UP_Button(11, 25, false, true);
Button Down_Button(12, 25, false, true);
// 'logo.jpg'
const unsigned char myBitmap [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x3f, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x7f, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x78, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x70, 0x0e, 0x07, 0x00, 0x60, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x70, 0x0e, 0x1f, 0xc1, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x78, 0x0e, 0x3c, 0xe3, 0xf8, 0xf7, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x7f, 0x8e, 0x38, 0xe3, 0x81, 0xc3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x7e, 0x0e, 0x3f, 0xe7, 0x01, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x70, 0x0e, 0x3f, 0xe7, 0x01, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x70, 0x0e, 0x38, 0x07, 0x01, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x70, 0x0e, 0x38, 0x07, 0x81, 0xc3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x7f, 0x8e, 0x3c, 0x43, 0xf9, 0xe7, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x7f, 0xc6, 0x1f, 0xe1, 0xf8, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x3f, 0x80, 0x07, 0x80, 0xf0, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0e, 0x00, 0xc0, 0x08, 0x39, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0e, 0x03, 0xf8, 0x7f, 0x3f, 0xe0, 0xfe, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0e, 0x07, 0x38, 0xff, 0x3f, 0xe1, 0xff, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0e, 0x0e, 0x1c, 0xe0, 0x38, 0xf3, 0x87, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0e, 0x0f, 0xfc, 0xe0, 0x38, 0x73, 0x83, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0e, 0x0f, 0xfc, 0xe0, 0x38, 0x73, 0x83, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0xe0, 0x38, 0x73, 0x83, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0xe0, 0x38, 0x73, 0x87, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0e, 0x07, 0x08, 0xf7, 0x38, 0x73, 0xcf, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0e, 0x07, 0xf8, 0x7f, 0x38, 0x71, 0xfe, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x04, 0x01, 0xf0, 0x1c, 0x10, 0x20, 0x78, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 1040)
void setup () {
  Serial.begin(9600);
  pinMode(PWM_Pin, OUTPUT);
  pinMode(Buzzer, OUTPUT);
  analogWrite(PWM_Pin, PWM_RES[l]);
  UP_Button.begin();
  Down_Button.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.drawBitmap(0, 0, myBitmap, 128, 64, WHITE);
  display.display();
  delay(3500);
  display.setTextColor(WHITE);
  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0, 0);
  display.print("Adjust ");
   display.setCursor(2, 15);
  display.print("Current:");
  display.setCursor(2, 40);
  display.print("UP   Down");
  display.display();
}
//************************* End of Setup function *******************************
void loop() {
  float c;
  UP_Button.read();
  Down_Button.read();
  if (UP_Button.wasReleased() && l < 11 && calc == false)
  {
    display.setTextSize(2);
    l = l + 1;
    display.clearDisplay();
    display.setCursor(2, 25);
    display.print("Curr:");
    display.print(String(Current[l]) + "mA");
    display.display();
  }
  if (Down_Button.wasReleased() && l > 0 && calc == false)
  {
    l = l - 1;
    display.clearDisplay();
    display.setCursor(2, 25);
    display.print("Curr:");
    display.print(String(Current[l]) + "mA");
    display.display();
  }
  if (UP_Button.pressedFor (1000) && calc == false)
  {
    analogWrite(PWM_Pin, PWM_RES[l]);
    digitalWrite(Buzzer, HIGH);
    delay(1500);
    digitalWrite(Buzzer, LOW);
    display.clearDisplay();
    timerInterrupt();
  }
}
//************************* End of Loop function *******************************
void timerInterrupt() {
  float c;
  calc = true;
  while (Done == false)  {
    Second ++;
    if (Second == 60)  {
      Second = 0;
      Minute ++;
    }
    if (Minute == 60)  {
      Minute = 0;
      Hour ++;
    }
    //************ Measuring Battery Voltage ***********
    for (int i = 0; i < 100; i++)
    {
      sample = sample + analogRead(BAT_Pin); //read the Battery voltage
      delay (2);
    }
    sample = sample / 100;
    BAT_Voltage = sample * (Vcc / 1024.0);
    //*********************************************
    display.clearDisplay();
    display.setTextSize(2);
    display.setCursor(20, 5);
    display.print(String(Hour) + ":" + String(Minute) + ":" + String(Second));
    display.setTextSize(1);
    display.setCursor(0, 25);
    display.print("Disch Curr: ");
    display.print(String(Current[l]) + "mA");
    display.setCursor(2, 40);
    display.print("Bat:" + String(BAT_Voltage) + "V" );
    display.setCursor(63, 40);

    Capacity =  (Hour * 3600) + (Minute * 60) + Second;
    Capacity = (Capacity * Current[l]) / 3600;
    display.setCursor(2, 55);
    display.print("Capacity:" + String(Capacity) + "mAh");
    display.display();
    if (BAT_Voltage < Low_BAT_level)
    {
      Capacity =  (Hour * 3600) + (Minute * 60) + Second;
      Capacity = (Capacity * Current[l]) / 3600;
      display.clearDisplay();
      display.setTextSize(2);
      display.setCursor(2, 15);
      display.print("Capacity:");
      display.setCursor(2, 40);
      display.print(String(Capacity) + "mAh");
      display.display();
      Done = true;
      l = 0;
      analogWrite(PWM_Pin, PWM_RES[l]);
      digitalWrite(Buzzer, HIGH);
      delay(100);
      digitalWrite(Buzzer, LOW);
      delay(100);
      digitalWrite(Buzzer, HIGH);
      delay(100);
      digitalWrite(Buzzer, LOW);
      delay(100);
    }
    delay(1000);
  }
}

After all must check everything has connected properly to the board or not short any wire with each other because Li-Ion Battery can burn your Arduino or other components then you can use this.


Comments