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

Reply  Post New Thread
 
Submit Tools LinkBack Thread Tools
Old 02-07-2012, 10:51 PM   #1 (permalink)
Administrator
 
Daox's Avatar
 
Join Date: Dec 2007
Location: Germantown, WI
Posts: 10,090

CM400E - '81 Honda CM400E
90 day: 39.62 mpg (US)

Daox's Grey Prius - '04 Toyota Prius
Team Toyota
90 day: 38.47 mpg (US)

Daox's 04 Civic - '04 Honda Civic DX
90 day: 41.58 mpg (US)

Daox's Insight - '00 Honda Insight
90 day: 64.33 mpg (US)
Thanks: 1,611
Thanked 1,916 Times in 1,179 Posts
DIY open source lithium BMS (battery management system)

I've made enough progress with my lithium BMS that I think its time to post up what I have so far. I am posting the info for others to use as well as get some feedback.

Let me preface this all with the fact that I am by and far no expert in this. I know some programming and a little bit about electronics. That and a lot of googling and help from others has lead me to developing this.

The BMS is currently setup to work with the plugin kit for my Prius. So, right now its very simple. For example, where you see dc-dc converter it would be the controller in an EV. However, it was developed while keeping in mind that I'd like to use a similar version on an EV.

With that I'd like to go over generally how it works without having to dive into code:

Charging protection is pretty simple. All the cells voltages are individually monitored via a series of celllog devices. The celllog can measure up to 8 cells at once. If more cell monitoring is needed you need another celllog and the tiny circuit that accompanies it. My circuit diagram shows 2 celllogs which is what I am using. The celllog has a user settable high voltage alarm that is used. Once the alarm goes off, the arduino cuts power to the charger.

Discharge protection is taken care of via a current sensor. You have to enter in the amp hours your batteries are rated for and the max DOD you want them to see. From there the current sensor will keep track of amp hours used. For my plugin kit it automatically shuts the kit off after I hit my max DOD. For a full EV you could simply not use that part of the circuit. I have added an 8 LED bar graph that tracks SOC of the pack as a 'fuel gauge'.

Balancing is currently not done with the BMS. It is designed to have the batteries balanced at the low end of their charge and then put into use. I have yet to find a good way to keep track of the SOC of each cell and balancing makes that much more complicated.

Thermal protection is not currently done either. The plugin kit doesn't even pull 1C on the batteries so its not an issue. However, I would be interested in adding this.

Here is the schematic:



And here is the code (NOT UP TO DATE):
Code:
/*
  Lithium BMS
  This is a simple BMS system for lithium ion batteries.
*/

#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/sleep.h>

// Pins
const int OnSwitchPin = 2;  // pin to read on switch status
const int ChargerRelayPin = 3;  // pin to control the charger relay
const int Pin110V = 4;  // pin to read if charger is plugged in
const int OnSwitchRelayPin = 5;  // pin to control the on switch (dc-dc pwr)
const int AlarmPin = 6;  // pin to read celllog alarm signal
const int latchPin = 8;  // pin to connect to latch pin on shift register
const int dataPin = 11;  // pin to connect to data pin on shift register
const int clockPin = 12;  // pin to connect to clock pin on shift register
const int CurrentPin = 1; // analog pin to read the current sensor

// Variables
volatile float CurrentRead = 0;  // holds CurrentPin analog read
volatile float AHused = 0; // holds amp hours used
float BatteryAH = 0; // holds usable battery amp hours
int AlarmPinStatus = 0;  // holds AlarmPin status
int OnSwitchPinStatus = 0;  // holds the OnSwitchPin status
int Pin110VStatus = 0;  // holds the Pin110V status
unsigned long DelayTimer = 0;  // variable to hold disconnect time
float SOC = 0;  // holds state of charge

// User defined variables
const int RatedBatteryAmpHours = 78;  // rated amp hours of the batteries
const float DOD = .7;  // maximum depth of discharge allowed


