My Linux Car Project

Power Controller Circuit

Basically, I want the PC to boot up automatically as I start engine, and shut down (not just power off) automatically as I turn the ignition key to off.

(Moreover, it would be nice if it stays running while I leave the car for 5 or 10 minutes, to reduce the time for reboot, but for this time the circuit can't survive the engine start anyway.)

Booting looks easily done by sensing ignition key switch. However, when the voltage is low (while starting engine), unless PC is isolated by a relay, it reboots with luck, or hangs up ("brown-out"), anyway it is stressful to the DC-to-DC board. To cope with this, one can arrange it to wait for a certain amount of time after ignition key is turned on, but that is not reliable. I used the supply voltage itself, the controller detects it at analog level.

To start a PC, after ATX is invented, only connecting the power with a relay is not enough, you also nead to press the power button. (EPIA has BIOS option called "Auto boot", but it did not work as I expected.) On the other hand, ACPI-compilant PC can be configured to shut down when power button is pressed. Using this feature, one can safely shut down the PC, regardless of what OS it is running, without a specially made program. So I made the controller to be able to send pulse to mainboard's power switch pin header.

After certain amount of time from starting shutdown, it turns off the relay. You might think it would be better if it detects PC turning off itself, however that is not very meaningful, because, PC draws very little stand-by current after powering off itself, and after all it must forcibly turn off PC after certain amount of time in case of PC's hang-up during shutdown (Windows often takes forever to shut down). If ignition key is again turned on while shutting down, to prepare engine start, it forcibly turn the relay off.

So, my power controller should behave like below:

  1. Turn relay off (initial state)
  2. Wait for ignition switch turned on
  3. Wait for supply voltage becomes high (engine starts and stabilizes)
  4. Turn relay on, then wait for voltage stabilization
  5. Send a pulse to power switch, then again wait for voltage stabilization (PC starts)
  6. Wait for ignition switch turned off (PC running)
  7. Send a pulse to power switch (start shutdown)
  8. After certain amount of time, go to 1.

While in boot up sequence, if ignition becomes off, it immediatly goes to initial state (turn relay off). Likewise, during shutdown, it immediately goes to initial state as ignition becomes on.

This behavior could be implemented with analog comparators and RC timers, but I'm not good at analog circuit, I used a PIC microcontroller. PIC is one-chip 8-bit microcomputer with integrated memory and other peripherals. Flash type devices (you can reprogram many times) are popular amoung hobbyist as well, hence inexpensive and easy to obtain. This time I used a 18-pin 16F628, which has embedded analog comparator for voltage detection. It also integrates reset circuit and even clock generator, all pins except power pins can be used for I/O. For program size and speed, even smaller 8-pin 12Fxxx was enough, I couldn't use it because the writer I had doesn't support it.

Circuit Design

Developing circuit and PIC program
+5V regulator for PIC

For 5V PIC power, I used S81350 from my parts box. I think it can be safely replaced with 78L05. Its maximum input voltage is 15V, connecting unregulated supply voltage was a bit uneasy, so I used regulated 12V from regulator board.

Ignition key switch input

Ignition key signal comes at 12V, so a circuit is needed to adapt it to PIC level, 5V. Usually diode clamp is used, however, it can break the PIC here, since current consumption of this whole circuit is very low, current from 12V raises 5V PIC power. (3-terminal regulator can do nothing when output is raised.) Larger resistor can make input current low, but that makes it delicate against noise. Hence, transistor is used. With it input current flows to GND. I used 2SC1815 because I have many of them, though almost any small-power NPN transistor can be used (note the pin-out). Input impedance is set relatively low to prepend noise. By dividing input voltage to about 1/10, its threshold is 10 times VBE=0.6V, approx. 6V. The transistor looks like open collector, but actulaly is pulled up by PIC integrated pull-up resistor.

Voltage detection input

This is battery voltage divider for PIC analog comparator. Comparator compares input voltage against 1.25V from PIC integrated reference voltage module (it just divides VDD). I guess this controller does not need high precision from a dedicated reference voltage IC. It is used to distinguish battery-driven (~12V) and alternator-driven (~14V), so VR is adjusted so that 13V supply makes 1.25V at PIC input. Impedance is set low here too, current flows somewhat larger, it is picked up from ignition line rather than battery.

Clamp diode is not here either, only a simple RC filter. It is enough because the voltage is divided to 1/10, you need more than 50V input voltage to break the PIC. That's why I chose 1.25V low reference volage.

Relay output

Relay coil draws about 30mA and the one I got was rated 12V, it's not driven directly by PIC but by a transistor (2SC1815 again). Relay itself is on the regulator board. If pull-down resistor is omitted, it sometimes wrongly moved at the moment power is applied.

PC power switch interface

I measured voltage at power switch pins on EPIA, then it seems, one is GND, and the other one is pulled up to 3.3V. (At that time the power supplied is only +5V for stand-by, so EPIA apparently has a regulator to convert +5VSB to 3.3V.) To control it just like pressing the button, open collector should be enough, however, I just found a photocoupler on the power supply board in the old modem lying around, I salvaged and used it. With this it will work even if switch is at positive rail and pull-down, and since the boards become electrically isolated, I don't have to worry unnecessarily. The real power button at the front panel is hooked up in parallel, so it can also be used as usual.

To see the PIC's behaviour, an LED is connected. It's programmed to light in 5 modes:

Everything is off, waiting for ignition to become on
Short on and long off (1 second/cycle)
Ignition is on, but battery voltage is low
Blinking in short cycle (0.25 second/cycle)
Ignition is on, and battery voltage is high (will power on after 1 second)
Power on
Long blinking (1 second/cycle)
Shutting down

Also, during the power switch is conducting (100ms), it lights off. So, with only a LED, I can see how the program is running. It's also enough for adjusting VR.


As well as the regulator board, I used pcb to design layout and wiring, used perforated circuit board and tin-plated wire. This board does not handle large current, so there are not many points to pay attention.

Layout and wiring Solder side

Programming PIC

To develop a PIC program, I used gpasm assembler on Linux. To burn programs to PIC, AKI-PIC Ver.3 and software akipic are used.

Burning PIC

For clock generation, it can use external crystal or ceramic resonator, or internal RC oscillator. This time, it does not require a high resolution time measurement, internal oscillator is enough. Also internal RC oscillator can be chosen from approx. 4MHz and 37KHz. If 37KHz is used, the power consumption is minimum, so SLEEP instruction (go to low power mode) becomes unnecessary even when idle. So, I decided to first try to program with 37KHz, and switch to 4MHz when it needs more speed.

To control the LED blinking stably and asynchronously to main program, timer interrupt is used, and it is used for all time measurement. Interrupt period is chosen to be 100 times per second, so that time constants can be written in 10ms.

Programming was started with a PIC with only an LED connected, to blink it as the pattern I specified, using timer interrupt. Blink pattern is specified by 8 bits of 0 and 1, which cycles in a second. It makes 1 bit 1/8 second, which cannot be devided by 1/100 second timer, but after all the clock is from low quality RC oscillator, don't mind. Although it was a little hard to accomplish this, once it was done, the remaining was easy.

Watching the LED blinking in programmed 1 second, it looks a little longer than actual 1 second, however it's enough for this application.

When program is finished, 37KHz speed turned out to be enough. The program memory used was only 189 words out of 2K-word flash memory. Even though the PIC can be driven at 20MHz, I use it at 500 times slower, and I didn't use lots of features of the chip at all either, such as data EEPROM, serial communication, etc. It sounds wasteful, but the chip is only ¥300 (approx. US$2.5). It would be impossible for me to build an equivalent circuit without PIC, in ¥300.


Next | My Linux Car Project