• Howdy! we're looking for donations to finish custom knowledgebase software for this forum. Please see our Funding drive thread

A PIC based Battery Management System


Staff member
Dec 31, 2006
California Bay Area, USA
I've been thinking about this one for quite a while, so I decided to create a new thread to collect thoughts. I'm hoping FrankG, Beagle123 and dirty_d can (and anybody else) help in the code writing department.

A fully analog BMS like the one Gary and Bob are working on is great and gets the job done, but it uses quite a few parts. My thought was by using a PIC microprocessor, it might be possible to achieve the same function with fewer parts and hopefully less expense.

If the PIC can measure the voltages from each cell, then the under and over voltage set points could be adjusted in software, allowing flexibility in various types of cells used. You would also have the potential for all kinds of fancy display options.

There are a number of possible ways to implement a PIC based BMS. My original thought was to use a multi-channel MUX chip to sequentially measure the voltage on each cell in the string. Since the MUX chip can only pass something like 15v max (depending on the part used), it will be necessary to divide the voltages down to within the allowable range.

One way to simplify the divider would be to use one resistor on each cell tap and use a common resistor on the output of the MUX to form the other leg of the divider (cuts number of resistors needed).

A dual channel MUX could sample each cell's + and - terminals and output to a differential amplifier to make the voltage referenced to ground for the ADC in the PIC. If the divider ratio was something like 10:1, then a 48v pack would have a maximum voltage at the MUX of around 4.8 volts. If the differential amplifier has a gain of 10, then the output of the amp would be the exact voltage of each cell it is connected to, regardless of position in the string.

Here's a rough diagram of the MUX section. The differential amp part is not fully drawn.
MUX front end.jpg
Great to see you wade into the fray. The more options explored and fleshed out the better. The idea of having different set-points for end-of charge is exactly what Safe has been searching for in about 3 or 4 of his threads.

Question: With the PIC requiring divider circuits to measure voltage, how much skew can the 5% resistor tolerance introduce? Will this need 1% tolerance parts?
This is a great thread! I'm thinking about exactly the same setup! I'll be using my USB IO card for prototyping for now (same IO as most microcontrollers, 8 12 bit ADC, 2 DAC, lots of digital I/O).

I'm just only begining to learn circuits so please excuse (and please point out) many mistakes/bad terminology I'll use.

This mux has only signal range of -15V to 15V. In my search I could not find any muxes that can take more volts (other than 220V rated big expensive things). So in simple case it can only measure 3S lithium cells. Any way to work arround that?

Any reason why you picked dual supply mux (-15V/+15V) instead of single supply?

And a really clueless question - what are the reasons for resistors between the cells and the mux input pins? Spec says MUX has on resitance of 2kOhm, so 4V into that would give current of 2ma.

I think we're on the right track, but I know that we're overlooking the most important component--the thing that is able to measure an isolated voltage. I'm sure an electrical engineer would know what it is. Once we have the component that can measure an isolaated voltage, the rest should be easy.

Fetcher, how are you currently set-up with PICs? Frank suggested to me to try the picaxe microcontroller, and I must say its an excellent choice. And the best part is that its cheap. I'd suggest that you get these parts:

1) picaxe breadboard adapter ($4.95) get two.
2) picaxe 18x chip ($8) You could start with the 8 pin chip for $3.95 if you want.
3) You'll need the programming cable ($25) But this is a one time purchase. It can be used for all projects. Frank made his own.
3) LCD screen from ebay:


These components are excellent. The LCD is great because the professor guy who developed them made an interface using a PIC that allows this unit to accept simple character strings via the serial port. Normally LCD are a HUGE pain. But he's done the work for you. All you have to do is connect one wire to a PIN on the picaxe, and you're ready to display text. On the picaxe you jut run this command:

serout PIN_8, N2400, "?x1?y1Hello World"

And it will display "Hello World at x=1, y=1

There are numerous commands that start with a "?" like "?f" = clear screen etc.

The best thing about the picaxe is that all the chips have built in anlog to digital conversion inputs so you don't have to buy an ADC chip. The popular BS2 microprocessor that sells for $50 each doesn't even have that, but the $3.95 picaxe does. And that's what we need.

Another good reason to use this set-up is that Fraank and I are both using it.

The bottom line is that using these components I can have the whole thing done in an afternoon if we can figure out how to measure an isolated voltage.

