Brian's Website > Car Projects > Toyota MR2 EV > EV Electronics >

Battery Monitoring System

Screenshot about 5 miles into a drive, showing drive phases recorded so far and voltage fluctuations on the batteries
Screenshot about 5 miles into a drive, showing drive phases recorded so far and voltage fluctuations on the batteries
Screenshot after 10 miles of driving with several drive phases visible and the batteries at rest.
Screenshot after 10 miles of driving with several drive phases visible and the batteries at rest.
Post-processed analysis of 5 batteries showing a charging phase, 3 drives that totalled 25 miles, and the recharge at the end. (this data is not from the same drive as the above screenshots).  The X-axis is in seconds, and the Y-axis in volts.
Post-processed analysis of 5 batteries showing a charging phase, 3 drives that totalled 25 miles, and the recharge at the end. (this data is not from the same drive as the above screenshots). The X-axis is in seconds, and the Y-axis in volts.
A detail of the third drive and the 2nd charging phase from the above chart.
A detail of the third drive and the 2nd charging phase from the above chart.

This page details the work I did to build a computerized battery monitoring system for my car. This system graphs detailed charge and discharge voltage profiles on every battery in the car in real time, and records data for further offline analysis.

The system consists of a microcontroller driven voltage transducer attached to each battery. Each of these wirelessly transmits data back to the central computer which processes and displays the data on an LCD display on my dashboard.

Architectural overview

There are 3 main components of the battery monitoring system on my Toyota MR2 EV. These are the central computer, two RF receiver units (one for the front of the car and, one for the back), and 21 voltage transducers (one per battery). The voltage transducers periodically sample the voltage of their battery and transmit the data back to the central computer via the RF receiver units. A modified Linux OS and custom software on the central computer perform the data processing, display and logging functions.


Three voltage transducers
Three voltage transducers

A voltage transducer in its housing.  Most of my transducers ended up installed in pairs, two to a housing but this is a single unit.
A voltage transducer in its housing. Most of my transducers ended up installed in pairs, two to a housing but this is a single unit.

Voltage Transducers

A voltage transducer is attached to each battery to independently measure its voltage. Each of these periodically samples voltage and reports it back to the central computer. They consist of a microcontroller driven circuit coupled to an RF transmitter module. The whole circuit fits on a circuit board about 1.25" by 2" in size. I used 1" ABS pipe couplings for enclosures as these are a compact, cheap, and sturdy. The transducers are parasitically powered (they run from the battery they are sampling) and they can measure battery voltage from 8V down to 4V with an accuracy of 0.01V and will raise a warning when battery voltage is out of measurable range. Current draw from the transducers averages 2mA, so running down my 200Ah batteries is not an issue.

Voltage Transducer Hardware

Each transducer is a very simple circuit. The sum total component prices at retail, small-quantity prices for each transducer was around twenty dollars. The circuit is designed to provide accurate voltage readings for the entire charge/discharge life cycle of a 6V lead acid battery, where it is realistic to see voltages anywhere from 4V up to 8V.

The microcontroller in each voltage transducer is an 8-pin PIC12F683, containing a 20Mhz-capable cpu core, a 10-bit analog-to-digital converter, timers, a configurable internal clock source, and other periphrial toys. I wrote a couple hundred lines of assembly code (discussed later) to drive the circuit.

The transmitter module is a Holy Stone MO-SAWR-A 315Mhz 2400-baud "virtual wire" unit, meaning in theory whatever digital state I put into the transmitter input end shows up on the receiver output end. It does, within limits. I had to write the software in the microcontrollers that generates the RS232-encoded data that goes out over the transmitter to compensate for distortion that is introduced by the transmitter/receiver pair and to prevent steady-state signals (no data) from causing the receiver to output continouous random digital noise.

Each transmitter and receiver were sold only as matched pairs. They are all on the same frequency, so I am using many transmitters and only a couple of receivers. Yes, it works, though some transmitters work better than others against a given receiver, but the overall performance is good enough. (normally each receiver is tuned to match its paired non-adjustable transmitter).

The remainder of the components includes an LM2391Z-5.0 voltage regulator which provides regulated power to the entire circuit, a LM336-2.5 voltage reference, which is there to allow accurate voltage sampling when the battery voltage drops under 5V (when regulator power is no longer constant) and various capacitors, resistors and other glue components to make it all work together. The raw battery voltage input bypasses the 5V regulator, and is instead run through a resistor/capacitor network to filter and drop its voltage to a range between 0 and 2.5 volts to be on a scale where it can be compared against the precision voltage reference value of 2.5V.

The circuit board is a Pololu PCB02A prototyping board; their smallest size. It has footprint for an 8-pin microcontroller, voltage regulator and filter capacitors, clock components, a DB9 socket, and a small prototyping area.

Voltage Transducer Software

