Troubleshoot your car battery with ATtiny

Last winter I experienced some problems with my car battery. I knew that it was about time to replace it so off I went to buy a new one. This fact reminded me of an old article about a car battery/charging system diagnostics kit I had seen in one of those 1980s electronics magazines.
Troubleshoot your car battery with ATtiny
That magazine’s battery monitor relied on an IC that had several analog comparators arranged in a way similar to the ones in the old LM3914. This made me think about designing a more up to date battery monitor with today’s microcontrollers in mind which could use a low LED/resistor count and a reduced PCB size and possibly fit inside an empty 1oz Tic-Tac box.

I had originally envisioned building this battery monitor around Microchip’s PIC12F675. However, after reading several instructables on microcontrollers I realized that everybody seemed to prefer Arduino. I concluded that it was about time to get my feet wet in this family of microcontrollers.

After reading this instructable, I also realized it was possible to use Arduino and get a controller with the size needed for this project.

I hope you enjoy it as much as I did putting it all together.

Step 1: Theory of Operation

Theory of Operation

The operation of this battery monitor relies on what the battery as a voltage source “sees” as a load. Using basic electric circuit theory we have:

Vbatt = Vd + (R1 + R2)•I ……………………….(1)

Vadc = R2•I ………………………………………(2)

Vbatt = Battery voltage
Vd = Silicon diode forward voltage drop
Vadc = Voltage that goes to ATtiny 13’s Analog to Digital Converter
I = current
R1 and R2 are the resistors used in the voltage divider.

From (2):

Vadc
I = ———
R2

Substituting in (1)

Vadc
Vbatt = Vd + (R1 + R2) ————
R2

Therefore:
R2
Vadc = (Vbatt –Vd) —————– …………..……(3)
( R1 + R2 )

Which is the formula used to calculate voltage seen by ADC.

Step 2: Schematic

Battery voltage gets into the battery monitor through connector J1. Diode D1 is used to protect the entire circuit against accidental battery polarity reversal in case you decide to test the battery directly across its terminals in the engine compartment. Should you connect the test alligator clips reversed, nothing will happen.

IC2 is a +5V low dropout voltage regulator. Its input voltage range –with a 100mA load- varies between 5.4V up to its absolute maximum of 30V. I admit that for this battery monitor a 78L05 +5V voltage regulator would have been more than enough, however, I had no 78L05s and several LP2950CZA-5.0 kicking around in my junk box.  Capacitors C1 and C2 (22uF and 1uF) are voltage regulator’s input and output filters. If you want to use pin-compatible 78L05 voltage regulator instead, use a 10uF capacitor as C2.

The battery voltage feeds both, the voltage regulator and the ADC input circuit to ATtiny through a voltage divider formed by a 10K resistor and a 3.3K resistor marked as R1 and R2 respectively. This voltage divider is used to reduce battery voltage to a safe input voltage range between 0V and +5V for ATtiny’s analog input. This voltage divider allows a maximum car battery voltage of 20.8V for this input voltage range. In order to smooth out this analog input voltage, a 10uF (C3) is used to reduce noise.

The visual output to the user is shown by means of three LEDs. A Red LED (LED3) shows either too low a voltage or a dangerous overvoltage. A Yellow LED (LED2) shows a moderate low voltage and the green LED (LED1) shows good voltage and safe charging voltage. Each LED comes with its respective current limiter 330 Ohm resistors, R3, R4 and R5. Resistors R6 and R7 at 10K each are pull up resistors for unused inputs.

Step 3: Software

The software was written based on the hints given by Eric-the-car-guy in this excellent video. He didn’t mention the voltage at which a battery can be considered bad. However, my own car’s service manual stated that while cranking the engine, voltage should not get lower than 9.6V. If it does, then battery should be replaced which seems to be about right for most car batteries.

This sketch is very simple, just a series of consecutive IF instructions to compare voltage read through ADC3 with some predefined values. If you follow the code closely, you’ll see that the values shown in the Theory of Operation slide show in Step 1 are the same values used in the different IF instructions to decide which LED should come on.