The component could be similar to an opticoupler where the voltage is converted into light and the light is measured. Opticouplers offer a way to isolate the measured voltage from the circuit. Whatever this component is, I know its out there because its in my ampmeter on my bike and in my multi-meter.

Pictured below is my set-up. The cable from the computer plugs into that little jack. You could get this going in aabout 1 hour.



  • DSCN0838.JPG
    87.6 KB · Views: 18,910

The resistors would be part of a voltage divider resistor pair for each input to bring the real voltage down to within the +/-15V limit of the inputs. Each input would then be measuring a set fraction of the actual voltage--you could scale 150V to be read as 15V with a 1/10th divider pair.

---Disregard the above--- I missed the MUX interface between the PIC and the cells. Off to research what exactly that means...
Great thread. :)

I'll try to contribute without dominating it.

:idea: Has anyone considered including the resistors into the software model itself?

What I'm getting at is that rather than simply scaling everything down 10:1 you could eliminate the whole scaling function (the use of a differential amplifier) with resistors and then add the resistors back into the software model. Software is easier to write than circuits are to design (and it's all free once you have a platform to run on) so you would have a bare bones (dare I say "caveman" :wink: ) design of wire-resistor-wire as inputs.

In this circuit all the voltages between the lower resistors (R3, R4 and the bare wire) read 3.2 volts. When the voltage changes unequally the values no longer match the cells, but you could model that and know what's going on. It's a case where in an abstract model you can get the result because you know the relationship between things, but the voltage actually read isn't immediately useful. It's a perfect example of where software can achieve things that hardware has trouble with.


  • PIC Voltage.gif
    PIC Voltage.gif
    14.5 KB · Views: 29,262
safe said:
I'll try to contribute without dominating it.
That's what the cancel button is for. It's at the end opposite from the preview button. :lol:

EDIT: "Safe" could not restrain hisself, so this thread gets crapped up a bit. Readers can add "safe" to the foes list in the user control panel (upper right corner of the page ); his posts will not display unless the reader chooses to do so. :?
Thanks for the explanation, OneEye. So the way I understand it is:
- The voltage on my ADC will be V = Vcell * (input impedance / (Input impdance+Rinput)
- But what is the input impedance of an ADC? What is it for analog mux?

My labjack manual says:

The input bias current of the LabJack U12’s analog inputs varies from +70 to -94 microamps (μA). This is similar to an input impedance of about 100 kΩ, but because the current is nonzero at 0 volts, it is better to model the analog input as a current sink obeying the following rule:
Iin = 8.181*Va – 11.67 μA

How precise is the "about 100k"?

A few more options to get quick start with microcontrollers:


Both Atmega8 and PIC versions, all with at leat 8 ADC inputs and lots of digital IO. I haven't used those boards but plan to pick one up soon.
Don't thank me for explaining it, Tom, I am currently completely turned around about what fetcher suggested in his original post. So I may or may not have accurately described what was intended.

Sorry for throwing the thread into an early left turn.
OneEye said:
The resistors would be part of a voltage divider resistor pair for each input to bring the real voltage down to within the +/-15V limit of the inputs. Each input would then be measuring a set fraction of the actual voltage--you could scale 150V to be read as 15V with a 1/10th divider pair...
That's sort of what I was thinking, but I was just going to use a single resistor and then model everything with software. As long as the resistor values increased from low to high as you went from low to high voltage then the voltage drop would bring the result to something that was usable. However, as the cells became unequal they will tend to deviate based on the equations for how resistors behave. You just need to model that in software which should be pretty easy because the resistors (if accurately known) will behave in a predictable manner.

The result is a very, very simple interface with the cells (just a bunch of resistors) but a more complex mathematical model that abstracts what is going on. The software becomes the "brains" and the circuit is just a wire.

My guess is that electrical engineers will naturally think in terms of building circuits, but computer science people will naturally think in terms of theoretical models. Old habits die hard... :lol:

The irony about the thinking going on so far is that here you have this chip that can do ANYTHING in software and yet people seem to still desire to create logic in the circuits. To really go all the way with this stuff (to really be faithful to the concept of the chip) you need to seek a MINIMAL circuit design and eliminate everything possible. Let the software do the thinking... that's what it's for...
fechter -
The mux inputs (except the selected one) will float at +48V. Is there a cheap part that can handle that ? Alternatively is there a part that has an internal diode clamp at each input ?
The No-Brainer 12 Cell PIC BMS?

If you want more than 12 cells you need to use a MUX, but if you are okay with 36 volts then you could just plug the wires directly into the chip.



The PIC16C84 is a 18 pin microcontroller that has 1k of EEPROM program space, 36 bytes of RAM, and 64 bytes of EEPROM Data. It has a few other features, such as a timer, watchdog timer, and 13 pins of I/O.

Hmmmm... that only leaves a single output signal. :oops: Maybe you really need the MUX. (not enough inputs to go without one)

I'm hoping that we can do this thread in such a way that we can ALL learn about PIC's and what works and what doesn't. Sometimes presenting what doesn't work and WHY it doesn't is as valuable as getting the right answer.


I just found this:


I/O Ports

The I/O ports are one of the most intriguing sections of the PIC 16F84. There are a total of 13 I/O pins available on this chip. Port A is comprised of the five I/O pins, RA0 to RA4, shown in the pin-out in figure 9. Port B is an eight-bit port made up of pins RB0 to RB7. The amazing part about these ports is that they can be programmed to be either input or output ports, even "on the fly" during operation! Each pin can source 20 mA (max) so it can directly drive an LED. They can also sink a maximum of 25 mA2.

So I correct myself... for a 12 cell system you could in fact get away without a MUX and just go direct in and direct out. You will need to do some kind of switching, but it could be pretty simple. (more so than a MUX I suspect)

Holy Crap!

Check out this PIC:


33 I/O pins!

A Review of Analog to Digital Input

For many people this might be common knowledge, but for me (and many possible readers) this is new information. The chips translate a voltage from 0v to 5v into a digital value inside the chips memory. You can then use the software to manipulate that digital information and eventually produce some sort of useful output. Some info about this follows:


Might produce this on a computer:




It looks like the maxiumum number of Analog Inputs is only 8-Channels. Hmmm... maybe the MUX is again required. (but now I might have some idea why)
curious said:
fechter -
The mux inputs (except the selected one) will float at +48V. Is there a cheap part that can handle that ? Alternatively is there a part that has an internal diode clamp at each input ?

I think floating is good. No drain. The MUX chip shown and the one Beagle found say they can handle up to 70v open.

On the selected input, the resistors will divide the signal down to within the allowable range. If a differential amp is used, the gain of the amp can be tweaked to get an accurate reading. From there, just use 1% resistors on the divider part.
I've seen Pic micro controllers specified to run at 2v and up, how about putting a Pic at each cell and having an isolated data bus connect them all? I'm assuming that there's and easy way to isolate a bi-directional serial data bus. ( http://www.analog.com/icoupler some likely suspects here. http://www.analog.com/en/prod/0,2877,ADUM5241,00.html has one pin going each way and isolated POWER transfer. that's a nifty chip! )

