|Screenshot after 10 miles of driving with several drive phases visible and the batteries at rest.|
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.
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.
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.
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.
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 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.
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.
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)
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 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.
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.
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)
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):