Practical PIC Projects


Automotive Voltage Monitor

  • Description
  • Schematic
  • Circuit Description
  • PCB Artwork
  • Construction
  • Firmware




Recently I got a new motorbike and on my second trip out, with only 50 miles on the clock the rectifier/regulator unit failed.  The battery on a bike is pretty small and with the head light permanently on and all the ECU, ignition and fuel injection stuff it didn't take long to run the battery flat.  Fortunately I'd stopped and there wasn't enough charge left to turn the engine over, but it's possible for the battery to discharge and the bike to cut-out while riding - not good.

After a bit of research it became apparent that this type of failure is common, with the regulator either not charging the bikes battery, or overcharging it.  Despite the ECU monitoring the voltage it doesn't generate any indication of a low voltage condition to alert the rider.  

This project aims to provide the rider with an early warning of a fault to the bikes battery/charging system by connecting to the electrical supply on the bike and continually measuring the voltage.  If it goes outside of programmed set points it alerts the rider by activating an LED. 

The design can be applied to cars as well as motorbikes and could also be used for other voltage monitoring applications.


Download schematic in PDF

Component values shown on the schematic are for operation with a 12 volt automotive electrical system.  

Circuit Description


The circuit use a PIC12F683 microcontroller programmed with firmware (see download section) that measures the vehicle supply voltage using an Analogue to Digital Converter (ADC) and compares it to set voltage points, activating the bi-colour LED to alert the rider when the voltage goes outside the expected normal operating range.

The vehicle supply voltage feeds IC2, an LM2931AC-5.0, Low Drop Out (LDO) voltage regulator IC to power the microcontroller. This part is designed for use in automotive applications and can withstand load dumps and reverse transient.  There are several variants of this part, so make sure to get the 'AZ' or 'AC' variant as these have a +/-3.8% or 2.5% tolerance output.  Diode D1 protects the circuit from accidental reverse polarity of the input supply voltage.  Capacitors C2 and C3 are required to stabilise the regulator as per the datasheet for the device.  The design uses a 47F  capacitor for C3, but a 22F part can also be used. 

The LM2931 was chosen because it is designed for use on automotive electrical systems where the electrical supply is quite hostile.  For other applications the following devices could be used as an alternative to the LM2931. 

An LM78L05 is cheap and easy to find, it's not ideal but should work. If you do use it, you can omit C3, but will need to replace C2 with a 1F / 25 volt electrolytic.

For a precision 5 volt LDO regulator look at the LP2950CZ-5.0, this will need a 1F / 25 volt electrolytic capacitor for C2 and 1F / 6.3 volt or 10 volt electrolytic for C3.

The status LED is a 5mm bi-colour common cathode part, We used an HLMP4000 part although any bi-colour LED should work here.   It should have a milky white or defused body since it needs to 'mix' the red and green to get orange.  Clear LEDs don't do this so well.

The PIC12F683 contains a 10-bit internal Analogue to Digital Converter (ADC) that compares the voltage on the AN2 input (Pin 5) with a reference voltage.  This design uses the Vdd 5 volt supply to the PIC as the reference voltage (Vref). 

Since the range of voltages in a 12 volt automotive system can go up to about 15 volts, and higher if the alternator regulator fails the input voltage needs to be scaled down so it falls within the range 0 to 5 volts when presented to the PIC.  This is done using a voltage divider comprising R1/R2 which are 1% precision resistors to help with accuracy.  There is an optional capacitor C4 which can be used to filter the input, however this isn't used here.

Should the supply voltage exceed 20.16 volts the output from voltage divider R1/R2 will exceed 5 volts.  The  PIC has internal clamp diodes on the inputs connected to Vdd and Vss, the excess voltage will be clamped by the diode while resistor R1 limits current to just a few milliamps.


The software code the PIC is running only uses the high order 8 bits of the 10 bit ADC conversion result.  The resolution of the ADC using 8 bits is 5 volts / 255 = 0.0196 volts/bit

(n.b. the firmware actually checks the 9th bit of the result and uses it to round up/down the 8-bit result)

The values of R1 and R2 are 10K0 and 3K30 respectively.  This gives a voltage divider ratio of
3K30 / (3K30 + 10K0)  == 3300 / 13300  = 0.248  (1:4.03)

Since we are scaling the input voltage the minimum resolution of the measured input voltage is:
0.0196 / 0.248 = 0.07 volts