I've also seen an isolated ADC over at Analog Devices. ( http://www.analog.com/en/prod/0,,AD7400,00.html is one suspect)

Safe found a differential amplifier that could handle +-300v common mode in one of his threads.

Ok, the ADUM5241 is blowing my mind! It should easily be able to power an 8-pin PIC on the isolated side and provide a bi-directional serial channel home to a central controller. This opens up a LOT of options for a scalable BMS.

Random ramblings,

P.S. Ak, just looked at the supply current needed for the ADUM5241's isolated power supply. 140mA current input is required for the maximum 10mA isolated output. Also current draw drops to "only" 104mA when no load is seen on the isolated power pin. Current draw is much better for the data only products. I guess getting power from the local cell is a better idea :p (huh looks like future versions will boost this dismal 8% efficency, so worth keeping tabs on)
awesome, id be glad to help out on this. this is pretty much the same as my lipo charger, except it will be a lot harder. on my charger the max voltage the pack would be is around 12V so i was able to just use an op-amp as a voltage difference amplifier on each cell and send the output to the ADC channels on the AVR. im not sure what the best way would be to do it with a high voltage pack, the resistors would work but i think it would introduce a lot of error for the cells higher up in the pack. there must be some sort of opto-isolator thats specifically made for this, converting a voltage relative to one ground(the cells negative terminal) to a different ground(whatever ground the PIC is on). but anyway, i think an AVR would be perfect for this, it seems like you get a lot of bang for the buck with them, the one i bought was only $4 and its runs up to 20Mhz and has three 8-bit I/O ports with 6 ADC channels and 3 PWM channels, i2c, UART, SPI and other stuff. they have models with more stuff and they are all about the same price. you don't need to buy any proprietary stuff to program it either, for the hardware just a DB25 male connector and 3 resistors and a socket for the AVR, for the software you can use their free development studio or use GCC compiled for an AVR target.