Most of the complexity in the voltage transducers is in the software on the PIC microcontrollers; not in the hardware. This is a good thing. The software does the sampling of the battery voltage, digitizing the signal, adding metadata including battery identification, running count of samples, checksum, etc. All of this is converted to specially distorted RS232 packet (to cancel distortion in the transmitter/receiver) and transmitted via RF. The software turns off the transmitter and voltage reference when not in use to save power and allow other transducer units a chance to transmit. Finally, the software uses low-power sleep mode for pseudo-random intervals between sampling and transmitting cycles. And transmits voltage samples with a frequency that is roughly proportional to how fast the voltage is changing.

If you are wondering how I synchronize all these transmitters to avoid having them step on each other, the answer is I don't. Each packet is small enough (about 100 bits) that the time it takes to fire up a transmitter and allow it to stabilize, transmit the packet, and shut off the transmitter is very small, so the probability of two transmitters stepping on each other is fairly low, even with a dozen transmitters running, as long as the interval between transmissions on each transducer is fairly long (on average, about 30 seconds) and transmitting intervals are randomized. Collisions will happen, but the recieving end sorts them out. The receiving software can detect malformed packets and bad checksums, and simply throws away this data.

In-Car Performance

In a word, fine. As of writing this I have just gotten the entire system working installed in the car for the first time, but ten of the transducers have been in the car for weeks and each is providing continous, sane, accurate data. Controller and charging noise don't seem to bother them. There is obvious voltage ripple during the charging cycle, but that is expected as the charger output is going to be a bit noisy. The ripple is smaller than 0.1V.

The only issue which I was well aware of given my design is that the sampling interval on each transducer is slow enough, and the random sample intervals are such that during driving you don't see every twitch of each battery voltage. However each battery voltage trend is plainly visible over the course of a drive, as is each battery's recharge voltage profile, and this is exactly what I wanted to see.


An RF to RS232-over-USB converter
An RF to RS232-over-USB converter

RF receivers

The RF receivers are very simple compared to the voltage transducers. They simply convert over-the-air signals from the transducers and turn it into an RS232 data stream. A receiver unit is simply a Holy Stone MO_SAWR-A 315Mhz receiver unit interfaced to an off-the-shelf RS232-to-USB converter (stripped of its plastic sheathing). The USB bus provides a convenient way to add as many reciever units as I need, and provides the 5V necessary to run them.

Like the voltage transducers, each receiver is mounted in a piece of ABS plumbing for a sturdy, compact enclosure. One receiver is located in the front of the car and supports 7 transducers, the other is located in the back and supports 14 transducers.


Compaq Evo T30, stripped down
Compaq Evo T30, stripped down

Central Computer

I am using a Compaq Evo T30 for my central computer. This was originally a 'Thin Client' or Windows NT terminal. It is a small, fully self contained 586-class computer that is about the size of a Websters's Dictionary. It has PCMCIA, SVGA, one PS/2 input (kb or mouse), one RS232 and one LPT port, ethernet, sound, and four USB slots. It boots from an onboard 128MB flash drive. There are no fans or other moving parts.

The Evo is not a hot rod (300Mhz CPU core) but it can run a modern Linux OS. It was a bit of a challenge initially getting the Evo to run Linux, but I got things to the point where the 2.6 series Linux kernel and its modified initramfs live on the 128M flash, and the root filesystem is on a 4GB card in the PCMCIA slot. Getting linux onto the Evo is documented (poorly, needs updating) on my Hacking an Evo T30 page.

The operating system (Debian Etch) is basically stock, except with some tweaks to make it happier running on a solid state disk. Things like reducing the frequency of writes to disk, setting sync options on the filesystems, and putting /var and /tmp on a ramdisk. It takes quite a while to boot all the way up to X windows, but once up and running it does fine considering the CPU speed. (Note: DSL boots very fast on the same machine, but was very annoying to try to customize which is why I went to Debian)


Dual Source (AC / DC) power supply for the Evo
Dual Source (AC / DC) power supply for the Evo

Computer Power supply

The power supply for the CPU is external. It is a Meanwell S-60-12 switching power supply with single 12V, 5A output from Fry's electronics. I added some additional input noise filtering and circuitry to make it use 110VAC when it is available, but switch to pack voltage (126VDC) when unplugged. I chose this power supply because (like most switching power supplies) it can run off of AC or DC, and it would function under load on DC input voltage of less than 80V. It needs this ability to run the computer during times of extreme voltage sag. It seemed better to use a dedicated supply than to try and run the computer of the car's normal 12V electrical system for various reasons. The whole getup is stuffed in the gutted husk of an ATX power supply.

The power supply for the LCD display is what came with it. It hooks directly into the car's primary 12V system, meaning the display shuts off when the car is turned off. Aside from some noise filtering, there is nothing special here.


The LCD Display up and running
The LCD Display up and running

LCD display

The LCD display is a 7" diagonal Lilliput EBY701 touch screen with 800x480 native resolution. I mounted it on the center console of the car down fairly low to make it fairly discreet. The display comes with VGA cabling. I will eventually get the touch screen capability working as well, hopefully its not too challenging.

Keyboard and mouse

The monitoring system will run with no keyboard or mouse present, but I do keep a wireless USB keyboard/mouse combination unit in the car. I keep it behind the passenger seat when not being used. It is sold as a Windows XP Media edition accessory but it is really just a standard USB keyboard and mouse with a wireless interface. The "mouse" is a thumb stick which works well in the environment of a car. It works seamlessly with Linux.

