Car Battery Tester on Steroids

Draper make a car battery tester that is a resistive element, designed to draw 100A from a 12V car battery; a toggle switch; and an analog voltmeter. This is all housed in a case and has clamps to connect to the battery. The analog voltmeter is read by eye after the load is applied for 15s. Ultimately this is crying out to be hacked into something more interesting. That ‘something’ is now an automated system that monitors both current and voltage over time and can export results.

Battery Tester.png

My hacked device is based around an Atmel AT Mega 8 microcontroller. The device is designed to firstly draw power from the 12V car battery under test, and on command from a trigger switch, record a test within its EEPROM. When disconnected from the car battery and connected to a USB host, it senses that fact (via voltage levels) and powers itself instead from the USB bus and (by pretending to be a USB keyboard) now writes the EEPROM values back to that USB host as tab-separated number columns. This is after an initial preamble describing the system, the test conditions and the firmware version. This can be used to populate a spreadsheet, and the results graphed. This is an example of the results from a brand new battery, showing the initial voltage, the drop under load, the recovery over time, and (in red) the current load :

Test example

The data is produced by two inputs to the microcontroller’s ADC pins. Firstly a resister potential divider is used to map the ~12V battery voltage to something below the 5V regulated supply to the microcontroller (High resistance values should be used to limit current). Hence a voltage trace is obtained. Secondly a solid state current sensor (an ACS755LCB-130-PFF, Hall Effect High Current Sensor) is inserted into the current path. It produces a voltage proportional to current, with the voltage read by another ADC pin on the microcontroller.

Hardware Design

The tester I obtained second-hand from eBay had a defective toggle switch, and the obvious replacement to allow automated operation was a car starter solenoid since these are effectively relays designed for this very purpose. I obtained one second-hand on eBay, and (when driven by an intermediate FET) this was happily controlled by the microcontroller. This was a few years ago, and it now looks as though 100A solid state relays can be obtained for similar prices : this might be a better idea, as it would also avoid a safety problem that I had to design around (below). That said, the solenoid provides a nice audio indication of the test starting and stopping.

The device operates well within the capabilities of the AT Mega 8. There are outputs to four LEDs (some bicolour) for status information to the user. Inputs are either ADCs; or to sense the microswitch or the solenoid status. A socket to the ISP pins are provided to allow firmware update.

As noted above, the device emulates a USB keyboard and this is achieved using the V-USB Driver, with structures/ideas from Frank Zhao’s USB business card.

I had thought this would be simpler than the Ethernet connection I used on, for example, my clamp meter conversion, but other than having the advantage that USB provides power, it was just as complex. I had been thinking also that USB was more universal and does not require bespoke software on the reading machine (especially as I might need to loan the device to people), however now that I can implement a (rudimentary) HTTP server on the microcontroller it would have been far simpler to access the data via a web server and I would do this if I undertook the project again. Alternatively writing direct to a flash card is an option, and this would both obviate the need for a separate communication system and solve the problem of limited EEPROM storage (below).

In terms of space, the starter solenoid, FET and current sensor fit within the original envelope of the tester. The lower power components, although they could possibly have fitted as well, are kept away from the heat and large currents by mounting in an old floppy drive metal case, which happens to have the same width as the tester and is riveted to stand proud above an air-gap atop the case. The whole is robust enough to live in the garage.

Software Design

The microcontroler is programmed in C, and primarily operates as a finite state machine moving from pre-test to test etc on command or timer. Overlaying that is a regular timed interrupt (10Hz) to service the LEDs etc. Some of the LED behaviour (e.g. mark-space flicker) is designed to minimise the power drain on the USB (theoretically only 100mA is available and, while the microcontroller uses very little, four LEDs can eat into that)

The primary design constraint is the size of the EEPROM into which the data is stored (512 bytes). Although the AT Mega 8 has 2kB of SRAM, the operation mode for this device has it powered down between connection with the battery under test and re-energised (perhaps days or hours later) to connect to a computer. There are several trade-offs possible – the sample rate for instance varies for the pre-test, test, and recovery phases deliberately to balance maximum information at interesting times with sample period length. Only 8 bit data is stored, and the voltage is scaled before storage to maximise resolution, based on an assumption of allowable values. The firmware had to be changed once I discovered it was not safe to assume that a new battery would not exceed 12.5V unloaded.

During the actual test period, the device measures current as well as voltage. As there are spare ADC lines, I also recorded the voltage across the heating element during this period (i.e. excluding any voltage drop across the solenoid) at the expense of the need for some more storage, but this turned out to not differ significantly from the full battery voltage.