So as an example if we have an input voltage of 12 volts, the output voltage at the junction of R1/R2 seen by the PICs ADC input will be 12 x 0.248 = 2.977 volts.

The ADC will convert this to a numeric value which is calculated as ( Vadc / Vref ) x 255
( 2.977 / 5.0 ) x 255 = 152

The maximum voltage we can measure using a 5 volt reference and 10K0/3K30 divider is:
5 volts / 0.248 = 20.16 volts.

The software program measures the input voltage around 8 times per second and keeps a rolling average of the last 8 measurements.  The averaged value is compared to preset values which are used to determine the battery voltage state indicated by the status LED.

above 15.1 volts the LED flashes orange ( red+green mixes to give orange)
between 15.1 and 13.2 volts, the LED is steady green
between 13.2 and 12.4 volts, the LED is steady red
below 12.4 volts, the LED flashes red
The software applies 1 bit (0.07 volts) of hysteresis to these set points.

With a good battery when the ignition is first turned on the battery should be in the 'low' voltage range since the engine isn't running the battery isn't being charged.  Once the engine is started the output from the alternator should bring the battery voltage into the 'charging' range.  If it doesn't stay in the charging range this will be indicated by the LED and should be investigated. 

These set points are stored in the PICs EEPROM and can, if required, be modified either by editing the EEPROM directly or in the source code.

The value returned by the ADC for a given input voltage can be calculated using the following:

Set Point Voltage * (R2 / (R1+R2)) / (Vref / 255) = ADC Value

Set Point Voltage * (3.3 / (10+3.3)) / (5 / 255) = ADC Value

Example:  14.5 volts x 0.248 / 0.01961 = 183  (hexadecimal 0xB7)

Status LED Mode

While the voltage remains within the charging voltage range, the green LED will turn off after approximately 15 seconds.  If you want the LED to remain on continually connect GPIO5 (pin 2) to ground.  On the PCB there are two pads which can be bridged with a solder blob to ground this pin (circled red, see image right)


The values of the three design set points are calculated based on the resistors R1 and R2 being exactly 10K0 and 3K30 ohms and the voltage reference exactly 5.00 volts.   In the real circuit the resistors are only accurate to within 1% and the LM2931 accurate to +/-3.8% so the firmware needs a one-time calibration before use.  This is done by fitting JP1 then powering up the circuit from a variable power supply.  The variable power supply is adjusted until the voltage measured at the input to the ADC (pin 5) using a precision voltmeter is exactly 2.50 volts.  Once set, the jumper is removed and the PIC calculates and saves a correction multiplier. The multiplier value is then applied to the set points during normal operation. 

1. Fit jumper / link between GPIO4 (pin3) and Gnd.
2. Power circuit up using variable output PSU.
3 Adjust board supply voltage until voltage at AN2 (pin 5) is exactly 2.50 volts.
4. Cut/open jumper on GPIO4 (pin 3).
5. The Status LED will flash to show the 9 bit calibration value
    This repeats until reset/power cycled 

  Read as MSB to LSB, Red =0, Green = 1, Orange =end
    This repeats until reset or power cycled.

This is for information only and you don't need to do anything with this.

6. Remove power to circuit and reapply (or reset PIC).

You can do the calibration as many times as you want so if you mess up, or just want to have dummy run you can. Just repeat steps 1-6 each time you need to calibrate it.

PCB Artwork

The artwork is provided if you want to make your own PCB. 
The circuit is quite strait forward and could also be assembled on pad or strip board.


Artwork bottom   Component overlay



photo 1.

photo 2.

photo 3.
1.  PCB etched, drilled and cut to profile

2. Fit the resistors.  These resistors are 1/8 watt carbon film and 0.4 watt metal film parts with physical body size of 3.2 x 1.5mm.  This is about half the size of standard 1/4 watt resistors which won't fit on this PCB

   R1 10K0 [brown black black red brown ] 1% 0.4 watt metal film

   R2 3K30 [orange orange black brown brown ] 1% 0.4 watt metal film

   R3, R4 270R  [red purple brown gold ] 5%, 0.125 watt carbon film

3. Fit 1N4148 diode.  The end with the black band must be fitted in the direction shown

photo 4.

photo 5.

photo 6.
4. Fit capacitors C1 and C2.  These are 100nF and will be marked 104 on the body.