void setup() {
  pinMode(AlarmPin, INPUT);
  pinMode(ChargerRelayPin, OUTPUT);
  pinMode(Pin110V, INPUT);
  pinMode(OnSwitchRelayPin, OUTPUT);
  pinMode(OnSwitchPin, INPUT);
  pinMode(CurrentPin, INPUT);
  digitalWrite(AlarmPin, HIGH);  // set AlarmPin high
  digitalWrite(ChargerRelayPin, LOW);  // turn charger relay off
  digitalWrite(OnSwitchRelayPin, LOW);  // turn on switch off
  
  BatteryAH = RatedBatteryAmpHours * DOD;  // calculate usable Ah
  
  // initialize Timer1
  cli();          // disable global interrupts
  TCCR1A = 0;     // set entire TCCR1A register to 0
  TCCR1B = 0;     // same for TCCR1B
  // set compare match register to desired timer count
  OCR1A = 16001;
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS10
  TCCR1B |= (1 << CS10);
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
  // enable global interrupts
  sei();
}

void loop() {

  // SOC gauge code
  // calculate SOC
  SOC = (BatteryAH - AHused) / BatteryAH;
  // write SOC to led bargraph
  if (SOC > .875) {
    // 8 leds lit up
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 255);
    digitalWrite(latchPin, HIGH);
  }
  else if (SOC > .75) {
    // 7 leds lit up
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 127);
    digitalWrite(latchPin, HIGH);
  }
  else if (SOC > .625) {
    // 6 leds lit up
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 63);
    digitalWrite(latchPin, HIGH);
  }
  else if (SOC > .5) {
    // 5 leds lit up
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 31);
    digitalWrite(latchPin, HIGH);
  }
  else if (SOC > .375) {
    // 4 leds lit up
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 15);
    digitalWrite(latchPin, HIGH);
  }
  else if (SOC > .25) {
    // 3 leds lit up
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 7);
    digitalWrite(latchPin, HIGH);
  }
  else if (SOC > .125) {
    // 2 leds lit up
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 3);
    digitalWrite(latchPin, HIGH);
  }
  else if (SOC > 0) {
    // 1 leds lit up
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 1);
    digitalWrite(latchPin, HIGH);
  }
  else {
    // 0 leds lit up
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 0);
    digitalWrite(latchPin, HIGH);
  }

  
  // Charger connect code
  // read pin110v status
  Pin110VStatus = digitalRead(Pin110V);
  // if 110V power is plugged in
  if (Pin110VStatus == HIGH) {
    digitalWrite(ChargerRelayPin, HIGH);  // turn charger on
  }
  
  
  // Charger disconnect code
  // read alarm pin status
  AlarmPinStatus = digitalRead(AlarmPin);
  // if alarm turns on set a timer to detect false alarms
  if (AlarmPinStatus == LOW && millis() - DelayTimer < 10) {
    DelayTimer = millis();  // set timer
  }
  // if alarm stays on
  if (AlarmPinStatus == LOW && millis() - DelayTimer > 2000) {
    digitalWrite(ChargerRelayPin, LOW);  // turn charger off
    AHused = 0;  // reset amp hours
    DelayTimer = 0;  // reset delay timer
  }
  
  
  // DC-DC connect code
  // read on switch status
  OnSwitchPinStatus = digitalRead(OnSwitchPin);
  // if dc-dc switch is on && battery has capacity left
  if (OnSwitchPinStatus = HIGH  && AHused < BatteryAH) {
    digitalWrite(OnSwitchRelayPin, HIGH);  // turn dc-dc converter on
  }
  
  
  // DC-DC disconnect code
  // if amp hours used exceeds usable amp hour capacity
  if (AHused > BatteryAH)
  {
    digitalWrite(OnSwitchRelayPin, LOW);  // turn dc-dc converter off
  }
  
  
  // DC-DC power down code
  // if dc-dc converter switch is off enter sleep mode
  if (OnSwitchPinStatus = LOW) {
  // enter sleep mode
  sleepNow();
  }
}


