Network Accessible AC Outlet Control

Synopsis: Using an Atmel NGW100, Olimex AVR I/O relay board, and some electrical elbow grease, I made a network accessible AC Outlet Control.

The purpose of this project was to see what it would take to build a remote controlled outlet. The basic requirements were that I wanted to be able to use a secure shell to log in to a device and tell it to turn on or off a 120V A/C socket.

The impetus for this came when I was at work at a client, OpenLogic, but their offices are about 70 miles from where I live. I have 3 servers at home which are housed in the crawl space under my office where they are out of the way, don't pollute my workspace with fan noise, and don't put out heat I have to live with. One of the servers wasn't responding even though I had network access to the rest. It was just dead and I needed to bounce it with a hard reboot but I couldn't given my geographical circumstances.

Using a $69 Linux embedded board (an Atmel NGW100), an AVR microcontroller relay board, open source development tools (WinAVR), and some home-brewed software and electrical elbow grease, I now have a system I can use to hard boot a server remotely.

I started with a basic control board, an Olimex AVR/IO board which has the ability to read and write a serial interface, read low-voltage digital inputs, and toggle up to 4 relays that could be used to switch 120V on and off. It would provide the ability to control up to for outlets.

It's a $41 raw board (no built-in software) with an AVR ATMega16 microcontroller on it and looks like this:

Main-AVR-IO-M16-0

In the picture above, the low-voltage inputs are on the left side and the high-voltage (compared to TTL), relays are on the right side of the board. The screw terminals on the right are used to connect the load in a normally-on or normally-off configuration.

The board is "raw" because it's up to the AVR programmer to decide how all this stuff behaves. I wanted to be able to control the relays both by using the low-voltage inputs and the serial port. Based on the inputs, if the voltage went from low (0V) to high (5V) I wanted to flip a relay corresponding to that input and vica-versa - if it went from high to low, flip the relay back. On the serial side, I wanted to be able to put a serial cable on the device and talk to it with a Mac or PC through a usb to serial cable and give it direct commands to turn specific relays on or off.

Both input modes lend themselves to microcontroller integration - a microcontroller can either "talk" to it by flipping bits using GPIO pins or by a direct serial line chat with it. Having either lets devices such as XBee or LANTronix XPort (wireless comms), either toggle the input pins or send commands serially.

Using the venerable, open source AVR cross-compiler, WinAVR, I wrote the code to drive the serial port and poll the inputs and toggle the relays based on the command. I got that running in a "standalone" mode, so before hooking anything else up I could hear the relays toggle with a soft click.

Next I rigged an outlet that I could use to control the juice to a power strip or to another A/C device. This is basic home-wiring 101. I went to Home Depot and bought a small metal outlet box, a terminal strip and some line cord to plug it into an A/C source. I wired it up as you would a normal outlet except that I broke the neutral wire out so I had two white, neutral leads coming out of the outlet. It's the neutral wire I use to control the outlet itself by completing the neutral circuit with the AVR/IO relay. The switched outlet looks like this:

HPIM4669HPIM4550

I connected it to a relay terminal block on the AVR/IO board as you can see in the first picture directly above. With my Mac talking to the AVR/IO board through the serial port, and a desk lamp plugged into the outlet, I was able to prove that I could turn the outlet on and off with serial commands. So far, so good.

At this point, the firmware for the AVR-IO-16 was complete and I could control it two ways - through a serial port or GPIO. You can see a listing of the main AVR-IO-16 code here.

Next, even though I could get the relays to toggle by using my bench power supply and injecting 0 or 5V onto one of the input terminals, what I really need to be able to do was to use a microcontroller with a GPIO pin to control it. GPIO typically doesn't have the voltage or the current necessary to drive the input side of this board. Most microcontroller's GPIO is 3.3V output and drives very little current.

To solve that problem I put together a simple PNP transistor circuit, powered by a 5V source, and used it to drive the input of the AVR/IO board. Using a very small current/voltage input to the transistor, it "hops up" the output voltage and current needed to activate the input side of the AVR/IO. So, a GPIO input from a microcontroller can be used as a control input to the PNP transistor which in turn is a control input into the AVR/IO board. Here's the PNP on a breadboard (whoopee):

