Controlling the mains via the parallel port

Today I’m looking at controlling a 240V socket with the parallel port on my Linux desktop; this design can take the full 13A available and can control any device or extension lead with a 13A plug. I’m currently using it to turn lights and monitors off at night, but I have also used it in the past to check live weather reports and automatically turn a fan on. The only limitations to its use are the number of appliances with plugs and your imagination.

Sadly parallel ports are disappearing from even full ATX motherboards; this is a shame due to the fact they give an interface that can be accessed by very simple electronics. There is no need for microcontrollers of development boards here; a basic transistor switch is all that is required.

Hardware first:

The finished item

Everything fits nicely inside a socket box designed to be the attached to the wall: data in one side via a parallel plug, power in the other via a fused kettle lead cable and a power socket on the front.

The Circuitry Inside

When we look inside we find a very simple circuit: earth and neutral are passed straight through, while live goes via a 17A relay. A 12V power supply for the switching circuitry is provided by a small transformer. Its output is full wave rectified with 4 diodes and smoothed by a 1000μF capacitor.

Closeup of the transistor switch

The green data connection is soldered to pin 3 which is the data1 pin (that is the 2^1 bit). This leads, via a current limiting resistor,  to a 2n3904. This switches the 12V relay.

Up to 8 devices could be switched independently by attaching them to pins 2-10 in the same way. I used pin 20 to tie my 0V to the computers ground (other ground pins are available).

[I have updated the hardware and included some extra details here]

Now Software:

The port is needs to be opened for access; in this case port address can be chosen manually, but will default to 0x378 which usually works. In order to only change the one bit we are interested in, the current value is read with inb() then a bitmask is generated. The new value is calculated by a bitwise AND/OR operation between this bitmask and the old value. Lastly the new value is written to the port using outb().

In order to access the port it must run with root permissions, this can be achieved for normal users by giving ownership to root and setting the setuid bit:

$ sudo chown root parallel_control
$ sudo chmod u+s parallel_control

You will remember that this socket is controlled by the 2^1 bit, so use it is as simple as:

#Turn the socket on:
$ ./parallel_control 1 1

#Turn the socket off:
$ ./parallel_control 1 0

parallel_control.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/io.h>

main(int argc, char **argv){

  if(argc!=3 && argc!=4){
    printf("Incorrect usage, correct usage is %s <device> <value> [port address]\nWhere port address defaults to 0x378\n",argv[0]);
    return 1;
  }

  //default port to 0x378 if not specified
  int port = 0x378;
  if(argc==4){
    port = strtol(argv[3],NULL,0);
  }

  //Must open port access before we can use it
  if (ioperm(port,1,1))
    fprintf(stderr, "Port %x could not be acessed\n", port), exit(2);

  int device=strtol(argv[1],NULL,0);
  int value=strtol(argv[2],NULL,0);
  int onmask = 1<< device;
  int offmask = ~onmask;

  if(value==1)
    outb(inb(port)|onmask,port);

  if(value==0)
    outb(inb(port)&offmask,port);
}

10 thoughts on “Controlling the mains via the parallel port

  1. Pingback: Controlling a fan with live weather updates | Products of Mike's Mind

  2. Pingback: Controlling the mains with bluetooth proximity | Products of Mike's Mind

  3. Pradip Shah

    In place of all this complicated circuitry easier solution would be simply to use an optically isolated SSR.

    So long as one does not stick anything metallic into the switched off socket there is no danger of getting an electrical shock from leakage current of an off state SSR. Since the SSR is optically isolated there is absolutely no chance of any kind of possible high voltage feedback from the transformer in the event of a surge which might short out the primary and secondary windings in it.

    The parallel port is very much capable of supplying the required current – something like 5 ma – to trigger the SSR. I am not sure about the motherboard circuitry but if there is any way that one could POWER OFF a specific USB port it would be compatible with that too.

    BTW the amount of stuff going into the box is very much reduced and is easier to accommodate.

    Reply
    1. Mike Post author

      Thanks for the suggestion; I’ve looked into using optocouplers but the triacs on the output stage always seem to be capable of less than 1A. Are they available/affordable at 13A and would cooling start to be a concern?

      Reply
  4. Eric Carter

    A schematic for your project would be more user friendly than photos. Nice photos but not that useful in practice.

    Reply
  5. Pingback: Blog de Avízpate – Apaga tu luz vía Bluetooth.

  6. Pingback: Revisiting parallell port mains control | Products of Mike's Mind

  7. AK

    Okay I am relatively new to robotics, but I am able to follow most of this. However, I am wondering if there was a way that you could make a step-by-step guide to building this (esp. through the next two posts). If not, could anyone else who has been successful in reproducing this create one? This is one of the coolest inventions I have seen in a long time and I don’t want to miss out simply because I screw something up. The programming part I have down. It’s the technical building of the device that I am worried about because I have only built simple robots (i.e. ones that that could perform simple tasks like following a black line)

    Reply

Leave a Reply