Arduino True Battery Capacity Tester (Li-Ion/NiMH/NiCD/Pb)
Intro: Arduino True Battery Capacity Tester (Li-Ion/NiMH/NiCD/Pb)
If anyone saw my last instructable "Simple Li-Ion Battery Power Tester" they can now upgrade to a computerized hi-tech version that is capable of measuring almost any type of rechargeable or none rechargeable batteries (but it will drain one charge from them in the process).
It can even connect to a PC and give you a full "Data-sheet" graph of the discharge and total capacity.
Note that this is my first Arduino project (I am not counting my "blink LED").
It can even connect to a PC and give you a full "Data-sheet" graph of the discharge and total capacity.
Note that this is my first Arduino project (I am not counting my "blink LED").
STEP 1: This Is What You Can Get at the End...(just to Get You Interested)
This is the graph you can get from the text file sent to the PC during drain cycle.
STEP 2: Lets Start at the Begining - Arduino
I really wanted to get this Diecimila copy Arduino board bit it took me ~2 weeks to get it by mail so I just had to start fast with my own bread-board Arduino so I purchased an ATMEGA168 and thought I could get it running without any more components .. to my suprize it didn't work and I just had to get another shipment with a 16Mhz crystal and two 22pf caps .. then I got the next ...
STEP 3: Bread Board Arduino
I basically took junk apart and added the components one by one ...
most of the information can be found in the Arduino web page :
http://arduino.cc/en/Main/ArduinoBoardDiecimila
They realy have everything you need .
It took me about a week to get it up and running (bootloader / building an ISP cable and an RS232 cable ...) - you can read all about this in the site above .
most of the information can be found in the Arduino web page :
http://arduino.cc/en/Main/ArduinoBoardDiecimila
They realy have everything you need .
It took me about a week to get it up and running (bootloader / building an ISP cable and an RS232 cable ...) - you can read all about this in the site above .
STEP 4: FET With 2.2Ohm Load
it was fairly simple to add a FET with "on" resistance of ~8mOHM (no barly any power disipation on it) and a 2.2 10W resistor .
I connected two A/D pins from the Arduino to the resistor poles and subtracted the values to get the exact volatge drop on the resistor .
Now I samples them every second and acumulated the current (I=DeltaV/R).
I also added a buzzer to indicate when charging was over and stoped the discharge .
I connected two A/D pins from the Arduino to the resistor poles and subtracted the values to get the exact volatge drop on the resistor .
Now I samples them every second and acumulated the current (I=DeltaV/R).
I also added a buzzer to indicate when charging was over and stoped the discharge .
STEP 5: The SW
So I also connected and LCD (which I took apart from some other junk) and found the data-sheet on the net + a cool driver from the Arduino web page and started coding .
Auto detecting battery type by the voltage .
Auto detecting battery type by the voltage .
STEP 6: Auto Detect Battery Tyoe
It will detect if it is NiMH/NiCD or Li-ION by the voltage range .
And then start the discharge cycle.
And then start the discharge cycle.
STEP 7: Discharging...
The discharge can take anywhere from 30-120 minuets depending on batery capacity but at the end you get a true indication of battery capacity / quality .
Do you want to use that battery for your air-plain receiver or not ?
This is the diagram of the discharge circuit...
Do you want to use that battery for your air-plain receiver or not ?
This is the diagram of the discharge circuit...
STEP 8: Discharge Circuit
very simple with the 2 A/D connected on the two sides of the resistor /
Vr=Vbat-Vfet.
Vr=Vbat-Vfet.
STEP 9: My SW (free for Anyone to Use)
// include the library code:
#include
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);// initialize the library with the numbers of the interface pins
int sensorPin = 0; // select the input pin for the potentiometer (pin 23)
int sensor2Pin = 2; // select the input pin for the potentiometer (pin 23)
int ledPin = 13; // select the pin for the LED
int SPKPin = 6;
int sensorValue = 0; // variable to store the value coming from the sensor
int sensor2Value = 0; // variable to store the value coming from the sensor
float LiMinThreshold = 2700; // Lithium Minimal Voltage for load removal
float LiMaxThreshold = 4200; // Lithium Max Voltage for load removal
float NmhMinThreshold = 950; // NMH Minimal Voltage for load removal
float NmhMaxThreshold = 1600; // NMH Max Voltage for load removal
float SelectedMinThreshold = 5000;
int i;
int BatVoltage = 5000;
int FetVoltage = 5000;
long TotalCurrent = 0;
boolean done = false;
unsigned long PrevMillis ;
unsigned long MillisPassed ;
void CL2(){
lcd.setCursor(0, 1);// Second line first char
lcd.print(" ");
lcd.setCursor(0, 1);// Second line first char
}
void setup() {
Serial.begin(9600);// start serial port to send data during run to the PC
pinMode(ledPin, OUTPUT);//activation led and enable for FET
pinMode(SPKPin, OUTPUT);//activation led and enable for FET
lcd.begin(24, 2);// set up the LCD's number of rows and columns:
lcd.print("Bat PWR Tester[Active]"); // Print a message to the LCD.
lcd.setCursor(0, 1);// Second line first char
lcd.print("Detecting Bat Type..."); // print voltage value
delay(2000);
lcd.setCursor(0, 1);// Second line first char
lcd.print(" ");
lcd.setCursor(0, 1);// Second line first char
digitalWrite(ledPin, HIGH); // set the LED on
sensorValue = analogRead(sensorPin); // read the value from the sensor:
digitalWrite(ledPin, LOW); // set the LED off
// Detecting battery type
BatVoltage = sensorValue*4.887;
if (BatVoltage > 4500){
lcd.print("Warning high-V! ");
done = true;}
else if (BatVoltage > LiMinThreshold){
lcd.print("Type:Li-Ion Bat ");
SelectedMinThreshold = LiMinThreshold;}
else if (BatVoltage > NmhMinThreshold){
lcd.print("Type:NiMH/Cd Bat ");
SelectedMinThreshold = NmhMinThreshold;}
else{
lcd.print("Unknown Bat V<1 ");
done = true;}
lcd.print("V=");
lcd.print(sensorValue*4.887); // print voltage value
Serial.print("DT[ms]");
Serial.print("\t");
Serial.print("Bat[mV]");
Serial.print("\t");
Serial.print("Fet[mV]");
Serial.println("");
delay(3000);
CL2();
PrevMillis = millis();
}
void loop() {
if (BatVoltage > SelectedMinThreshold && !done) {
digitalWrite(ledPin, HIGH); // set the LED on
sensorValue = analogRead(sensorPin); // read the value from the sensor:
sensor2Value = analogRead(sensor2Pin); // read the value from the FET:
FetVoltage = (sensor2Value*4.887);
BatVoltage = (sensorValue*4.887);
CL2();
lcd.print("V=");
lcd.print(BatVoltage); // print voltage value
lcd.print("mV");
//lcd.print(FetVoltage); // print voltage value
TotalCurrent=TotalCurrent+MillisPassed/1000*(BatVoltage-FetVoltage)/2.2/3.6;
lcd.print(" I=");
lcd.print(TotalCurrent/1000);
lcd.print("mAH ");
delay(1000);
MillisPassed = millis()- PrevMillis;
PrevMillis = millis();
Serial.print(int(MillisPassed));
Serial.print("\t"); // prints a tab
Serial.print(BatVoltage);
Serial.print("\t"); // prints a tab
Serial.print(FetVoltage);
Serial.println(""); // prints a tab
CL2();
}
else
{
done=true;
digitalWrite(ledPin, LOW); // set the LED off - stop loading
lcd.setCursor(0, 0);// First line first char
lcd.print("Bat Power Tester [DONE] "); // Print a message to the LCD.
CL2();//clear line 2
sensorValue = analogRead(sensorPin); // read the value from the sensor:
BatVoltage = (sensorValue*4.887);
lcd.setCursor(0, 1);// Second line first char
lcd.print("V=");
lcd.print(BatVoltage); // print voltage value
lcd.print("mV I=");
lcd.print(TotalCurrent/1000);
lcd.print("mAH ");
for (int i=0; i<100 ; i++){
digitalWrite(SPKPin, HIGH);
delay(1);
digitalWrite(SPKPin, LOW);
delay(1);
}
delay(1000);
}
}
#include
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);// initialize the library with the numbers of the interface pins
int sensorPin = 0; // select the input pin for the potentiometer (pin 23)
int sensor2Pin = 2; // select the input pin for the potentiometer (pin 23)
int ledPin = 13; // select the pin for the LED
int SPKPin = 6;
int sensorValue = 0; // variable to store the value coming from the sensor
int sensor2Value = 0; // variable to store the value coming from the sensor
float LiMinThreshold = 2700; // Lithium Minimal Voltage for load removal
float LiMaxThreshold = 4200; // Lithium Max Voltage for load removal
float NmhMinThreshold = 950; // NMH Minimal Voltage for load removal
float NmhMaxThreshold = 1600; // NMH Max Voltage for load removal
float SelectedMinThreshold = 5000;
int i;
int BatVoltage = 5000;
int FetVoltage = 5000;
long TotalCurrent = 0;
boolean done = false;
unsigned long PrevMillis ;
unsigned long MillisPassed ;
void CL2(){
lcd.setCursor(0, 1);// Second line first char
lcd.print(" ");
lcd.setCursor(0, 1);// Second line first char
}
void setup() {
Serial.begin(9600);// start serial port to send data during run to the PC
pinMode(ledPin, OUTPUT);//activation led and enable for FET
pinMode(SPKPin, OUTPUT);//activation led and enable for FET
lcd.begin(24, 2);// set up the LCD's number of rows and columns:
lcd.print("Bat PWR Tester[Active]"); // Print a message to the LCD.
lcd.setCursor(0, 1);// Second line first char
lcd.print("Detecting Bat Type..."); // print voltage value
delay(2000);
lcd.setCursor(0, 1);// Second line first char
lcd.print(" ");
lcd.setCursor(0, 1);// Second line first char
digitalWrite(ledPin, HIGH); // set the LED on
sensorValue = analogRead(sensorPin); // read the value from the sensor:
digitalWrite(ledPin, LOW); // set the LED off
// Detecting battery type
BatVoltage = sensorValue*4.887;
if (BatVoltage > 4500){
lcd.print("Warning high-V! ");
done = true;}
else if (BatVoltage > LiMinThreshold){
lcd.print("Type:Li-Ion Bat ");
SelectedMinThreshold = LiMinThreshold;}
else if (BatVoltage > NmhMinThreshold){
lcd.print("Type:NiMH/Cd Bat ");
SelectedMinThreshold = NmhMinThreshold;}
else{
lcd.print("Unknown Bat V<1 ");
done = true;}
lcd.print("V=");
lcd.print(sensorValue*4.887); // print voltage value
Serial.print("DT[ms]");
Serial.print("\t");
Serial.print("Bat[mV]");
Serial.print("\t");
Serial.print("Fet[mV]");
Serial.println("");
delay(3000);
CL2();
PrevMillis = millis();
}
void loop() {
if (BatVoltage > SelectedMinThreshold && !done) {
digitalWrite(ledPin, HIGH); // set the LED on
sensorValue = analogRead(sensorPin); // read the value from the sensor:
sensor2Value = analogRead(sensor2Pin); // read the value from the FET:
FetVoltage = (sensor2Value*4.887);
BatVoltage = (sensorValue*4.887);
CL2();
lcd.print("V=");
lcd.print(BatVoltage); // print voltage value
lcd.print("mV");
//lcd.print(FetVoltage); // print voltage value
TotalCurrent=TotalCurrent+MillisPassed/1000*(BatVoltage-FetVoltage)/2.2/3.6;
lcd.print(" I=");
lcd.print(TotalCurrent/1000);
lcd.print("mAH ");
delay(1000);
MillisPassed = millis()- PrevMillis;
PrevMillis = millis();
Serial.print(int(MillisPassed));
Serial.print("\t"); // prints a tab
Serial.print(BatVoltage);
Serial.print("\t"); // prints a tab
Serial.print(FetVoltage);
Serial.println(""); // prints a tab
CL2();
}
else
{
done=true;
digitalWrite(ledPin, LOW); // set the LED off - stop loading
lcd.setCursor(0, 0);// First line first char
lcd.print("Bat Power Tester [DONE] "); // Print a message to the LCD.
CL2();//clear line 2
sensorValue = analogRead(sensorPin); // read the value from the sensor:
BatVoltage = (sensorValue*4.887);
lcd.setCursor(0, 1);// Second line first char
lcd.print("V=");
lcd.print(BatVoltage); // print voltage value
lcd.print("mV I=");
lcd.print(TotalCurrent/1000);
lcd.print("mAH ");
for (int i=0; i<100 ; i++){
digitalWrite(SPKPin, HIGH);
delay(1);
digitalWrite(SPKPin, LOW);
delay(1);
}
delay(1000);
}
}
STEP 10: The Schematics ...
All the schematics for arduino can be found on the Arduino web page (step 2).
you can Also find how to connect standard LCDs on the same site so no need to copy it all here.
you can Also find how to connect standard LCDs on the same site so no need to copy it all here.
STEP 11: Please Support My Work by Voting for Me !
All and all prototype Breadboard and then moving it to a box and soldering it all together took me two weeks (night work 3-4 hours a day)
Thanks you for reading and feel free contacting me with any questions / remarks .
I am now an Arduino expert (naa I am not - 2 weeks XP )
But I have many new project I would like to do .
Thanks you for reading and feel free contacting me with any questions / remarks .
I am now an Arduino expert (naa I am not - 2 weeks XP )
But I have many new project I would like to do .
85 Comments
pistib 3 years ago
KDMcMullan 6 years ago
I suspect the method is flawed. You're sampling the voltage at each end of the load resistor: FET drain end and also battery end. You say you use the difference to calculate the V drop across the load. I accept that this is correctly going to give you the V drop across the load, but I don't think that's the information you need. I suspect you really need the total V drop across the load and the FET all the way down to ground. The ground is, of course, 0V. So the Vdrop needs only to be measured at the cell itself. I don't see the need for the voltage measurement at the FET drain at all.
PeterK63 7 years ago
int sensorPin = 0; // select the input pin for the potentiometer (pin 23)
int sensor2Pin = 2; // select the input pin for the potentiometer (pin 23)
And what those potentiometers do, connected to the same pin 23 ? Precisions, precisons...
picposter 7 years ago
Your Code is not Working properly and there are no shematics. Could be a bit more precise.
oldskoolhead 8 years ago
some battery chargers have a test function
nohopehere 8 years ago
The "vote for me" LED did not seem to work. :-/
GaryH34 8 years ago
Any idea how much the project would cost if you had to buy all of the components?
Also, do you have a picture showing batteries hooked up to your board (just wondering how you physically connect many cells.
How many parrallel cells does it handle?
moris_zen 8 years ago
Sorry I dont .
Only one every time .. or you can connect in parallel if they have same voltage but then you dont know capacity of each ...
Menneset 8 years ago
The contest is over, but I would have voted for you just because of the LED comment. :)
CarlosV46 8 years ago
Hi. what kind of resistor is used (2.2 ohms) Watts, tolerance %, (maybe a shunt resistor)?
Thanks in advance.
moris_zen 8 years ago
AlexYan 8 years ago
Hi, can your capacity-meter test multiple cells simultaneously? I mean I max b6 allows to measure capacity and it is just ~30 $. The downside is that it tests one cell at a time. I have a few hundred cells to test so looking for a way (multy-cell testing device) to speed up the process. Can you give any suggestions?
moris_zen 8 years ago
I have a similar problem .. many cells to check which I would like to do in parallel .
Is this for personal use or business? is this something you would like me to develop / join develop?
AlexYan 8 years ago
bart.szester 9 years ago
moris_zen 8 years ago
moris_zen 9 years ago
That must be a huge e-cig :-)
If you like you can ship some over and I can test for you .
richard.kost.50 9 years ago
WhiteD1 8 years ago
Hi, i would like to make this. any update? also, is it possible to use IRFZ44N mosfet in this circuit? (VDSS = 55V
RDS(on) = 17.5mΩ
ID = 49A)
and someone please give a clear schematic of this... though i saw a ppt schematic, but not clear about the discharger part of that.
mjanich 8 years ago
This is a good project. Could you add charging now? I propose a LM150/350 for a constant voltage (digitally selectable) for charging LiIon type batteries. Remember they have to be charged with constant voltage (4.2V)/Constant current methodology and switch off at 3% (of what? forgotten), no leak charge. Details on how you charge are here: http://batteryuniversity.com/