01-28-2012, 12:47 PM
|
#1 (permalink)
|
Administrator
Join Date: Dec 2007
Location: Germantown, WI
Posts: 11,203
Thanks: 2,501
Thanked 2,589 Times in 1,555 Posts
|
DIY lithium BMS help
For those who don't know, I have an enginer PHEV kit for my Prius. The BMS that came with it was a total piece of junk (it has since been improved upon), so I started to develop my own to stop it from killing the batteries.
The setup right now is relatively simple. There are a couple celllog8s devices monitoring the batteries voltage. The celllog keeps track of up to 8 lithium cells at once. It has a low and high voltage alarm as well as a voltage differential alarm that are user settable. The celllog also has an alarm port that activates a transistor when an alarm goes off.
I currently have a couple celllogs monitoring the 16 cells in the PHEV kit. Using the alarm ports, they are hooked up via optoisolators to an arduino that controls power to the charger. When the high voltage alarm is triggered on the celllog it sends the signal to the arduino to shut off the power to the charger. This works great for charging, but I'd like to expand the system to control when to turn off the PHEV kit from providing power to the car (protection from over discharging). I have tried using the low voltage alarm, but it is not that simple. With variance in voltage sag due to loading and temperature there isn't a good voltage to set and forget. Under EV acceleration the voltage will sag much lower than when you're just cruising for instance.
So, I am looking for help on how to enhance this system. I see no reason why this system can't be scaled to use on a full blown car and its also REALLY cheap to setup. Right now I'm looking at two different options.
1) Some smarter arduino programming on how to identify when a real low voltage alarm is happening vs a fake one. Something as simple as the alarm has to be going off for more than 20 seconds or something. Unfortunately there are some hills you may climb in EV mode that will trigger this.
2) Add a current sensor and keep track of Ah used. This would be a much more robust option I think. For example I am using 40Ah batteries in the PHEV kit. So I'd program it to power down after say 32Ah used. I know this can be done, I'm just not really sure how to do it.
3) ??? I'm open to suggestions!
|
|
|
Today
|
|
|
Other popular topics in this forum...
|
|
|
01-28-2012, 01:57 PM
|
#2 (permalink)
|
PaulH
Join Date: Feb 2008
Location: Maricopa, AZ (sort of. Actually outside of town)
Posts: 3,832
Thanks: 1,362
Thanked 1,202 Times in 765 Posts
|
Is there an Analog to digital converter channel available on your microcontroller? You could just stick the current carrying bar through something like this:
http://search.digikey.com/scripts/Dk...+300-s&x=0&y=0
(they have them with any current range you want)
The interface to the sensor is OUT, +5V, and GROUND. Zero current through the sensor means OUT is 2.5v. 300 amps gives an output of 2.5 + 0.625v. -300 amps gives an output of 2.5 - 0.625v.
Just feed the output into the available A/D channel, and read it in fixed intervals. Say 1kHz. Then when you read the current, you have used that amount of currrent * 0.001 seconds. Add it up in an accumulator variable. The variable will start back at zero when the power shuts off unless you save it though.
So, let's say you read a 10 bit value for the A/D result. 512 would mean zero current. 512 + 128 would mean 300 amps. Just save your total in a long INT.
Every 0.001 seconds do:
ampHrsRaw = (A_D_Result - 512) + ampHrsRaw
The units of ampHrsRaw are "A/D tick * millisecond". So, you have to wait until it gets to what corresponds to 32 amp*hours. 32 amp*hours converted to "A/D tick * millisecond" would be ...
32amp*hr*3600sec/hr*1000ms/sec*128ADTicks/300amp. Now once the units cancel, you get...
49,152,000. So...
if (ampHrsRaw >= 49152000)
OH NO!!! 32 AMP*HRS HAVE BEEN USED! DO SOMETHING!!!
Last edited by MPaulHolmes; 01-28-2012 at 02:48 PM..
|
|
|
The Following User Says Thank You to MPaulHolmes For This Useful Post:
|
|
01-28-2012, 03:43 PM
|
#3 (permalink)
|
Administrator
Join Date: Dec 2007
Location: Germantown, WI
Posts: 11,203
Thanks: 2,501
Thanked 2,589 Times in 1,555 Posts
|
Awesome Paul, thanks!
Yeah there is an analog to digital converter. I'll just have to figure out how to do readings at specific intervals.
|
|
|
01-28-2012, 04:04 PM
|
#4 (permalink)
|
PaulH
Join Date: Feb 2008
Location: Maricopa, AZ (sort of. Actually outside of town)
Posts: 3,832
Thanks: 1,362
Thanked 1,202 Times in 765 Posts
|
Is it an atmega168? or atmega328? I can post code for setting up a timer no problem!
|
|
|
01-28-2012, 05:17 PM
|
#5 (permalink)
|
Administrator
Join Date: Dec 2007
Location: Germantown, WI
Posts: 11,203
Thanks: 2,501
Thanked 2,589 Times in 1,555 Posts
|
I think I have both chips laying around that I can put into an arduino board. Right now I'm using a 168.
Posting code would be extremely helpful. Thanks Paul.
|
|
|
01-29-2012, 08:44 PM
|
#6 (permalink)
|
PaulH
Join Date: Feb 2008
Location: Maricopa, AZ (sort of. Actually outside of town)
Posts: 3,832
Thanks: 1,362
Thanked 1,202 Times in 765 Posts
|
Code:
#define FOSC 16000000
// timer 1 input capture ISR (1000 hertz)
SIGNAL(SIG_INPUT_CAPTURE1)
{
counter_1k++; // 1 KHz counter
}
// Now, somewhere down in main()...
// set up input capture 1 interrupt at 1000Hz
TCNT1 = 0; // load 16 bit counter 1
ICR1 = (long)F_OSC / 1000; // timer at 1000 Hz
TCCR1A = 0; // no output action on match
// let counter 1 run at fosc, reset to 0 at ICR1
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS10);
TIMSK1 = (1 << ICIE1); // enable input capture 1 interrupt
Just change FOSC to whatever frequency you are running at.
Last edited by MPaulHolmes; 01-29-2012 at 08:49 PM..
|
|
|
The Following User Says Thank You to MPaulHolmes For This Useful Post:
|
|
02-01-2012, 01:40 PM
|
#7 (permalink)
|
Administrator
Join Date: Dec 2007
Location: Germantown, WI
Posts: 11,203
Thanks: 2,501
Thanked 2,589 Times in 1,555 Posts
|
Thanks Paul. I'll have to tinker with that to understand it, but thats a great start!
|
|
|
02-01-2012, 04:35 PM
|
#8 (permalink)
|
EcoModding Apprentice
Join Date: Nov 2010
Location: Annapolis
Posts: 159
Thanks: 0
Thanked 32 Times in 27 Posts
|
We've recently been integrating our battery monitor system with the rest of the system, and it has been illuminating.
First the hardware. Our battery monitor is a modification of the STM32-based motor controller we built. The processor power is isolated with a DC-DC converter, talking to the CAN bus through a Si8421 digital isolator and standard CAN transceiver. Up to 12 cells are monitored per controller using the on-chip 12 bit A/D converter, with the remaining four channels used for temperature and charge current monitoring. We get a fresh sample of all channels every millisecond.
One of the things we discovered is that the cell voltages sag quite a bit while driving. We got a hint from the whole-pack voltmeter, but our high sample rate catches the extremes. Even with a freshly charged battery, the cell voltages will drop below the nominal shut-off voltage level (which is specified at zero load) during acceleration.
The high load sag combined with the discharge voltage curve being very flat makes it very difficult to use a whole-pack voltmeter to track discharge. You can't distinguish between the expected voltage sag and a nearly dead cell. And a stand-alone cell monitor can't tell if the voltage is sagging from load, or because the cell is mostly discharged.
You pretty much need a battery monitor that tracks the weakest cell. Better, a monitor that knows the discharge current and uses that to set the alarm voltage threshold. Ideally with a way to advise the motor controller to incrementally lower the power limit to match the weakest cell's capability.
|
|
|
02-01-2012, 05:03 PM
|
#9 (permalink)
|
Administrator
Join Date: Dec 2007
Location: Germantown, WI
Posts: 11,203
Thanks: 2,501
Thanked 2,589 Times in 1,555 Posts
|
That is basically what I have found as well. Voltage alone can not be used as a low charge indicator (works fine as a high charge indicator through). That is why I am planning measuring amp hours used for the low charge indicator. There will be a fairly large factor of safety built into the calculations so that the batteries can only hit ~80% DOD. They also aren't being fully charged either to increase cycle life. Thankfully I have excess capacity in this case and pushing the batteries to the limit isn't necessary.
With this method I don't see a reason to individually monitor each cell. The one thing my BMS system does not do is active balancing. The pack will be balanced at the bottom before it is installed into the car. In time I'm sure the cells will drift and another balance will be needed to restore proper performance. Time will tell how long this will take.
|
|
|
02-01-2012, 05:32 PM
|
#10 (permalink)
|
EcoModding Apprentice
Join Date: Nov 2010
Location: Annapolis
Posts: 159
Thanks: 0
Thanked 32 Times in 27 Posts
|
We also ruled out balancing until we are confident of the system reliability. And when/if we do add balancing, it will be likely be a low current, long-term balance. We won't try to complete the balance while charging, or even during a single post-charge cycle. We'll track the high and low cells during both charge and discharge, do an minor incremental balance and track the effect over multiple discharge cycles.
|
|
|
|