Battery Pack, individual cell voltage measurement

A balancer type does more than just measure individual cell voltage.

Good point mauried.

@phoyt
How much to these gadgets cost?


Rob

That’s what I’m talking about @oric_dan. You only need 4 banks, and 4 Megas for 0.04v resolution.
45x2 tiny resistors. No other hardware.

relays for computer logic gates.

We did an entire runway lighting control system with relays once, 1000s of them in 19" racks, all plug-in modules with NAND, AND, OR, flip flop etc functions and all at 48 volts.

It was destined for an Asian country (Malaysia I think) and the design brief was that it had to be simple technology that the "natives" could fix.

and 4 Megas

You didn't mention 4 megas originally which partly explains why I didn't get it but you still have to isolate the megas from each other. This means powering each mega off it's bank, then having an isolated comms link. Is that what you have in mind?


Rob

You got it Rob!

I'm not the fastest horse in the race, but I get there eventually :)

I've modified my design to allow monitoring of 6 batteries and 2 temperatures. If phoyt or anyone is interested I'll post the new design. This is very similar to what you're proposing but without the extra crap that comes with a Mega and that isn't needed. However with mine you still need a single Arduino (just a small one will do) to talk to a PC, display the results etc.


Rob

We did an entire runway lighting control system with relays once, 1000s of them in 19" racks, all plug-in modules with NAND, AND, OR, flip flop etc functions and all at 48 volts.

It was destined for an Asian country (Malaysia I think) and the design brief was that it had to be simple technology that the "natives" could fix.