// sleep mode code
void sleepNow() {
  attachInterrupt(0,loop, RISING);  // set interrupt to on switch
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
  sleep_enable();
  digitalWrite(latchPin, LOW);  // turn off SOC gauge
  shiftOut(dataPin, clockPin, MSBFIRST, 0);
  digitalWrite(latchPin, HIGH);
  sleep_mode();  // enter sleep mode
  sleep_disable();  // resume code after exiting sleep mode
}


// interrupt to count amp hours used
ISR(TIMER1_COMPA_vect)
{
    CurrentRead = analogRead(CurrentPin);
    // Convert currentread to amps
    CurrentRead = (CurrentRead - 512) * .78125;
    // Convert to AH & add to total
    AHused = AHused + (CurrentRead * .001);
}
Here is a list of the components:


I've been using the charging protection for a few months with my plugin kit and it has worked great. I have just finished working on the discharge protection and haven't yet assembled the circuit.

Anyway, thanks for reading if you got this far. Its a lot to look at, but I'd really appreciate some feedback.

Attached Thumbnails
Click image for larger version

Name:	bom.jpg
Views:	12755
Size:	116.2 KB
ID:	10246  Click image for larger version

Name:	PHEV_BMS_schematic01.jpg
Views:	13073
Size:	88.1 KB
ID:	11088  
__________________
Current project: Heating the manual trans with engine coolant

Last edited by Daox; 02-20-2012 at 03:20 PM.. Reason: updates
  Reply With Quote
The Following 4 Users Say Thank You to Daox For This Useful Post:
Intrigued (07-21-2012), MPaulHolmes (02-08-2012), mrbigh (02-15-2012), sawickm (02-08-2012)
Alt Today
Popular topics

Other popular topics in this forum...

   
Old 02-08-2012, 07:42 AM   #2 (permalink)
Administrator
 
Daox's Avatar
 
Join Date: Dec 2007
Location: Germantown, WI
Posts: 10,090

CM400E - '81 Honda CM400E
90 day: 39.62 mpg (US)

Daox's Grey Prius - '04 Toyota Prius
Team Toyota
90 day: 38.47 mpg (US)

Daox's 04 Civic - '04 Honda Civic DX
90 day: 41.58 mpg (US)

Daox's Insight - '00 Honda Insight
90 day: 64.33 mpg (US)
Thanks: 1,611
Thanked 1,916 Times in 1,179 Posts
I added the bill of materials to the 1st post.
__________________
Current project: Heating the manual trans with engine coolant
  Reply With Quote
Old 02-20-2012, 10:42 PM   #3 (permalink)
ecomonkey
 
Join Date: Dec 2009
Location: middleburg fl
Posts: 239

silver clown - '02 toyota echo 2 door base
90 day: 47.16 mpg (US)

white ghost - '05 prius base
90 day: 51.61 mpg (US)
Thanks: 33
Thanked 29 Times in 20 Posts
doax that is impressive, i build microcontroller circuits and write code in assembly. if it works well and does not fail its a good design!. for thermal protection you probably already know that you could use negitive or positive temp coefficent thermisters and an op amp to trigger where ever you calibrate it. we use them on our lasertag vests charging systems. im interested in these kits for the pruis,,, i dont have one yet but i am eyeballing them, because of the avalibility of kits to up their mpg. my echo is getting long in the tooth at 199k. and 70 mpg is promised on some of these kits,
__________________
  Reply With Quote
Old 02-21-2012, 07:58 AM   #4 (permalink)
Administrator
 
Daox's Avatar
 
Join Date: Dec 2007
Location: Germantown, WI
Posts: 10,090

CM400E - '81 Honda CM400E
90 day: 39.62 mpg (US)

Daox's Grey Prius - '04 Toyota Prius
Team Toyota
90 day: 38.47 mpg (US)

Daox's 04 Civic - '04 Honda Civic DX
90 day: 41.58 mpg (US)

Daox's Insight - '00 Honda Insight
90 day: 64.33 mpg (US)
Thanks: 1,611
Thanked 1,916 Times in 1,179 Posts
Thanks for the idea moonmonkey. I've used lm35 temperature sensors on different arduino projects before. I think if I were going to use some for this project I'd go with a 1-wire type because you could have multiple sensors and I don't have a huge abundance of pins left if I want to keep doing more and more.
__________________
Current project: Heating the manual trans with engine coolant
  Reply With Quote