HPIM4662

So, at this stage, I have an AVR/IO board with software that can respond to inputs and control relays for output and outlet control. I have a switchable outlet. And I have a driver circuit suitable to drive the system from a microcontroller. What I don't have yet is the microcontroller driver or a way to put this whole thing on a network.

Enter the Atmel NGW100.

The NGW100 is a wicked cool device - for $69 you get a complete 32bit (AVR32) Linux embedded controller with 2 ethernet ports, a full TCP/IP stack, and GPIO ports out the wazoo. Using this device, I have the solution for a) being able to reach the controller on the network and b) using the controller to toggle GPIO inputs to the transistor/driver...in turn controlling the outlet through the AVR/IO board. (This is starting to sound like the story, "A Fly went by".)

The NGW100 looks like this:

HPIM4297

It's easy enough to log in to the device, but then what? How do you toggle the GPIO ports? What pins are the GPIO ports (there are dozens of pins broken out)? After some research in the online docs of the NGW100 at Atmel, I was able to locate the schematic and pinouts and choose a candidate GPIO port to prototype.

In order to manipulate the GPIO ports on the NGW100, it turns out that the Linux embedded implementation uses 'configfs' which doesn't have a whole lot written about it. That said, in a nutshell, configfs maps things like GPIO ports to linux files on the file system. Then by reading and writing to that mapped file on the file system, you can manipulate the GPIO pin associated with the file. When the file value changes, the GPIO pin value changes (0 or 1 file value creates a 0V or 3.3V change on the pin.)

When the NGW100 boots, you have to make sure you setup the directories and gpio files. I use a version of a script that was on the Linux embedded build flashed on the board (I think that's where it came from) to setup the GPIO PA21 pin as an example. I put a modified version in my home directory on the NGW100 flash file system.

See the GPIO setup code and GPIO golow and gohigh scripts for the NGW100.

Once the testgpio shell script runs, it will have made the mapped files to the configs for the PA21 pin. The golow and gohigh scripts match the objective of taking the input of the AVR/IO low or high via the GPIO pin and PNP transistor.

At this point, you can do another test which is to connect the NGW100 GPIO pin that we configured above to the PNP transistor and test to see if it's able to toggle the relay of the AVR/IO board. Obviously, connect the NGW100 GPIO pin to the input side of the PNP transistor. It's easiest to do this with a wire that has a female single on one end to plug into the NGW100 header and a male pin on the other to plug in to the breadboard where the PNP is. I should mention that I soldered the right angle double header onto the NGW100 in order to make this whole thing easier to access. Also, take the output side of the PNP directly to the input terminal on the AVR/IO board. Insure you have a common ground between the 3 boards (AVR/IO, NGW100, and the PNP transistor board.)

HPIM4664HPIM4665HPIM4667

Now you can either ssh into the NGW100 if you have it on the network already or you can connect a serial cable to the console port of the NGW100. Either way, you cd to the home directory where you have created the scripts shown above and execute the golow and gohigh scripts to test the toggling of the relay. If you don't succeed, get a multimeter or oscilloscope and monitor the GPIO pin shown to see if it's toggling between 0 and 3.3V when you run the golow and gohigh scripts.

At this point, you can test the entire system end-to-end and try turning on and off the desk lamp that's plugged into the switched outlet. If all is well, you can then make your NGW100 accessible on the network just like any other Linux device....set up the router rules you need to get to it or poke holes in your firewall to allow ssh to be forwarded to your NGW100. That's all standard IP networking stuff that I won't describe here.

Conclusion

Using an Atmel NGW100 Linux embedded system to perform the network and secure shell functions as well as the GPIO to the relay board, along with a switchable outlet, I was able to achieve the goals of a remotely controlled AC outlet.

The next steps are to create a 4 PNP transistor board, setup 3 more GPIO ports on the NGW100, fit the transistor board to the AVR/IO board so it's convenient to run a small cable from the GPIO pins of the NGW100 to the AVR/IO board and finally add 3 more switched outlets for a fully configured system. Naturally stuffing it into an enclosure would be wise.
Clicky Web Analytics