To create the blinking effect on LEDs whenever voltages are higher than 13.1V, a counter is increased by one on every pass through that portion of the code. Before the code loops back to read ADC3 again, execution is delayed 100 milliseconds. IF instructions turn LEDs on whenever the pass counter is below 6 and turn LEDs off whenever counter is between 6 and 11. Once counter reaches 11, the counter is reset to zero to repeat the cycle.

ADC3 input is used to read the analog voltage coming from the voltage divider. By the way, ADC0 had been the first choice as this project’s analog input, however, when voltage coming from the battery was a bit lower than 8.7V all three LEDs would go out.  This didn’t seem right as I had used a low-dropout voltage regulator. After doing some more research on the web I found that anytime you used a pin as an input  that could also function as hardware Reset, these things could happen. Once ADC3 was selected as analog input, battery voltage could come down close to 6V and red LED would still be on which means the software would still be running. It was then that in order to prevent further problems, unused pins 1 and 5 were pulled up to +5V through 10K resistors.

ATtiny 13 code:

// This sketch monitors battery voltage and turns on an LED based on it.
// Processor: ATtiny 13.
// Author: rlarios
// Date: 13.04.03
//

int rLED = 4;                                    //Red LED pin
int yLED = 1;                                   //Yellow LED pin
int gLED = 2;                                   //Green LED pin
int val = 0;                                        //This variable will hold voltage input value
int dlyctr = 0;                                    //This is the delay counter.

void setup(){
pinMode(rLED, OUTPUT);               //Define Red LED output
pinMode(yLED, OUTPUT);              //ditto Yellow LED
pinMode(gLED, OUTPUT);              //ditto Green LED
}

void loop(){
val = analogRead(A3);                      //Read voltage through Analog input 3
if(val<452){                                     //Is battery voltage below 9.6V?
digitalWrite(rLED, HIGH);               //Yes, this is bad, turn on Red LED
digitalWrite(yLED, LOW);               //Turn off Yellow LED
digitalWrite(gLED, LOW);               //Turn off Green LED
}
else
{
if(val<594){                                   //Is battery voltage between 9.6V and 12.4V?
digitalWrite(rLED, LOW);             //This is a low voltage, turn off red LED
digitalWrite(yLED, HIGH);            //Turn on Yelow LED as a warning.
digitalWrite(gLED, LOW);            //Turn off Green LED
}
else
{
if(val<629){                                    //Is battery voltage between 12.4V and 13.1V while idle?
digitalWrite(rLED, LOW);            //Yes, turn off Red LED
digitalWrite(yLED, LOW);           //Turn off Yellow LED
digitalWrite(gLED, HIGH);          //Turn on Green LED to indicate fully charged battery voltage.
}
else
{
dlyctr = dlyctr + 1;                       //increase delay counter. every pass approx. 100ms
if(val<751){                                 //Is battery voltage above 13.1V and below 15.5V?
digitalWrite(rLED, LOW);         //Turn off red LED
digitalWrite(yLED, LOW);        //Turn off yellow LED
if(dlyctr<6){
digitalWrite(gLED, HIGH);    //Pulse green LED on for half a second
}
else
{
digitalWrite(gLED, LOW);     //Pulse green LED off for half a second to show battery is      charging.
if(dlyctr>10){
dlyctr=0;                            //Reset delay counter
}
}
}
else                                         //Battery voltage is above 15.5V.Danger ! Overcharge
{
digitalWrite(yLED, LOW);        //Turn off Yellow LED
digitalWrite(gLED, LOW);        //Turn off Green LED
if(dlyctr<6){
digitalWrite(rLED, HIGH);     //Turn on Red LED for half a second.
}
else
{
digitalWrite(rLED, LOW);      //Turn off Red LED for half a second.
if(dlyctr>10){
dlyctr=0;                            //Reset delay counter
}
}
}
delay(100);                             //Stop program 100 milliseconds to help pulse LEDs.
}
}
}
}

 

For more detail: Troubleshoot your car battery with ATtiny


About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us:
LinkedinTwitter

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top