5. Fit the 8 pin DIP socket.  Make sure the end with small indent is fitted in the direction shown.

 For reliability in high vibration environments it is advisable to solder the pre-programmed PIC12F683 directly to the PCB rather than fitting it in to a socket.  Alternatively, use a small piece of high density foam cut to size so when the lid of the case is fitted it presses against the top of the PIC.

6. Fit voltage regulator IC2 with flat face in the direction shown

photo 7.

photo 8.

photo 9.
7.  Fit capacitor C3.  This must be fitted the correct way round.  One lead is shorter than the other.  Identify the short lead and install it so that the short lead is on the side arrowed in the photo.  This is the negative terminal of the capacitor

8./9.  Install the bi-colour LED.  This has 3 leads, the lead for the Red LED is shorter than the other two leads.  Fit so the Red lead is in the position shown in photo 9.   The LED should be fitted so the bottom of the main LED body is 8 to 9mm above the PCB. Also note how the leads are bent in Photo 9. to allow the LED to push down when the case is fitted without stressing the solder joints.

photo 10.

photo 11.

photo 12.
10.   For testing and development we used a jumper for the calibration link.   Since you will only need to calibrate it once you can fit a wire link.  During calibration you cut the link with side cutters.

The case used for this project is a Hammond 1551MBK series ABS enclosure 35mm x 35mm x 20mm

11.  Drill a 5mm diameter hole in the lid of the case for the LED to fit through

12. The grommet for the supply cables has an internal diameter of 4mm.  The hole size in the case is 6.5mm.  Drill the hole so the top edge of the grommet is flush with the top edge of the main case without the lid fitted.

photo 13.

photo 14.

photo. 15
Once the board is fully assembled it is advisable to spray the entire board, top and bottom, with a conformal coating to protect from damp and corrosion.  Something like this available from Rapid Electronics  Kontakt-Chemie Plastik 70 PCB Laquer 200ml Rapid part # 87-0670

Depending on how and where you mount the unit you may need to consider additional waterproofing of the case and circuit board.

13.  Fit red/black wires to the supply connections.  These should be long enough to reach between the point the box will be located and the point the wires connect to the vehicle wiring. Thread the wires through some 4mm PVC sleeving for protection.

14.  Push the PVC sleeving through the grommet.  This is a bit fiddly to do since the hole in the grommet is 4mm and the sleeving has an inside diameter of 4mm so overall it is slightly bigger.

At this point it is worth connecting it to a variable output power supply to test it is functioning.  The PIC will already have a default calibration value set so you can do some initial testing before you do the calibration.  Slowly increase the voltage from about 10 volts up to 16 volts and back down again. The LED should operate as follows.   Use a precision multimeter to measure the voltage even if your power supply has a voltmeter built-in since typically a multimeter will be more accurate.

The orange 'Over charge' state is indicated by turning on both the red and green LEDs (red+green mixes to give orange).  Some bi-colour LEDs are better than others at colour mixing so if you see red and green not orange you need to source a better bi-colour LED.
The HLMP4000 LED specified for this project colour mixes very well which is why I used it.

 FYI - there is not a third orange coloured LED in a bi-colour LED

Once you're happy the circuit is functioning you can do the calibration.  Setting the power supply to about 10.1 volts should give around 2.5 volts at the AN2 input of the PIC.  Use a precision voltmeter and adjust the power supply to get exactly 2.50 volts at AN2 input.  Remove or cut jumper link JP1

Calibration Steps
1. Fit jumper / link between GPIO4 (pin3) and Gnd.
2. Power circuit up using variable output PSU.
3. Adjust board supply voltage until voltage at AN2 (pin 5) is exactly 2.50 volts.
4. Cut/open jumper on GPIO4 (pin 3).
5. The Status LED will flash to show the 9 bit calibration value
6. Remove power to circuit and reapply (or reset PIC).

You can do the calibration as many times as you want so if you mess up, or just want to have dummy run you can. Just repeat steps 1-6 each time you need to calibrate it.

15. Completed voltage monitor



The HEX file is ready to program directly into a PIC 12F683.  The zip file contains the source code which you can modify or just view to see how it works.  If you are going to modify the code I recommend you download and install the Microchip MPLAB IDE which will allow you to edit, modify and program the PIC seamlessly.

Description Filename Download link
Source code, v1.0.5, 12/04/2011 download
HEX file ready to program into the PIC vmon.HEX, v1.0.5, 12/04/2011 download
checksum 0x69DB