There are several safety issues, in addition to those already inherent in the device and working around car batteries. Notably, as a 1kW heater the device could burn people or potentially start fires. However adding an element of software control brings new problems.

I designed the main safety feature as follows. The test is initiated by closing and holding a microswitch. The microcontroller will terminate the load test after 15s, but for safety it must also terminate if the microswitch is released sooner. The important safety element of the design was to ensure that these were independent systems : it would be no use releasing the switch if this merely told the microcontroller to stop as this would leave the safety problem in software and not create an independent system. However it was also necessary for the initial press on the switch to tell the microcontroller to start; and for release to be sensed by the microcontroller so that it would not reapply the current if the switch reconnected. The solution was to tie the FET gate to 12V via a 10k resistor. The microswitch then connects the gate to a lower voltage derived from a pin on the microcontroller and potentially overpowers the first resistor, but with the microswitch open, the microcontroller gets no vote. Initially this pin on the microcontroller is set to be an input, without an internal pull up. Hence it senses when the microswitch operates, but the FET is not activated. The microcontroller switches the pin to be an output, but leaves it high (5V) which still does not activate the FET. The recording cycle starts, and at the appropriate point the pin is driven low, activating the FET. The solenoid has a convenient 12V output when activated, allowing a LED to indicate the test is underway, and a separate input on the microcontroller to sense this fact. Since releasing the microswitch will unilaterally close the FET, this second sense input allows the microcontroller to cancel the cycle (preventing restart) in this abort condition. Altogether this should ensure the device can always be stopped safely without ever requiring the clamps to be released under load with the associated spark hazard.

A significant safety issue is that, while the original metal box is insulated from both battery poles, the use of a metal starter solenoid whose case was connected to its earth made it necessary to earth the tester’s metal box (as the solenoid was too large to be isolated away from the box, indeed it required some metal cutting to fit). This increases the risk that the positive pole might short to earth; but also has the particular problem that if used to test a battery in a car with a positive earth (unusual, but not unknown) there would be a great risk that the tester case would touch bodywork and short. The solution was simply to only connect the case to earth via a fuse of high enough value to allow the solenoid to operate, but low enough to blow otherwise. 10A was suitable.

Possibly unnecessarily, but I protected every microcontroller input with a tranzorb spike suppressor of 4.7V. They are cheap, and it was not clear how switching 100A in close proximity would affect the controller. A 15V transorb protects the whole device (in parallel across the 12V input), as in series does a 1A blade fuse and a diode to protect against reversed connections. Despite all this, I believe it is wise to enforce a prohibition about connecting the device to a computer while the test is on going, relying instead on storage.


The functionality of the machine is probably fairly clear from the instructions now printed on the faceplate (below) and the graph of outputs.



Hacking a Digital Photo Frame as a World Clock

By exploiting these ideas I hacked a Kitvision digital picture frame to make it into a Daylight Clock.

By showing a pre-existing map image and cutting the RGB signal at the right moments (using code derived from Peter Duffett-Smith’s Practical Astronomy with your Calculator) you get the following (which looks better than in the photograph) :


The trick is to do the calculation during the flyback period, and use interrupts to do the time critical cutting of the picture.  In addition to the Digital Picture Frame, the project uses just two ICs : an ATMega328 clocked at 16MHz (mainly needing the 32k of program space for the calculation of the sunset/terminator line) and a video switch chip (analog multiplexer) 74HC4053.  The AT Mega has no trouble keeping up – the quantisation of the jagged terminator line is however due to the timing fidelity driven by the clock.

The result can be compared with an online solution.  Note that the time shown in the picture was added by the camera and is BST (GMT+1).

Essentially the Photo Frame shows a map of the world and the ATMega decides which parts should be dark and light and controls the analog multiplexer to switch between the frame’s picture and black. Serendipitous stray coupling between the signals gives the ‘moonlight’ effect of the dark!

The frame used was a Kitvision. Models DPF7SIK or DPF7BKK (respectively Silver and Black) are 7 inch digital photograph frames with 480 x 234 pixel displays. Depending on the model they can access 8MB or 20MB files, with SD/MMC/MS CARD and USB interfaces.

Although all sharing the above model numbers, the internal components differ. Notably certain models (all of those operating at 5V that I have bought) have convenient pads on the circuit boards allowing video signals to be extracted. The one model with a 12V supply was entirely different internally, with no easy access to the signals. Externally the 12V model is distinguished by 4 buttons on the back, rather than 6 buttons on the top and is also the only model to allow the 20MB files.