And the byline to this is that they could hear it in Indonesia. [check your map if you don't know geography].

Would it be possible to use zener diodes to drop the voltages down into the range that the Arduino can measure?

Nope, leastways I can't think of a way to use zeners.

If you just want to drop the voltage down the easiest way is to use 45 voltage dividers, all set to provide the best range possible for the voltage at that point in the battery string.

Truth is that's probably the simplest method but it's not scalable, picking all the resister would be a pain and this approach needs 46 wires. Also it means some very high voltages are on your PCB, something I would not be happy with.


Rob

With my idea, there is no reason to use different values for each resistor. Only 2 values are needed. Sure with different values you could get more precision with the first few cells, but the one at the end would only get 0.04v precision. So why not just use the same resistors for all, giving them all the same precision instead of increasing the precision of the first cell to 5/1024v. Maybe I haven't explained it properly. It seems like Rob and Dan got it.

Peter is on to something. If you use Zeners to drop the 30-40v wires toward the end in my plan down to 10v, you would get more precision, if you needed it. Everything would have to be calibrated manually in software with a DMM. With this method, and 45 inputs, you could possible do it with only 1 Mega?

Graynomad: Nope, leastways I can't think of a way to use zeners.

If you just want to drop the voltage down the easiest way is to use 45 voltage dividers, all set to provide the best range possible for the voltage at that point in the battery string.

The voltage divider approach obviously loses resolution the further you need to drop the voltage - I don't know what resolution is needed here, but there must come a point where the voltage is so high that it isn't possible to achieve enough resolution.

I was thinking with the zener something like connecting each battery junction to a zener and then through a voltage divider to ground, the idea being that the zener would drop the voltage by a known constant amount to bring the voltage down to a range that can be measured, with no loss of resolution.

By the time you have several cells in series all with varying voltages the range of values that needs to be measured could easily exceed 5V hence the voltage dividers to reduce the range - still some loss of resolution due to the voltage dividers used for that, but nothing like as much as there would have been if dividers were used to drop the full voltage down to 5V.

Works for me! This is the easiest solution for hardware. Calibrating it using a DMM in the code will take some time and effort.

I get the zener idea now (told you I was slow), but if each voltage divider is tuned to the voltage surely there's no loss of resolution anyway.

We haven't heard from the OP since post #7 so as is often the case we're talking to ourselves, still it's good to bounce some ideas around.


Rob

Hello Would the temperature coeff. of zener/avalanche diodes skew the accuracy ? http://users.tpg.com.au/users/ldbutler/ZenerDiodes.htm jolphil

I realize this is old. But I'm working on a vary similar project using LifePo4 batteries. My batteries modules are from the Fisker cars. There 24v each. I am trying to brake them up to 12v. I am planning on splitting the packs to get 2 12v batteries out of each module. I had thought about using voltage dividers but that is assuming that the other cells before the cell you would like to measures stay at the same voltage. so if a cell that is before the one you would like to measure is low that will throw off the sell that you are measuring. Switching between cells sounds like a good idea. instead of using relays could you use transistors? How would you write the code for that?? Also I would like to have a serial print so it would need to tell me what the cell voltages are. I guess you can do that with a delay of some kind. I have a basic sketch made up for 4 cells using the analog inputs that will trigger a digital output if any of the 4 cells goes below a certain threshold voltage. That would trigger an external alarm/relay to pull that module out of the group. I have 4 of the 24v modules that i was going to do this mod to and parallel them in my battery bank. Each module will be getting a monitor. I was also planning on having individual cell balancing driven by a comparator to trigger a mosfet to a resistor bank. That would keep the cells from over charging in the event one or two cells have not fully charged.

There are a bunch of good ideas here.

Hope this can revive some of them.

Thanks Rich.

"Switching between cells sounds like a good idea. instead of using relays could you use transistors?"

I lean toward mechanical relays for this ( double pole). Transistors have voltage drop, relays do not.

Each relay can switch in a cell ( positive, and ground), to be tested, using only one analog pin.

Thanks for the quick reply.

I thought it would be something like that. ( voltage drop across transistors) I have started writing a new sketch. I’m getting a little lost on how to have it print the reading of individual cells and hold it till it reads that cell again. I will post a copy of what I have so far. Maby you can tell me if I’m on the right track.

Thanks again.
Rich.

int safty = 13;
int check = 12;
int threshold = 2.5;

int Cellv = A0;
int CellVal = 0;
float Cellpin = 0;
float CellVoltage = 0;

int gnd = 2;
int Cell1 = 3;
int Cell2 = 4;
int Cell3 = 5;
int Cell4 = 6;


  void setup(){
    Serial.begin(9600);
    
pinMode(safty, OUTPUT);
pinMode(check, INPUT);

pinMode(Cell1, OUTPUT);
pinMode(Cell2, OUTPUT);
pinMode(Cell3, OUTPUT);
pinMode(Cell4, OUTPUT);

}
 
 
   void loop(){
    
    int checkVal = digitalRead(check);
    int sampleCellVal = 0;
    int avgCellVal = 0;
    
    for (int x = 0; x< 10; x++){
      
      CellVal = analogRead (Cellv);
      sampleCellVal = sampleCellVal + CellVal;
      
      digitalWrite(Cell1, HIGH); delay(0.0);
      digitalWrite(Cell1, LOW); delay(0.5);
      digitalWrite(Cell2, HIGH); delay(1.0);
      digitalWrite(Cell2, LOW); delay(1.5);
      digitalWrite(Cell3, HIGH); delay(2.0);
      digitalWrite(Cell3, LOW); delay(2.5);
      digitalWrite(Cell4, HIGH); delay(3.0);
      
      
      
      if (CellVoltage < threshold) digitalWrite(safty, HIGH);
      else{ digitalWrite(safty,LOW);
      
    }


delay (10);

    }
    
    avgCellVal = sampleCellVal /10;
    Cellpin = avgCellVal * 0.00610;
    
    CellVoltage = Cellpin;
    
    
    
    
delay(10);
   }

I know I said I was going to have 2 groups of 4 cells. But for trial I’m only going to do one group. I can add the other group after proof of concept. I’m also doing .5 seconds of read per cell. I’m not really shore if this is enough time to get an accurate reading?

I believe you meant to say, you decided to use mechanical relays to connect each cell for analog reading on just one analog pin. Right?

I had problem reading your script, but I don't think it is perfect yet. It helps to add comments in the script.

I think you will want to use a couple arrays, since you will have several cells to test.

You will need a relay for each cell, and be able to control each relay. You may not have enough output pins to control that many relays directly, and may need some sort of multiplexer chip. How many cells do you think there will be?

Yes I am going the rout of the relay. I’m only going to be doing 8 cells per module. So then I would only need 8 relays, 8 outputs for the relays. But I’m also using an output for a safty cutout and and input to check the safty cut out. So that would be a total of 10 digital I/O. I put in some comments I hope this will help. I’m still trying to figure out or to serial print the different voltage reading of the different cells.

int safty = 13; // An output to Cut out the moduel if any cell is under a specified voltage.//
int check = 12; // An input to check the output of safy.//
int threshold = 2.5; // The spesified voltage of the safty cutout.//

int Cellv = A0; //The analog input to meshure voltages of the cells.//
int CellVal = 0;
float Cellpin = 0;
float CellVoltage = 0;


int Cell1 = 3; // Output to triger relay 1 for cell one to read analog voltage.//
int Cell2 = 4; // Output to triger relay 2 for cell 2 to read analog voltage.//
int Cell3 = 5; // Output to triger relay 3 for cell 3 to read analog voltage.//
int Cell4 = 6; // Output to triger relay 4 for cell 4 to read analog voltage.//


  void setup(){
    Serial.begin(9600);
    
pinMode(safty, OUTPUT);
pinMode(check, INPUT);

pinMode(Cell1, OUTPUT);
pinMode(Cell2, OUTPUT);
pinMode(Cell3, OUTPUT);
pinMode(Cell4, OUTPUT);

}
 
 
   void loop(){
    
    int checkVal = digitalRead(check);
    int sampleCellVal = 0;
    int avgCellVal = 0;
    
    for (int x = 0; x< 10; x++){
      
      CellVal = analogRead (Cellv);
      sampleCellVal = sampleCellVal + CellVal;
      
      digitalWrite(Cell1, HIGH); delay(0.0); // delays to change between cells of 5 mills.//
      digitalWrite(Cell1, LOW); delay(5.0);
      digitalWrite(Cell2, HIGH); delay(10.0);
      digitalWrite(Cell2, LOW); delay(15.0);
      digitalWrite(Cell3, HIGH); delay(20.0);
      digitalWrite(Cell3, LOW); delay(25.0);
      digitalWrite(Cell4, HIGH); delay(30.0);
      
      
      
      if (CellVoltage < threshold) digitalWrite(safty, LOW);
      else{ digitalWrite(safty,HIGH);
      // if statment so if the voltage goes below threshold it trigers the output of the safty pin.//
    }


delay (10);

    }
    
    avgCellVal = sampleCellVal /10; // calibration of the anilog voltage pin.//
    Cellpin = avgCellVal * 0.00480;
    
    CellVoltage = Cellpin;
    
   
   
Serial.print("  B1C1 = "); delay (0.0); // delay is an attempt at distiguishing between the difrent cells as it parces them.//
Serial.print(CellVoltage);
Serial.print("  B1C2 = "); delay (10.0);
Serial.print(CellVoltage);
Serial.print("  B1C3 = "); delay (20.0);
Serial.print(CellVoltage);
Serial.print("  B1C4 = "); delay (30.0);
Serial.print(CellVoltage);
Serial.print("  safty = ");
Serial.println(checkVal);
    
delay(1000);
   }
      digitalWrite(Cell1, HIGH); delay(0.0); // delays to change between cells of 5 mills.//
      digitalWrite(Cell1, LOW); delay(5.0);
      digitalWrite(Cell2, HIGH); delay(10.0);
      digitalWrite(Cell2, LOW); delay(15.0);

May need to look more like:

     digitalWrite(Cell1, HIGH); delay(5); // delays to change between cells of 5 mills.//
       cellOneVolts=analogRead(cellV);
      digitalWrite(Cell1, LOW); delay(5);
      digitalWrite(Cell2, HIGH); delay(5);
       cellTwoVolts=analogRead(cellV);
      digitalWrite(Cell2, LOW); delay(5);

Once you have all the cell***Volts, then you can display them to the serial monitor. one line at a time, or maybe all 8 on the same line with time (depending on how long of a line your display will take).

Side note: I am not confident that the relays will react in 5 ms, so I would suggest something like 50 ms. Also, just in case the relays are slow, put a ~50 ohm resister on both legs of all the relays. We don't want to short out cells!