oops: never mind about the voltage divider part, your doing it different than i thought, that should work real nice :D
fechter said:
The MUX chip shown and the one Beagle found say they can handle up to 70v open.
Maxim part is quite expensive in small quantities. Which is the other one ?

What is the idea on the power supply for the whole thing ? The pack itself ? Or the BMS is going to be operational during charge/use only ?
i did some looking around for the opto-isolator solution, i read this datasheet(http://cp.literature.agilent.com/litweb/pdf/5989-2137EN.pdf), and shows ways to do what you want, it seems like it would be very accurate, but each cell would need one of those opto-isolators which are about $2 and an op-amp, so its not cheap. fechter i guess the voltage dividers are the best way to go, you could just use a pot on each cell and dial it in so everything is perfect, get all the inputs under 5V for the ADC then just do the math in software. any ADC error would be greatly exaggerated though, if you have 30 cells and the top cell gets resistively divided by 30 and the ADC is off by 5mV, in software your gonna have to multiply by 30 and be off by 150mV. it might all just average out though, its probably good enough.

oops: nevermind about the voltage divider, i see your doing it different than i thought, that should work nice :D
Sounds like a fun project. :)

I'm having a bit of trouble seeing how all this saves much in the way of parts, because so far this only seems to address the LVC portion of a BMS. The LVC circuit we're using only has three parts per channel, a voltage detector chip, a small current limit resistor and an opto. Doesn't get much simpler than that. :)

The big part of what makes up a BMS is the charge management portion. The cheap Chinese BMS boards mostly don't do much but RC-styled balancing, where the higher voltage cells are dragged down to the level of the lowest. What we are doing is using zener-like shunt regulators on each channel, so that each cell can get a full charge, independent of what the other cells are doing.

What would be interesting would be to have a PIC-based circuit that could significantly reduce what it would take to allow each cell get a full charge and do so using standard bulk chargers.

-- Gary
GGoodrum said:
What would be interesting would be to have a PIC-based circuit that could significantly reduce what it would take to allow each cell get a full charge and do so using standard bulk chargers.
I'm almost at the point where I'm thinking what's needed is a standard personal computer running software for everything. Just yank out the controller, balancer and low voltage cutoff and manage all of it with software. Place MOSFET's on each cell so that you have fine grained control everywhere. The PIC is sort of like taking baby steps towards this eventual goal. This sort of thing would also eliminate the need for a Cycle Analyst or Watts Up meter. For racing purposes you could also measure all sorts of performance related stuff to increase your track times. The upper limit is very high. The software development project would be rather large and would probably require 5-6 people six months to complete. You need million dollar budgets for this and it's the sort of thing that might "trickle down" from other racing activities elsewhere, in fact, it might be possible to buy much of the software for many of the necessary systems and then adapt the software to this application. It's going to take money, money, money.

Once the software was developed the price for the consumer would be good.

:arrow: But this is a diversion... and needs it's own thread. (which I'm not going to do right now)
Gary, I guess my idea was that the same voltage monitoring setup used on discharge would also work during charge, since the set points can be changed in software during charge. There still needs to be a shunt on each cell controlled by the processor.

There also might be a way around a bunch of the opto isolators, but you would still want some for interfacing to the controller.

If the cost of all the required parts is higher than the all-analog version, then it would be sort of pointless to pursue it further.

Another quite different topology would be to use a processor for each cell, then work out a way for communications between the cell processors and the charger and controller.
safe, the software side of this is very simple, even if you do all sorts of different monitoring, it would only take one person probably a week at most to code. and why get a pc involved? some computers don't even have a parallel port. a 20MHz PIC is plenty fast for this type of thing.
Fechter, I think the circuit you first posted would be ideal for using the charger show in this thread as an active BMS. If the primary is powered from the whole battery, that circuit will tent to discharge the stronger cells in a pack while charging the weaker cells in a pack. Allowing every last whatt hour to be used. Losses in the circuit would kill battery life if it was left running all the time, so the controller needs to know the voltage of each cell so it can turn on only when needed. For charging I'd add a relay to switch power input for the primary from the battery to a charge input. Simply hooking up the charger could do this.

I don't think the inputs to the MUX will be in any danger from having a resistor pulling it up to >36v. Most ICs have diodes on all the inputs that clamp the input to a value that's not (much) below ground or (much) above the supply. In this case there'd always be a small drain on the upper cells in a pack.