In addition to convenient access, 5V is of course also convenient to link to TTL logic and to provide power for a microcontroller. Although the three 5V DPF7xxK that I have bought all have different display models, the circuit board is common. Although one of the three also had a different display ribbon connector (while the other two were physically and electrically interchangeable), the circuit board is common – with solder pads for either ribbon, the other being left unconnected.  The circuit board from the rear looks like:


All pads are visible, although the +5V supply label is just out of shot – the pad is to the top left of the ribbon connector. Those of interest are :

Pad Signal Wire Description
5VP +5V Purple +5V
GND 0V Black Ground
VR Red Red Analog RGB – RED
VG Green Green Analog RGB – GREEN
VB Blue Blue Analog RGB – BLUE
VCOM RGB common Brown Square wave to provide common level for RGB signals (presumably zero DC offset)
CLK Clock Grey Pixel clock ~10MHz square wave
STV Start Vertical Orange Pulses before 1st display line, at about 55Hz
CKV Vertical clock Yellow Pulse at new horizontal line, about 15.6kHz
OEV or STH? Output enable vertical White Returns screen to default in interval – allows DC to stabilise.

The image below shows the connections to the pads on the rear (left hand side) and the front (right hand side).  On the front, the RGB connections are made to one end of a SMD capacitor’s pad after the capacitor was removed (achieved by snipping with pliers).  The whole is later held in place with epoxy.  Effectively the 4053 switch replaces the capacitor.


By using an ATMega328, one can connect the STV pulse direct to the INT0 input (PD2) which will trigger an interrupt routine whenever the display is about to refresh (rising pulse).  As can be seen, the routine can set the display row number to zero, and also rely on the signal to increment an accurate clock (JulianFract is a time variable which runs from 0.0 to 1.0 over 24 hours).  STVHZ is about 60Hz. This means there is ~17ms for all horizontal lines to be painted – which would allow 262 lines at 64μs per line (see below). The display has only 232 lines allowing some spare time (~2ms).

STV pulse width (while high) is measured at ~6.4μs; the manual seems to have 64μs. Curious.

AVR C Interrupt code for the vertical pulse is:

ISR(INT0_vect) // Highest priority. Used for STV - Vertical start pulse
// STV measured at ~6.4 us width high pulse approx every 17ms i.e. 60Hz
// STV line is ORANGE and connected to INT0 - PD2 on Atmega8/328
row=0; // Measured at 1.75us at 16MHz

The CKV pulse can be connected to INT1 and will trigger whenever a new row is about to start. The CKV signal looks like :


CKV is low for about 52μs, during which there are 480 pixels of about 94ns each (48μs total). CKV is high for ~12μs, during which there is ‘flyback’.  Hence the period is about 64μs, i.e. 15,625Hz.

The signal can be used to control what we display. In this example the idea is that any given row will display either some day, followed by night, followed by day – or the reverse (Night-Day-Night); with special cases all day or all night.

We have previously (outside the interrupt) calculated two array of values, two values for each row. One signifies the point at which darkness should start, and the other the point at which the day should start. Whichever is smaller dictates the starting point – i.e. to draw day-night-day specify the -night-day part which implies the initial day- part.

VCOM looks like this (the even square wave) and switches polarity at every STH pulse (i.e. for alternate rows) as shown.


The AVR C code for processing rows is:

ISR(INT1_vect) // Second priority. Used for CKV - New row
uint8_t i,t3;
// CKV measured as 3V p2p. Square wave with approx 1:4 mark to space
// Measured 12us mark; 52 us space, 64us period = 15.6kHz
// CKV line is YELLOW and connected to INT1 - PD1 on Atmega8/328

// Original picture shows when PORTC 0..2 are HIGH

// Note that it is quicker to use PORTC = 0x07 and PORT C = 0;
// than PORTC |= (0x07) and PORT C &= ~(0x07)
// Logical to do this because we know we're not using the rest of PORT C
// and timing is crucial


t1=t1s[row]; // Copy to fixed variable to avoid repeating row index
t2=t2s[row]; // calculation – consistent speed

// Use -Os for this speed

if (t1 < t2) // Day-Night-Day
if ((t1+1) == t2) // Immediate Day
t3 = t2 - t1;

for (i=1;i<t1;i++) __asm("nop"); // Delay
for (i=1;i<t3;i++) __asm("nop"); // Delay

[Similar code for Night-Day-Night]

I also got the extra code to display eclipse shadow calculations working on a PC but was having trouble shoe-horning that into the AT Mega’s 32k code limit, so that remains a work in progress.