2016. február 21., vasárnap

Battery capacity measurement with an Arduino - In other words, let's discharge the batteries


Welcome everyone. Who has read my plan - that I will use the Keweisi capacity meter to measure my 18650 cell capacities - knows that I have chosen the Arduino solution, because it gives a more accurate reading. I have spent several days to find out what parts I need and what code do I have to run. I have analyzed several similar projects on the internet. I had to create a simple yet effective code. With my solution it is possible to measure the capacity of 1,2V Ni-MH, Ni-Cd and 3,7V Li-ion or polimer batteries. In fact you can measure the capacity of any battery with this design which has a voltage lower then 5V.

Ingredients:

-a microcontroller, in this case I used an Arduino Duemilanove. Of course it is not a genuine Italian one, it is an aftermarket model from China. I do not think this is still in production, the Uno model is the recent one, but not much has changed on it since. If someone has another type of microcontroller, my connection diagram will not help.

-a resistor. This should be rated at least 5W, so it will be able to bear the load. I have bought a 3,9 OHM and an 5,9 OHM ceramic resistor. The smaller OHM rating we use, the bigger the current will be to discharge the batteries. Why does it have to be 5W rated? It is because if for example the Voltage is 4V and I want to discharge with 1A current then the output is: 4V*1A=4W, this energy is turned into heat on the resistor. If we use OHM's law for calculation at 4V and with 3,9 OHM resistor, the Current will be 4V/3,9OHM=around 1A. Of course as the battery voltage decreases over time, the current will become smaller and smaller. If I use the 5,9 OHM resistor, then at 4V the current will be: 4V/5,9OHM=0,677A. I used the 4V example because a fully charged Li-ion cell gives around 4 volts. This was just an example. But if for instance I want to discharge an AAA 1,2V Ni-Mh battery, the numbers are the following, with a 3,9OHM resistor it will discharge it with 0,307A, which they can bear. I am not sure how much current they can give, but I think 0,3A is enough to prevent overheating. It seems they can bear 1A discharge current as well. You can now calculate the required resistor size if you know with how much current you want to discharge the battery.

-a MOSFET. I used one with three leads called: IRLU8256. This is required to open and close the discharge circuit controlled digitally with the Arduino. It is like a switch, but you can control it from the Arduino code. In case of a Li-ion battery you can turn the discharge off, to prevent over discharging.
Important characteristics: Vds=25V, so it can bear the voltage. Rds=around 5mOHM, here the smaller is better so it has a little resistance. Vgs should be little, so the Arduino 5V power is able to turn the FET on and off.

-a battery to be discharged. You can also buy battery holders, but used magnets to hold the wires on the battery. This is a cheaper solution.

That is all. I have read on the internet, that other designs also measure the voltage on the MOSFET and if there is any loss they use it as well for the current calculation. My MOSFET always gave 0V here, so I left it out.

The two other designs I used as inspiration: One, two.

Warning! The resistor heat up during discharge so it can burn your hand. Of course it will not burn, but it will be hot. Always use wires which can bear the load that you are using. It can happen that the MOSFET stays open and keeps discharging the batteries if we shut the Arduino off or if we stop the code run in the middle. Do not leave it unattended and make sure that it will not over discharge the batteries. I take no responsibilities for the damage this discharger may cause.

If there is no battery connected and the code runs, it will give false Voltage readings.

You can see on the pictures how to connect the wires. Although there are two batteries connected in series on the picture, this is only because there was no other picture in the program. I usually discharge one cell at a time.

Arduino code:

#define MIN_VOLTAGE      950   // mV, the voltage should not drop until this amount. At a Li-ionnál: 3000, with NI-MH:950

int FETPin = 13;      // select the digital output pin for the LED and the FET
int BatVoltage = 0;
int STOPI = 0;
float loadCurrent, TotalCurrent, TotalCurrent2, onescurrent;
int sec = 1;

void setup() {
  unsigned long PrevTime;
  Serial.begin(9600);// start serial port to send data during run to the PC
  pinMode(FETPin, OUTPUT);
  digitalWrite(FETPin, LOW); 
  Serial.println("6");	//countdown until the discharge process, I use this time to connect the battery
  delay(1000); 
  Serial.println("5");
  delay(1000); 
  Serial.println("4");
  delay(1000); 
  Serial.println("3");
  delay(1000); 
  Serial.println("2");
  delay(1000); 
  Serial.println("1");
  delay(1000); 
  
  Serial.println("START!");
  int val1 = analogRead(0); // we take an initial test to measure the initial voltage
  BatVoltage = map(val1, 0,1023,0,5000);;
  Serial.print("Starting voltage in mV=");
  Serial.println(BatVoltage + 40); // here I added 40 to the the measured voltage as the Arduino measuread an incorrect Voltage
}

void loop() {
  
  
  if(STOPI != 1){
    
    digitalWrite(FETPin, HIGH);  //here we active the the discharge circuit
    int val1 = analogRead(0); 
    BatVoltage = map(val1, 0,1023,0,5000);;
    
    loadCurrent = (BatVoltage + 40) / 3.9;              //at the end of the equation the exact resistor rating in OHM should be changed

    onescurrent =  loadCurrent / 3.6;		//here we calculate the Current amount load in a second
    TotalCurrent = onescurrent + TotalCurrent;
        
    Serial.print(BatVoltage + 40);   
    Serial.print(" mV   I=");
    Serial.print(loadCurrent);		//Current load amount per second
    Serial.print(" mA   Time=");
    Serial.print(sec);
    Serial.print(" s   Totalcurrent=");
    Serial.print(TotalCurrent / 1000);   // total mAh burnt
    Serial.println(" mAh");
    sec = sec + 1;
    if(BatVoltage + 40 <= MIN_VOLTAGE){
      STOPI = 1;
      Serial.println("Voltage is lower then the set min Voltage STOP!");
    }
  }
  else{
    digitalWrite(FETPin, LOW);  
  }
  delay(1000);  // wait one second, then get next set of samples  
}

The measured capacity is just an estimate, as the higher the discharge Current, the lower the measured capacity will be.

Nincsenek megjegyzések:

Megjegyzés küldése