Display and Logging Software

Hack alert!

the software running to receive, collate, log, and display battery voltage is all written in perl. It is set up to automatically start at bootup. There are two main components to the software. These are a receiver daemon process, and a graphical display application.

The receiver process forks a listener thread for each USB receiver device detected, and it handles telemetry coming in from each one. Received data is validated via checksum, and then stored in a persistent log file on a USB stick. The same data is also broadcast via UDP in real time, to be picked up by the graphical display application.

The graphical display software gets battery telemetry data via UDP from the receiver process. It uses this information to construct three primary data fields. The first field is a "graphic equalizer" style display where each column shows the most recent voltage and the "envelope" of recent voltage data for that battery. The bars are color coded to indicate strong, moderate, and weak voltages. The second field of the graphical display is a historical voltage profile for the battery pack as a whole. It allows you to easily see the overall "envelope" of battery voltages sampled for the entire pack in a running chart with one hour of historical data. The ability to scroll back in time on this display and change its time scale will come soon. Like the individual bar graphs, color changes to indicate strong, moderate, or weak battery voltage. This section of the display allows you to easily see the pack discharging as you drive, and see how widely voltage varies on the batteries with time. The final field of the graphical display shows uptime and pack state of charge (based on voltage only for now)

Data Analysis

The above two charts are some early telemetry (only 5 batteries attached) from my monitoring system, post-processed using the Gnumeric spreadsheet to show about 36 hours worth of data. The second chart is a detail from timestamp 80000 to 110000 of the first chart. The data shows a charging cycle, three drives during the next day (home to work, work to SEVA meeting, and SEVA meeting to home). After arriving home, It charges back up over the next night. The Y-Axis is Volts, and the X-Axis is seconds, relative to when I started the analysis.

Several interesting and educational things are clearly visible in the data. (In no particular order):

  • You can quite obviously see the battery voltages going down during use: After the first charge completes, the batteries settle down to an open circuit voltage a little over 6.5 volts. The first drive (about 8 miles) knocks them down to about 6.4 volts. The second drive, 9 hours later, (about 5 miles) takes them down to 6.35 volts or so. Four hours after that, I drive the "hypotenuse" leg of 12 miles home. At the end of the day, the batteries are starting to settle out at open circuit voltages of 6.2 volts or so each when I put it on the charger.
  • During charging, the battery voltage increases slowly until the batteries are nearly charged. As the batteries approach full charge, the per-battery voltage approaches 8 volts. This is also when they start gassing. At a point near the top of each spike, my Russco 24-120 charger switches from constant current to constant voltage charging. At this point, the rise in voltages slows down and the individual battery voltages diverge noticeably during this final stage of charging. I am attributing this to differences in the internal chemistry and capacity of the batteries. It is clear the points at which charging ends; the voltage drops off very quickly to below 7 volts, and then over the course of an hour or so settles down to about 6.5 volts as the surface charge dissipates.

  • I am actually quite impressed by how well the individual batteries track each other in voltage during charging, driving, and during quiet periods. The only time a noticeable variation appears is during the constant-voltage stage of charging. These batteries are still fairly "young" however with only 10 months of use and about 3000 miles.

  • The driving shown on this chart totals about 25 miles. It took about 5.5 hours to recharge from this drive, meaning I can recharge at the rate of about 4 to 5 miles of driving for each hour charging.
  • During driving, Individual battery voltages swing from over 6 volts while under no load to under 5.5 volts when accelerating and climbing hills. This makes sense of course, battery voltage will sag under load.
  • During the drives, (most evident on the third drive) the peak battery voltages drop off quickly as I drive. Battery voltage recovers by about 0.1 volts once the batteries are given a chance to rest for a few minutes. This open circuit voltage is what the manufacturers recommend to use to determine state of charge.
  • For This drive, if my average open circuit voltage after the third drive was about 6.25 volts (before I plugged in) then according to Trojan Battery's online information at http://www.trojanbattery.com/BatteryMaintenance/Testing.aspx I still had SOC (State of Charge) of about 70%. If this was a 25 mile drive, and the minimum safe SOC is 20%, or an 80% DOD (Depth of Discharge) then I see a useful range under these real driving conditons (mostly flat but a couple moderate hills and 50MPH, in this case) about 50 miles.
  • As the batteries discharge, the "valleys" (low voltage samples seen under load) get lower and lower. This would be much more pronounced on a longer drive as the batteries will sag much more when their SOC gets weaker.
  • As for the performance of the voltage transducers, there are 3 samples that I consider spurious in this data. They show up as blips considerably off (2 up, one WAAAY down) from the rest of the samples. They all occurred during charging when everything is noisier, and interestingly all three bad samples came from the same transducer, which is the prototype unit. I have no idea whether that has anything to do with it or not, but it is interesting. Of course there is enough fluctuation in voltages during driving that it is hard to pick out an abnormal sample there, or at least an abnormally low one.