Old 02-25-2012, 11:48 PM   #5 (permalink)
ecomonkey
 
Join Date: Dec 2009
Location: middleburg fl
Posts: 239

silver clown - '02 toyota echo 2 door base
90 day: 47.16 mpg (US)

white ghost - '05 prius base
90 day: 51.61 mpg (US)
Thanks: 33
Thanked 29 Times in 20 Posts
doax the pic microcontroller is easy to learn and there is alot of code examples out there to do just about anything you want. the programmers are cheap and tech support ,,,fair. the 16f84 is the one everyone learns on . but i use the 16f877 for most of my stuff because it has 33 I/O that you can program to be any combanation of inputs and outputs, i dont know if you write in assembler but this chip is a risc (reduced instruction set) and has only around 33commands, and cost around $10.00 dollars,then you just need a few resistors,a crystal and a few caps. i have used these chips in some very complex machines, they are rock solid and easy to use once you get used to them.i will be happy to help if you want to switch over to them.im not that knowledgable about arudino, it was'nt out when i started with pic.
__________________
  Reply With Quote
Old 03-07-2012, 11:39 AM   #6 (permalink)
OMG... It's SkeeterB!!!
 
Join Date: Feb 2012
Location: Mississippi
Posts: 27
Thanks: 6
Thanked 3 Times in 3 Posts
Send a message via AIM to skeeterb Send a message via Yahoo to skeeterb Send a message via Skype™ to skeeterb
Quote:
Originally Posted by moonmonkey View Post
doax the pic microcontroller is easy to learn and there is alot of code examples out there to do just about anything you want. the programmers are cheap and tech support ,,,fair. the 16f84 is the one everyone learns on . but i use the 16f877 for most of my stuff because it has 33 I/O that you can program to be any combanation of inputs and outputs, i dont know if you write in assembler but this chip is a risc (reduced instruction set) and has only around 33commands, and cost around $10.00 dollars,then you just need a few resistors,a crystal and a few caps. i have used these chips in some very complex machines, they are rock solid and easy to use once you get used to them.i will be happy to help if you want to switch over to them.im not that knowledgable about arudino, it was'nt out when i started with pic.
I like to work with PIC uCs too, especially since I can speed the coding using a program called Flowcode to generate the code. The free version is pretty good even though it has a 4 macro 16 icon/macro limit. It won't generate code for the EEPROM or a few other devices. I've registered my copy so I have full use. You can also get free samples of the PIC uCs too at microchip. If you want to try using PICs, download the free versions of MPLAB and Flowcode and experiment. If you like them, you can start using them for your projects. I'm not really familiar with coding an arduino, but I would like to recommend PICs as a user of that line of uCs. I started using PICs by using assembly, but when I was introduced to Flowcode, I was hooked. If I can get enough money together, I hope I can start converting an ICE Car to an EV. User friendly BMS' are good to have, especially if it was created by a fellow EV user/fan.
__________________
This is the way the world ends,
This is the way the world ends,
This is the way the world ends,
Not with a Bang
But with a Belch
BUUUUUUURRRRRRRRRRPPPPPPPP

Last edited by skeeterb; 03-07-2012 at 11:50 AM..
  Reply With Quote
Old 06-24-2012, 05:08 PM   #7 (permalink)
Administrator
 
Daox's Avatar
 
Join Date: Dec 2007
Location: Germantown, WI
Posts: 10,090

CM400E - '81 Honda CM400E
90 day: 39.62 mpg (US)

Daox's Grey Prius - '04 Toyota Prius
Team Toyota
90 day: 38.47 mpg (US)

Daox's 04 Civic - '04 Honda Civic DX
90 day: 41.58 mpg (US)

Daox's Insight - '00 Honda Insight
90 day: 64.33 mpg (US)
Thanks: 1,611
Thanked 1,916 Times in 1,179 Posts
I've evaluated all the cells in my pack now, and I know all of their capacities. That means the batteries are ready to go back in the car. So, its back to working on the BMS system to ensure nothing else bad happens again.

