A short while ago there was a discussion about building lithium battery packs
out of old 18650 cells found in laptop battery packs. I too have a collection
of these and have used them for LED flashlights. It is generally easy to find
the bad pair of of batteries in the packs that caused them to be discarded. But,
just how good are the other ones in the pack. This seemed like a nice little
demonstrator project for a UNO. This shows how you can program a UNO to solve a
momentary problem adding a few extra parts and then it can be taken apart and
used for another project. It reads out in amp minutes and will overload the
counter at a little over 5AH. It also has an analog voltage output that can be
read by a digital meter once filtered. The range is 0-5V corresponding to 0 to
255 amp minutes. The counter will overload before that time (300 A min), still
more than sufficient for testing a pair of 18650 batteries. Never parallel more
than two batteries together without fusing for each pair.There is an easy fix for
this and a chance to improve your skills. You won't learn if I just hand working
programs to you. This does work sufficiently well as it is to be quite useful.
The voltage and resistance is known. From that the amps could be calculated each
minute and added together. Rough estimates are more than adequate to evaluate a
battery. There can easily be a 10% difference charging the battery with the same
charger.
When first powered, a HELP screen appears in the compilers TOOLS section on the
serial screen. It is calibrated for 1A standard test when "S" is entered. Currents
are based on 3.7V with a 2.5 ohm resistor (two 5ohm 10W resistors in parallel). You
can change resistances for whatever you have. Currents can be adjusted on the screen
to whatever is desired by choosing set values and incrementing or decrementing from
them. A timer gives the elapsed time of the test. It doesn't start till a PWM
load value is entered. The current is calculated by MAX CURRENT * PWM / 255.
When battery voltage drops below a set value the test is ended and DONE appears on
the screen. The last elapsed time, Amp Minute and current are saved. R is entered
on the screen to reset the program. Then select a current Any preference for another
current can be added to the program. Just select a convenient keyboard character and
edit the program to include that. Remember, you must type that character in the
upper box and then click SEND.
If there are questions, please ask. Not going to write elaborate explanations for
a program that isn't used. This is probably the most useful program for the majority
of people here.
/*
LIPO_BAT_TEST program for testing AH capacity of battery
1. select various PWM for current draw
2. Read battery voltage & stop at minimum
CREATED 12/10/2016
REVISED 12/12/2016
*/
// Declare variables as integers and set initial values
int AI0 = 0; // Battery raw A/D conversion
int AI1 = 0; // spare
int kbd = 'h'; // start with help screen
int blinktime = 0; // blink counter
int PWMdrv = 0; // PWM drive
int LASTpwm = 0; // final PWM drive
int battery = 0;
int END = 3600;
int TOTAL = 0;
int AMPmin = 0;
int DONE = 0;
int seconds = 0;
int minutes = 0;
int oneamp = 175; // PWM for one amp
void setup() {
// initialize the digital pins
// Pin 13 has LED on Arduino UNO board
pinMode(13, OUTPUT); // board LED
Serial.begin (9600); // Set up serial monitor routine
}
void loop() { // This is the start of the program
// This section reads the analog signals. Range is 0 to 5V DC or 0 to 1023 counts or 4.9mV per count
AI0 = analogRead (0); // Anolog In. Read the battery voltage PIN #A0 BATTERY
AI1 = analogRead (1); // Anolog In. PIN #A1 36V PANEL
battery = battery - battery/ 6; // subtract one average reading
battery = battery + AI0; // add in a new reading
AMPmin = minutes * (PWMdrv *100/ oneamp) / 100; // calculate amp minutes
if (battery <= END && PWMdrv > 0 && seconds > 10) // check battery if A/D stable > 1 minute
{ // and drive is on
TOTAL = AMPmin; // end amp minute
DONE = 1; // end of test
LASTpwm = PWMdrv; // end PWM drive
PWMdrv = 0; // turn off load
}
// This section sends out serial data contained in the program. It has no actual functional use in the program. It can be viewed by
// sing SERIAL MONITOR in TOOLS when the ARDUINO programmer is running. The program can run without any serial monitor connected.
// Some diagnostic sectin like this should be included in all programs. It will save a lot of time in the development of programs.
if (Serial.available() > 0) kbd = Serial.read(); // look for and get keyboard character
// kbd is the character returned from keyboard
// COMMAND FOR PWM TEST
if (kbd == '0') PWMdrv = 0; // OFF
if (kbd == '1') PWMdrv = 10;
if (kbd == '2') PWMdrv = 20;
if (kbd == '3') PWMdrv = 30;
if (kbd == '4') PWMdrv = 40;
if (kbd == '5') PWMdrv = 50;
if (kbd == '6') PWMdrv = 60;
if (kbd == '7') PWMdrv = 70;
if (kbd == '8') PWMdrv = 80;
if (kbd == '9') PWMdrv = 90;
if (kbd == '-') PWMdrv = PWMdrv - 1;
if (kbd == '+') PWMdrv = PWMdrv + 1;
if (kbd == 'm' || kbd == 'M') PWMdrv = PWMdrv + 100;
if (kbd == 'i' || kbd == 'I') PWMdrv = PWMdrv + 10;
if (kbd == 'd' || kbd == 'D') PWMdrv = PWMdrv - 10;
if (kbd == 'f' || kbd == 'F') PWMdrv = 255;
if (kbd == 's' || kbd == 'S') PWMdrv = oneamp; // Standard 1A test @2.5 ohm
if (kbd == 'r' || kbd == 'R') // RESET everything
{
PWMdrv = 0;
seconds = 0;
minutes = 0;
TOTAL = 0;
DONE = 0;
}
kbd == 'z'; // reset keyboard to non used character each loop
// HELP SCREEN
if (kbd == 'H' || kbd == 'h') // if H send out HELP screen
{
Serial.println(" ");
Serial.println(" ");
Serial.println(" 0 OFF "); // load OFF
Serial.println(" 1-9 10 to 90 "); // preset PWM
Serial.println(" + increment by one ");
Serial.println(" - decrement by one ");
Serial.println(" I increment by ten ");
Serial.println(" D decrement by ten ");
Serial.println(" M increment by 100 ");
Serial.println(" F 255 ON "); // max load
Serial.println(" S STANDARD 1A TEST ");
Serial.println(" R RESET TEST ");
Serial.println(" ");
Serial.println(" ");
delay (5000); // keep screen for five seconds
kbd = 'z';
}
if (PWMdrv >255) PWMdrv = 255; // set upper limit of PWM
if (PWMdrv < 0) PWMdrv = 0; // set lower limit of PWM
// BLINK BOARD LED and COUNT TIME
// This section blinks the board LED when the micro is working.
// seuenced using a count routine.
blinktime = blinktime + 1; // increment blink counter
if (blinktime == 100) // 100 ish is about 1 second
{
blinktime = 0; // Reset blink counter
if (DONE == 0 && PWMdrv > 0) seconds = seconds +1; // increment seconds if running
}
if (blinktime == 0 && seconds >= 60) // 60 is 1 minute
{
minutes = minutes +1; // add a minute
seconds = 0; // reset seconds
}
// SEND OUT LOAD DRIVE
analogWrite(10, PWMdrv); // analogWrite values from 0 to 255
delay (10); // delay creates second interval
// BLINK LED
if (blinktime == 0) digitalWrite (13,LOW);
if (blinktime == 5) digitalWrite (13,HIGH); // on blink
if (blinktime ==
digitalWrite (13,LOW);
if (PWMdrv >= 1 && blinktime == 40) digitalWrite (13, HIGH); // indicate LOAD ON
if (blinktime == 60) digitalWrite (13, LOW); // indicator LED OFF
if (PWMdrv >= 100 && blinktime == 80) digitalWrite (13, HIGH); // indicator LED ON
if (blinktime == 90) digitalWrite (13, LOW); // indicator LED OFF
// SCREEN PRINT ROUTINE
if ( blinktime == 0)
{
Serial.print (AI0);
Serial.print (" ");
Serial.print (battery);
Serial.print ("mV ");
Serial.print (END);
Serial.print (" END ");
Serial.print (PWMdrv);
Serial.print (" PWM ");
Serial.print (minutes);
Serial.print (":");
Serial.print (seconds);
Serial.print (" elapsed ");
if (DONE == 0) Serial.print (AMPmin); // overloads at 327Amp Min
else Serial.print (TOTAL);
Serial.print (" AMP min ");
if (DONE == 0) Serial.print ((float)PWMdrv / oneamp);
else Serial.print ((float)LASTpwm / oneamp);
Serial.print ("A ");
if (DONE == 1) Serial.print(" DONE"); // indicate test finished
Serial.println(" "); // start new line
// SEND AMP MINUTE CAPACITY TO PIN 5 TO READ ON AN ANALOG METER
// filter with a 4 to 5K resistor and 2.2uF cap or higher
// Voltage is divided by two because 255 = 5.1V. The division
// will make 128 = 2.55V Normal micro supply voltage will be between
// 5.05V and 5.2V A CAL for 100 is included
// output is X2 volts
if (DONE == 0) analogWrite (5, AMPmin); // overloads at 255 Amp Min
else analogWrite (5, TOTAL); // or about 4AH
analogWrite (6, 100); // CAL PIN FOR 100 AMP MIN
}
} // END of the program loop