This article is a work in progress to create a power-controller for the Raspberry Pi based on a PIC microcontroller and MOSFET. The PIC implements an I2C slave to allow power control, and also to approximate the registers of a PCF8563 Real Time Clock (RTC) chip, to allow timed wake-up of the Pi.
- Power the Raspberry Pi off and on with a push-button.
- Fully shut down the Raspberry Pi on ‘shutdown -h’.
- Wake-up at a specified time (one-off or periodic).
- Monitor the supply voltage.
- Log glitches in the power-supply (e.g. caused by USB device activity).
- Maintains the time from a CR2032 button cell.
During power-down, the circuit currently consumes around 5μA of power, useful where a battery is being used to power the Pi (remote solar-power applications, or in-car systems, for example).
The Pi is able to instruct the PIC to power it down using a short I2C command sequence. Wake up events include a push-button, or other voltage-sense on an input pin.
It’s only on a breadboard at the moment, the firmware is very much still a work-in-progress, and the schematics have only been roughly sketched out. I’ll likely paste in another circuit I have to add the options of an LCD display and multi-button inputs using IO expanders.
The PIC chip I’ve chosen is the PIC18F27J13, which has 128K of program memory and over 3K of RAM. This means there’s plenty of room left for custom programs on the PIC to intercept inputs and buffer data while the Pi boots up, and a CR2032 battery backup prevents data-loss in the PIC in the event of power failure.
I’m hoping that the low-voltage programming feature of the ‘J’ family of PIC chips will allow custom firmware to be developed on the Pi and deployed directly to the PIC, but I’ve yet to read up on the implications of this.
The schematic below implements enough to implement a RTC, implement an I2C slave that can be driven by the Pi to turn the power off, and to power the Pi on and off with a push-button.
The 26-way connector used is a female receptacle rather than a 26-way pin-header. This will probably change initially, because there’s no easy way for me to solder a female connector to the copper side of a home-made PCB. Therefore, I’ll likely use pins and a ribbon connector to hook up the board.
Note that Q1 is not the MOSFET used – it’s actually an STU95N2LH5 from ST Microelectronics. This has a much lower Vgs threshold and a very low Rds, which means it switches on fully with 3.3V and drops very little voltage between the drain and the source.
I’ve chosen a USB type A socket (the big ones) for ease of assembly in hand made PCBs. This could be substituted for the same socket as is on the Pi, but it’s a lot more fiddly. A +5V sense pin is probably required so that the PIC can detect when the main power is disconnected.
Beyond this, I’ll probably bring out 5V, 3V3, and some ADC/GPIO pins to external connectors so they can be used to interface with the PIC. The MCP1700 voltage regulator can deliver up to 250mA, which could be useful to external circuits, and the PIC chip has a 12 bit ADC.
The schematic above is a slight modification of the previous circuit that includes a potentiometer to set a voltage threshold to alarm if the voltage goes below (or above, I suppose) the pre-set value.
Firmware and details on integrating with Debian to follow… If you’re in a hurry, then you could implement a push-button just by handling PORTB interrupt on change and toggling LATC7 (after software de-bounce), and perhaps even additionally hooking RB7 to a GPIO on the Pi.
PIC18F47J13 Family Datasheet – details on the PIC18F27J13 used in this project.
Microchip AN734 – Using the PIC Devices for Slave I2C Communication, gives a fairly clear definition of the possible states that need to be handled to implement slave devices.