Go Back   EcoModder Forum > EcoModding > Fossil Fuel Free
Register Now
 Register Now
 

Reply  Post New Thread
 
Submit Tools LinkBack Thread Tools
Old 04-18-2014, 09:31 PM   #41 (permalink)
Southern Squidbillie
 
Join Date: Aug 2012
Location: Heart of Dixie
Posts: 97
Thanks: 50
Thanked 26 Times in 22 Posts
Fool-proof = Sure Fire

Quote:
Originally Posted by Daox View Post
If you want a fool proof system you want a BMS. If you want to tinker and tweak, then you can get away without one.
If you check the DIY electric car site there is a thread (search Elithion's posts) with a count of the number of cars that burned up--the largest number were top-balancers using a BMS. If you want a sure fire way to burn your garage down then just put your trust in a BMS and let it control your charging.

  Reply With Quote
Alt Today
Popular topics

Other popular topics in this forum...

   
Old 04-19-2014, 02:15 AM   #42 (permalink)
Master EcoModder
 
mechman600's Avatar
 
Join Date: Jul 2008
Location: Langley, BC
Posts: 1,228

Fusion - '16 Ford Fusion Hybrid SE
Thanks: 190
Thanked 275 Times in 168 Posts
I have been testing different types of Arduino to Arduino communication in an attempt to find the best way to use multiple boards for BMS and sending the voltage measurements to a master board. Once we can get a bunch of accurate voltages (18 in TurnNBurn's case) to the Master board, it isn't difficult to switch a charger relay off or set off DEFCON 1 low voltage warnings while driving.

Methods:
1. PWM/duty cycle two way communication (inquire & read/respond & send)
2. Two way serial communication (inquire & read/respond & send)
3. One way serial communication (read & decipher/broadcast)

Side note: I am testing with four analog inputs - two 5K pots and two LM34 temperature sensors. I was having trouble with erratic ADC readings with multiple inputs. Example: when adjusting one of the pots up and down, one of the temperature readings would always go wonky.

What I discovered is that the MCU really has only one ADC and it is mulitplexed to 8 inputs. Since the ADC is not digital it can get residual data left on it that is then picked up by the next read, throwing it off. All I had to do to fix this is do two analog reads and chuck the first one, similar to burning a card in Texas Hold Em:

Quote:
analogRead(potPin1);
int raw_adc1 = analogRead(potPin1);
1. PWM/Duty Cycle Communication

The master sends a PWM instruction (inquiry), waits and then reads:

Quote:
analogWrite(ComToSlave, 100); //send PWM inquiry to Slave
delay(30); //wait a moment
int adc1_COM = pulseIn(ComToMaster, HIGH); //measure returned PWM data

analogWrite(ComToSlave, 150);
delay(30);
int adc2_COM = pulseIn(ComToMaster, HIGH);

analogWrite(ComToSlave, 200);
delay(30);
int adc3_COM = pulseIn(ComToMaster, HIGH);

analogWrite(ComToSlave, 250);
delay(30);
int adc4_COM = pulseIn(ComToMaster, HIGH);
The slave reads instructions and writes PWM values to the master accordingly:

Quote:
int instru = pulseIn(ComToSlave, HIGH); //measure PWM inquiry
if(instru > 600 && instru < 1000) { //if inquiry is in this range....
analogWrite(ComToMaster, adc1_COM); //...write PWM value of adc1_COM

} else if (instru > 1000 && instru < 1400) {
analogWrite(ComToMaster, adc2_COM);

} else if (instru > 1400 && instru < 1800) {
analogWrite(ComToMaster, adc3_COM);

} else if (instru > 1800 && instru < 2200) {
analogWrite(ComToMaster, adc4_COM);

} else {
digitalWrite(ComToMaster, LOW); //inquiry failure failsafe
}
Pros: data is always allocated to the proper address.
Cons: data is reduced to 8-bit PWM (256 steps); erratic and jittery.
Conclusion: FAIL.

2. Two Way Serial Communication

The master sends a serial instruction (inquiry), waits and then reads serial data:

Quote:
while(Serial.available() > 0) {

Serial.println(1); //send value of 1 to Slave
delay(1); //wait a moment
adc1 = Serial.parseInt() / 204.8; //read serial data and call it adc1
Serial.read(); //clear the serial buffer

Serial.println(2);
delay(1);
adc2 = Serial.parseInt() / 204.8;
Serial.read();

Serial.println(3);
delay(1);
adc3 = Serial.parseInt() / 2.05;
Serial.read();

Serial.println(4);
delay(1);
adc4 = Serial.parseInt() / 2.05;
Serial.read();
The slave reads the serial instructino and writes ADC values to serial bus accordingly:

Quote:
while(Serial.available() > 0) {
command = Serial.parseInt(); //inquiry sent by Master
Serial.read(); //clear the serial buffer
}
if(command == 1) { //if Master says "1", print adc1 value
Serial.println(adc1);
}
if(command == 2) {
Serial.println(adc2);
}
if(command == 3) {
Serial.println(adc3);
}
if(command == 4) {
Serial.println(adc4);
}
Pros: data is very accurate, no jittering.
Cons: data rarely arrives at the correct address. Ex..data is usually shuffled to the incorrect address on the Master. Unplugging both boards and restarting sometimes corrects this. Sometimes.
Conclusion: FAIL.

3. One way serial communication

The Slave throws all ADC data onto the serial bus with a letter preceding it to give it an address that the slave can understand:

Quote:
// Slave Sender

// Data Buffering Parameters
const byte sampleRate = 10; // number of samples
const byte buffer = 25; // buffer delay() time

int raw_adc[5];
int adc[5];

void setup() {
pinMode(0, INPUT); // set up input pins
pinMode(1, INPUT);
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, INPUT);
Serial.begin(1200);
}
void loop() {
int raw_sample[] = {0, 0, 0, 0, 0};
for(int x = 0; x < 5; x++) {
analogRead(x); // read ADC + burn the first one
raw_adc[x] = analogRead(x); // read ADC a second time & keep it
}
for(int i = 0; i < sampleRate; i++) { // Data buffering/averaging loop
raw_sample[0] = raw_sample[0] + raw_adc[0];
raw_sample[1] = raw_sample[1] + raw_adc[1];
raw_sample[2] = raw_sample[2] + raw_adc[2];
raw_sample[3] = raw_sample[3] + raw_adc[3];
raw_sample[4] = raw_sample[4] + raw_adc[4];
delay(buffer);
}
for(int i = 0; i < 5; i++) {
adc[i] = raw_sample[i] / sampleRate; // Data average from above loop
char address = 'a' + i; // Create broadcast character address
Serial.write(address); // Broadcast address...
Serial.write(lowByte(adc[i])); // ...followed by corresponding data low..
Serial.write(highByte(adc[i])); // ...and data high
}
The Master reads the serial bus and deciphers the data, allocating it to the correct address:

Quote:
while(Serial.available() > 2) { // wait for first 2 bytes
comm_in = Serial.read();
if(comm_in == 'a') { // if address broadcast is 'a', the data must be adc[0]
adc[0] = Serial.read(); // read low byte
adc[0] += Serial.read()<<8; //read high byte
}
if(comm_in == 'b') {
adc[1] = Serial.read();
adc[1] += Serial.read()<<8;
}
if(comm_in == 'c') {
adc[2] = Serial.read();
adc[2] += Serial.read()<<8;
}
if(comm_in == 'd') {
adc[3] = Serial.read();
adc[3] += Serial.read()<<8;
}
if(comm_in == 'e') {
adc[4] = Serial.read();
adc[4] += Serial.read()<<8;
}
Pros: data is quick and accurate with no jitter. Data is always allocated to the proper address.
Cons: none. Less control over data flow?
Conclusion: SUCCESS.

Last edited by mechman600; 04-20-2014 at 11:44 PM..
  Reply With Quote
Old 04-19-2014, 01:26 PM   #43 (permalink)
Master EcoModder
 
P-hack's Avatar
 
Join Date: Oct 2012
Location: USA
Posts: 1,408

awesomer - '04 Toyota prius
Thanks: 102
Thanked 252 Times in 204 Posts
Cool! FYI you have some synchronization bugs in your method 2. I prefer the method 2 approach as it has a controller in control that initiates communication so it can collate the results. Also fixed length binary data is easier to keep in sync than random length numbers as strings (and faster). Finally arrays make nice containers for lots of sensors, here is an example:

Code:
//example slave code
//hard code the first cell this slave is reading. (cell 1 is 0)
#define cellstart 8 //16 for the second slave
#define numcells  8  //2 for the second slave
void setup() {                
  Serial.begin(9600);
}

int readings [numcells];
void loop(){
  for(int x = 0;x<numcells;x++)
    for(int t=0;t<16;t++) //take several readings
      readings[x]=analogRead(x);
  if(Serial.available() > 0) {
    int cell = Serial.read(); //inquiry sent by Master
    //see if this board services the cell in question
    if(cell >= cellstart && cell < cellstart + numcells){
      Serial.write(lowByte(readings[cell-cellstart]));  //send low byte first
      Serial.write(highByte(readings[cell-cellstart]));     //then hi byte
    }
  }
}
Code:
//master example
//model 2, with byte level communication and arrays/iteration
#define numcells 18


void setup() {                
  Serial.begin(9600);
}
int  readings [numcells];//easier to deal with lots of values in an array and loop over them
void loop() {
  for(int x = 0; x < 8;x++) //readings for cells 0-7 are "local"
    for(int t = 0; t < 16;t++)
      readings[x]=analogRead(x);
      
  for(int x = 8; x < numcells; x++){
    Serial.write(x); //send the cell number to the slaves
    while(Serial.available() <2) {} //wait for two bytes of adc
    readings[x] = Serial.read(); //load the low byte
    readings[x] += Serial.read()<<8; // fill in the high byte  
  }

//... do something interesting with all those readings
//i.e. convert them to actual cell voltages and look for high and low
int basevolt=0;
  for(int x = 0; x < numcells; x++){
    int cellvolt=readings[x]-basevolt;
    basevolt=basevolt+cellvolt;
    
  //  lcd.clear();
   // lcd.goto((x%5)*4,x/20);
    //lcd.print(cellvolt); //10 bit value of the cell voltage
    
  }

  delay(500);               // wait for a second
}
note, you might want to shuffle the cell starts and the local loop so that you have some ADC ports on the master for current and temp and ?

Last edited by P-hack; 04-19-2014 at 01:48 PM..
  Reply With Quote
The Following User Says Thank You to P-hack For This Useful Post:
mechman600 (04-19-2014)
Old 04-19-2014, 02:01 PM   #44 (permalink)
Master EcoModder
 
P-hack's Avatar
 
Join Date: Oct 2012
Location: USA
Posts: 1,408

awesomer - '04 Toyota prius
Thanks: 102
Thanked 252 Times in 204 Posts
Also one of Jacks complaints (and he is definitely a battery guru) is the unsophisticated interface between bms and charger. He goes into charging and monitoring voltages in some detail in that video. Because of things like internal resistance (which is wildly variabe), it is challenging to determine the state of charge under load, and some over or under voltage is normal if you deviate from the manufacturers charge profile.

ANYONE WHO IS CHARGING A BATTERY MANUALLY OR CONTROLLING A CHARGER SHOULD WATCH IT.

Last edited by P-hack; 04-19-2014 at 02:12 PM..
  Reply With Quote
Old 04-19-2014, 02:28 PM   #45 (permalink)
Master EcoModder
 
Ryland's Avatar
 
Join Date: Jan 2008
Location: Western Wisconsin
Posts: 3,903

honda cb125 - '74 Honda CB 125 S1
90 day: 79.71 mpg (US)

green wedge - '81 Commuter Vehicles Inc. Commuti-Car

Blue VX - '93 Honda Civic VX
Thanks: 867
Thanked 434 Times in 354 Posts
Quote:
Originally Posted by kennybobby View Post
If you check the DIY electric car site there is a thread (search Elithion's posts) with a count of the number of cars that burned up--the largest number were top-balancers using a BMS. If you want a sure fire way to burn your garage down then just put your trust in a BMS and let it control your charging.
There is a difference between balance boards and battery management systems that top balance, because I have seen a handful of balance boards that just "prevent" each cell from going over the set voltage and bleed the extra energy off as heat and that is where fires can start!
If you are dumping in 10a or 15a or even more amps in to a battery pack and you have a 1/2amp resister that bleeds off power when the battery is up to voltage then something is going to go wrong and at some point you are going to have a battery swell or start on fire!

A battery management system needs to be able to manage the pack, it needs to be able to talk to the charger and throttle back the charger if ANYTHING is going wrong, it also needs to be able to cut power to the controller if anything is going wrong and it needs to have thermo sensors on each battery to shut stuff down if it's getting hot.

We have a bunch of members in our electric car club with lithium batteries and a few of them have destroyed batteries by trying to watch a battery as it charged to make sure it didn't over charge, doing that is like trying to catch your toast out of the toaster as it pops up, only your toaster is taking many hours to toast, you turn around and your battery is over charged and destroyed!
But most of the batteries have been destroyed by bottom balancing.
  Reply With Quote
Old 04-19-2014, 05:05 PM   #46 (permalink)
Master EcoModder
 
P-hack's Avatar
 
Join Date: Oct 2012
Location: USA
Posts: 1,408

awesomer - '04 Toyota prius
Thanks: 102
Thanked 252 Times in 204 Posts
Quote:
Originally Posted by Ryland View Post
...We have a bunch of members in our electric car club with lithium batteries and a few of them have destroyed batteries by trying to watch a battery as it charged to make sure it didn't over charge
lithium ion or lifepo4?

Quote:
Originally Posted by Ryland View Post
But most of the batteries have been destroyed by bottom balancing.
Bottom balancing them via how? leaving a resistor on too long or something?
  Reply With Quote
Old 04-20-2014, 07:07 PM   #47 (permalink)
Master EcoModder
 
mechman600's Avatar
 
Join Date: Jul 2008
Location: Langley, BC
Posts: 1,228

Fusion - '16 Ford Fusion Hybrid SE
Thanks: 190
Thanked 275 Times in 168 Posts
I was hoping that a can of 'bottom vs top balance' worms wouldn't be opened here. Just go to DIYelectriccar.com and see how violent and ill-tempered those "discussions" become.
It's simple. Keep each cell's voltage between 2.5 and 3.6 (LiFePO4) or 2.7 and 4.2 (Lithium Ion). With a simple way to measure it all, cell death is impossible.

P-hack, you have taught me much about programming here and I thank you. I was wondering why you would read low byte and then high byte, but then got my answer when I set it up this way. Man is it ever fast now! Data streams in my example #3 above ridiculously fast now. I think this is the method I will use because of simplicity. Plus, this keeps the TX pin free on boards so they can relay messages along, although more can be created by using software serial if need be.

EDIT: I have altered my code above in example 3 to reflect what P-hack has taught me. I will update example 2 soon.

Last edited by mechman600; 04-20-2014 at 11:46 PM..
  Reply With Quote
Old 04-23-2014, 11:46 PM   #48 (permalink)
Master EcoModder
 
mechman600's Avatar
 
Join Date: Jul 2008
Location: Langley, BC
Posts: 1,228

Fusion - '16 Ford Fusion Hybrid SE
Thanks: 190
Thanked 275 Times in 168 Posts
Voila:



Notes:
-Each board has its own isolated DC-DC converter and serial comm is through opto-isolators to ensure full isolation (I have tested serial comm at 1200 baud and PS2502 optos work fine)
-Schematic is for two way serial comm between boards, but I would do one way comm (Example 3 above) to free up pins for other things like a motor temp sensor
  Reply With Quote
Old 04-25-2014, 05:04 PM   #49 (permalink)
Master EcoModder
 
P-hack's Avatar
 
Join Date: Oct 2012
Location: USA
Posts: 1,408

awesomer - '04 Toyota prius
Thanks: 102
Thanked 252 Times in 204 Posts
It's, umm, gotten kinda expensive and complicated. You sure you don't want to experiment with the $10 discovery boards with 20 odd ADC onboard? I mean the language isn't *that* bad and sure simplifies the hardware. There are plenty of code examples online for stm32.
  Reply With Quote
Old 04-25-2014, 09:56 PM   #50 (permalink)
Master EcoModder
 
mechman600's Avatar
 
Join Date: Jul 2008
Location: Langley, BC
Posts: 1,228

Fusion - '16 Ford Fusion Hybrid SE
Thanks: 190
Thanked 275 Times in 168 Posts
About $100. Way cheaper than a "real" BMS. And arguably better.
The most expensive bits are the DC-DC converters @ $18/each X 3 from Digikey. Nanos are $7.75/ea here: Mini USB Nano V3 0 ATMEGA328P 5V Micro Controller Board FOR Arduino Compatible | eBay

EDIT: I just bought two of these Nanos! Ha ha.

  Reply With Quote
Reply  Post New Thread






Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Content Relevant URLs by vBSEO 3.5.2
All content copyright EcoModder.com