This weekend I worked on tweaking the current sensor setup. Its still not perfect, but after a few tests it seems to be accurate enough that I won't be over-discharging anything.

I also worked on getting the SOC meter. I got it wired up and tweaked the code a bit to get everything working correctly. I even made a quick video to show how its working. I do have another bargraph on order that is linear instead of having LEDs side by side. We'll see what one I like when that one gets here.

__________________
Current project: Heating the manual trans with engine coolant
  Reply With Quote
Old 06-24-2012, 06:02 PM   #8 (permalink)
Drive less save more
 
ecomodded's Avatar
 
Join Date: Jul 2011
Location: Vancouver Island, Canada
Posts: 1,189

Dusty - '98 VOLKSWAGEN Beetle TDI
TEAM VW AUDI Group
90 day: 60.42 mpg (US)
Thanks: 134
Thanked 158 Times in 132 Posts
I like the bar graph your using, with its 1/8 drop off.
The circuity and electronics are foreign to me , but I know a good meter when i see it !

I think your onto a money maker, must be more then one model of hybrid that would benefit from your lithium BMS meter.

Maybe your not trying to make money with it, i see a lot of marketable talent here on ecomodder.

Sales Section here on ecomodder could do well..
__________________
Save gas
Ride a Mtn bike for errands exercise entertainment and outright fun
__________________




Last edited by ecomodded; 06-24-2012 at 06:10 PM..
  Reply With Quote
Old 06-24-2012, 06:08 PM   #9 (permalink)
Administrator
 
Daox's Avatar
 
Join Date: Dec 2007
Location: Germantown, WI
Posts: 10,090

CM400E - '81 Honda CM400E
90 day: 39.62 mpg (US)

Daox's Grey Prius - '04 Toyota Prius
Team Toyota
90 day: 38.47 mpg (US)

Daox's 04 Civic - '04 Honda Civic DX
90 day: 41.58 mpg (US)

Daox's Insight - '00 Honda Insight
90 day: 64.33 mpg (US)
Thanks: 1,611
Thanked 1,916 Times in 1,179 Posts
Thanks!

I have designed the BMS with the thought in mind that it could fairly easily be scaled and tweaked to be used in a full EV. I do have a future project in mind, but its on the back burner at the moment.

A money maker it will not be though. I'd really like to keep it as an open source project. The commercial BMS systems are fairly expensive and I haven't found a good alternative myself, so this is the route I am taking. Being open source also allows me to get help from others! I'm far from an expert, and I've already had a bunch of useful input from the guys here and local EV club. Its great to get useful criticism and feedback so it can be further improved upon.
__________________
Current project: Heating the manual trans with engine coolant
  Reply With Quote
Old 06-27-2012, 08:47 PM   #10 (permalink)
Administrator
 
Daox's Avatar
 
Join Date: Dec 2007
Location: Germantown, WI
Posts: 10,090

CM400E - '81 Honda CM400E
90 day: 39.62 mpg (US)

Daox's Grey Prius - '04 Toyota Prius
Team Toyota
90 day: 38.47 mpg (US)

Daox's 04 Civic - '04 Honda Civic DX
90 day: 41.58 mpg (US)

Daox's Insight - '00 Honda Insight
90 day: 64.33 mpg (US)
Thanks: 1,611
Thanked 1,916 Times in 1,179 Posts
I got the new bar graph and I think I'm liking it better. As you can see all the LEDs are in a line so its a bit more straight forward. The size of the two is identical. The only downside to using this graph is that it has 10 LEDs and my shift register only has 8 output pins so I can only drive 8 of the LEDs with it. There are many ways to deal with this, but the fact that you do have to deal with it is something to think about, especially if you want things to look real nice.


Attached Thumbnails
Click image for larger version

Name:	prius 004.JPG
Views:	12476
Size:	75.3 KB
ID:	11086  
__________________
Current project: Heating the manual trans with engine coolant
  Reply With Quote
Reply  Post New Thread


Tags
bms, lithium, open source, phev

Thread Tools




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