Raspberry Pi ATX power management using an Arduino (Pt. 1)

So I’ve been rather busy.  I completed my R-Pi HTPC.  I also completed my ATX power management board.  This is a subject that has been tackled in a number of ways.  I’ve seen various methods and implementations.  The problem with using an ATX power supply to power a Raspberry Pi is: You have to “trigger” it on yourself by tying the trigger (green) lead to ground, and when you shut down the Pi, it does not turn all the way off. This means you either need to disconnect the power to the Pi -or- disconnect the power to the ATX supply -or- disconnect the trigger.  I went with a multi-step approach using an Arduino Micro.


Theory of Operation

So the way this works is somewhat complex, but very effective and more-or-less mimics the basic ACPI function on a standard ATX-style motherboard.  The Arduino monitors 2 input pins, these pins have momentary (normally open) push buttons attached to them.  When the system is off, pushing the reset button is ignored, but pushing the power button triggers a relay that powers on the Pi.  Once its on, pushing the reset button triggers another relay that shorts the reset pins on the Pi (you will likely need to solder a 2-pin header onto the Pi).  This sounds simple, but to accomplish all this AND accommodate a 2.5″ SATA HDD, requires a little bit more complexity.

I used a total of (3) 5V relays and some transistor magic to make it all happen.  1 relay handles shorting the reset pins on the Pi, another handles switching the 5V rail on/off for powering the Pi and providing the 5V to the HDD, the 3rd relay handles switching the 12V rail on/off to the HDD.  Obviously, the relays for the 5V and 12V rails need to switch simultaneously.  Now, to truly behave like a normal ACPI-compliant board, we can’t leave the ATX supply on all the time.  So we’ll power the Arduino using the 5V Standby on the ATX supply (purple wire).  This lead is always “hot”.  On a normal motherboard, this standby voltage is used to back the NVRAM portion of the CMOS (used for storing user settings (time, date, etc)) and also to power the ACPI circuit.  When you push the power button on your computer, this circuit triggers the ATX supply on and powers up the rest of the system.  That is our goal with the Pi.

So, to do this we will need all 8 digital I/O pins on the Arduino.  One of the caveats is: The 5V standby does not provide enough juice to power all 3 relays and 2 LEDs.  So, we use it to power the Arduino only.  Then using an NPN transistor as a switch, we short the trigger to ground causing the ATX supply to “turn on”, giving us another dedicated 5V rail from the ATX supply to power the rest of the circuit.  Now that we can power the relays, turning the power on will activate both power control relays powering on the Pi and the HDD and allowing it to boot normally.  To turn it off, pushing the power button drive the output pins low, causing the relays to switch off.  Of course, we can’t just power these relays using the output from the I/O pins directly, so we use NPN transistors activated by the output pins to turn on the relays, and we clamp the relay coil using a rectifier diode.

But what about “soft off”?  Good point.  When you shutdown the Raspberry Pi, that doesn’t shut off the power.  So you would have to shutdown the Pi, then turn off the power, then turn it back on to get it boot up again.  That’s annoying.  As it turns out, the Raspberry Pi drives the UART TxD pin on the GPIO header high when it turns on.  It will go low again for ~200ms when the hand-off from the soft-firmware to the kernel bootstrapper occurs and will then stay high until CPU_HALT.  So we just connect to TxD pin to an input pin on the Arduino and watch its state.  When the system is powered on, we monitor that pin to see if it goes low.  Now since we know that it will briefly go low at some point during the boot cycle, we can’t just shutdown as soon as we see that .  So inside our loop() routine, the first time we notice this happen, we need to use a timer and a counter to keep track of *how long* the pin went low.  To be safe, my Arduino firmware waits 500ms for up to 4 cycles (a total of 2 seconds) after CPU_HALT to be certain that the Pi has shutdown completely.

As it turns out, this is just enough time for the TV/Monitor to notice that the HDMI signal is lost.  By then, the Arduino drops out both power control relays, then waits another 50ms and turns off the ATX supply.  That’s pretty much the jist of it.  I plan to post my schematics, firmware source code, and all the scripts and config files for the actual HTPC software to GitHub as soon as I get everything together.  Keep an eye out for my next post where all dig into system design, materials, etc and then later on the OS and software.  I’ll post a bunch of pics to.  In the meantime, you can take a look at the schematic for the power management board here.

Facebooktwitterredditpinterestlinkedinby feather

Leave a Reply