Saturday, April 13, 2013

DIY: Raspberry Pi controlled Power Strip - Part 1

This post will cover some behind-the-scene details on what went behind making this power strip. Had been quite busy for a while, so couldn't make it earlier.

There were few questions that I had to answer before I was sure I could build this:
  1. How do I control 220V AC from an electronic circuit, safely? Can I do it right the first time so I don't blow up the raspberry Pi? Being completely a software guy, this was a challenge. This was the first part of the problem I solved as shown in my earlier post on Controlling 220v Bulb using Raspberry Pi.
  2. Can I fit this whole solution seamlessly into an existing power strip so it has a clean form-factor and intuitive to use? Finding one such power strip which had enough space to hold additional circuits was a challenge.
  3. Building software so I can remotely control the power strip over any device. I decided to go the web interface route, so I can do it easily from any device. The software I eventually implemented is based on RESTful APIs, so it would also be easier for me to write an Android app or any other app over this interface.

Controlling 220V AC from Raspberry Pi


One of the foremost requirements for choosing Raspberry Pi was that it has programmable GPIO (General Purpose Input / Output) headers, without which any electronic interfacing would be pretty difficult and inefficient. Most micro-controllers (including modern microprocessors do provide GPIO pins) for interfacing with other low-level hardware peripherals. The voltage on a GPIO PIN can be controlled by instructing the micro-controller. Usually a TTL low/high is used to signal 0 or 1. But it is totally up to the interface to decide how to interpret it. Raspberry Pi uses 3V3 TTL, which means a 3.3V for high and 0V for low. Specially when you are using the GPIO pins for input, make sure the voltage doesn't exceed 3.3V. For the power strip, it is only in output mode.

Relay is another important component. It is an electro-magnetic switch that is used to turn on or off the high voltage. Relays require slightly higher voltages (>=12V) to work. When there is enough current flow, an electro-magnetic coil gets magnetized and pulls off a lever to turn on the switch. When the power is switched off, there is no magnetic field, and a mechanical spring pulls it back to its original position. Relay is a mechanical device and might suffer some latency and noise during its operation. It is not meant for high-precision control, but in my case this is good enough.

Since relays work on higher voltages and that it requires substantial current, a relay cannot be driven directly from a Raspberry Pi. It is very common to use a transistor as a switching device to turn on slightly higher voltages and/or when you need more current. This allows us to withdraw very less current (only the base current) from the controlling source (in our case Raspberry Pi) and to use a completely different power source (>=12V) for the controlled device (in our case, a relay). I have plugged in a 12V power adaptor which provides sufficient current to turn on/off the relay.

This is the circuit that drives a single relay: (The core idea of this circuit is a very common circuit that is used to control a relay via a transistor. I have customized it to appeal for the given use case.)

Remember that Raspberry Pi runs off USB power. Model B has a cap of 700mA in the inlet and this current is used for the complete functioning of Raspberry Pi. Any current that we draw out of this, is expensive and we need to be cautious. Specially if you are planning to drive a load (say a LED) directly, without using a different power source. 

WARNING: As I learned, there is no fuse of any sort behind the GPIO headers -- so any incorrect use might blow the micro-controller, thereby making a Raspberry Pi brick. Take extreme precautions and ensure that you are fine with the current you draw/sink from/into the GPIO.

The GPIO18 is just one of the many GPIO pins that could drive this transistor. To turn it on, my code will set a HIGH on that pin, thereby raising the voltage on that pin to 3.3V. With the required V-BE (the base-emitter voltage) at 0.7V to turn on, for the 4.7KOhm base resistor, the transistor will just draw around 0.5mA current from the raspberry Pi. Even when multiple relays are ON, there is no risk of over-drawing current from Raspberry Pi. The Diode D1 provides protection against any reverse current that could occur at the moment the relay is switched off.

Raspberry Pi has a GPIO python library that we can use to control the GPIO pins with ease. By being able to control from python, I didn't have to go through the pain of cross-compiling every time I modified any code.

Snip of code:
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM) # use BCM pin numbering
GPIO.setup(gpio_pin_number, GPIO.OUT) # mark for output

#end of initialization; following could be called multiple times.

GPIO.output(gpio_pin_number, GPIO.HIGH) # output high / 3.3v
GPIO.output(gpio_pin_number, GPIO.LOW) # output low / 0v
As simple as that. Based on the command issued remotely, my power strip daemon would choose the right gpio_pin_number and set it to HIGH or LOW appropriately.

This post is getting long :). So, more about the packaging of the relay board, associated software design, in the subsequent posts.