Sunday, 17 November 2013

Controlling lights from the web using Raspberry Pi and Arduino

I've just got back from a weekend with my parents, where I had lots of fun attempting to get an Arduino Uno to control a cheap set of remote control mains sockets.  My dad has a set of 3 of these (http://www.maplin.co.uk/remote-controlled-mains-socket-set-531547) and has them plugged into desk and pedestal lamps in the living room.  Since my last two christmas/birthday presents to him were a Raspberry Pi Model B, and a book about home automation using Arduino, he'd picked up an Arduino starter kit from Amazon, and had bought a second remote control and taken it to pieces, all we needed was some solder and some code.

First step, solder 3 wires onto the remote control extracted from the plastic housing, as per http://blog.sui.li/2011/04/12/163/, and connect it up to the Arduino's 5V, ground and digital out pins (I chose pin 11).

Next, import the library from https://code.google.com/p/rc-switch/, then write a quick app to set switch one on and off.  Once we'd proved this works, we worked through a quick example using a photodetector, then decided it'd be fun to get this working over the web.  Since we didn't have any network connectivity, we roped in the Raspberry Pi to serve a very basic website, and use the Pi's GPIO to signal to the Arduino to turn on the lights.  I hope you'll forgive the gross insecurity of the web server, but it's quick and does the job - here's the code:

Python Code: 

#! /usr/bin/python

import sys
import RPi.GPIO as GPIO
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

class LightsHandler(SimpleHTTPRequestHandler):
    def do_GET(self):
        print "handling " + self.path
        if ("lightson" in self.path):
            self.lights_on()
        elif ("lightsoff" in self.path):
            self.lights_off()
        self.send_response(200,'OK')

    def lights_on(self):
        print "on"
        GPIO.output(18, True)

    def lights_off(self):
        print "off"
        GPIO.output(18, False)


HandlerClass = LightsHandler
ServerClass=BaseHTTPServer.HTTPServer
Protocol="HTTP/1.0"

server_address= ("", 8080)

HandlerClass.protocol_version = Protocol
httpd = ServerClass(server_address, HandlerClass)

sa = httpd.socket.getsockname()
print "serving"

GPIO.setmode(GPIO.BOARD)

GPIO.setup(18, GPIO.OUT)


httpd.serve_forever()

Arduino Code:


#include

RCSwitch mySwitch = RCSwitch();
int d_raspPiInputPin = 10; 
int d_transmitterPin = 11;
int onboardLedPin = 13;
int lightsOn = 0;
int delayTimeout = 1000;
int delayCommand = 500;
int valueFromPi = 0;

void setup()
{
  mySwitch.enableTransmit(d_transmitterPin);
  pinMode(onboardLedPin, OUTPUT);
  pinMode(d_raspPiInputPin, INPUT);
  Serial.begin(9600); 
}

void loop()
{
  valueFromPi = digitalRead(d_raspPiInputPin);
  if(valueFromPi == HIGH){
    allLightsOn();
  }
  else {
    allLightsOff();
  }
  delay(delayTimeout);
}

void allLightsOn() 
{
  if (lightsOn == 0) {
  mySwitch.switchOn(1, 1);
  delay(delayCommand);
  mySwitch.switchOn(1, 2);
  delay(delayCommand);
  mySwitch.switchOn(1, 3);
  delay(delayCommand);
  mySwitch.switchOn(1, 4);
  delay(delayCommand);
  lightsOn = 1;
  }
  digitalWrite(onboardLedPin, HIGH);
}

void allLightsOff() 
{
  if (lightsOn == 1) {
  mySwitch.switchOff(1, 1);
  delay(delayCommand);
  mySwitch.switchOff(1, 2);
  delay(delayCommand);
  mySwitch.switchOff(1, 3);
  delay(delayCommand);
  mySwitch.switchOff(1, 4);
  delay(delayCommand);
  lightsOn = 0;
  }
  digitalWrite(onboardLedPin, LOW);
} 


And a photo of the Arduino all wired up:


Notes:

  1. Don't forget to connect the grounds of the Pi and the Uno together
  2. We used GPIO 18 on the Pi as a digital output connected to pin 10 on the Uno
  3. Be careful if you're using the Pi for digital input as it'll only take 3.3 Volts
  4. We used the onboard LED on the Uno to check that we were sending the right signals to the transmitter
  5. We needed a short delay between sending commands to the transmitter, otherwise we'd only get some rather than all the lights to respond.
  6. You'll need to run the python script under sudo to be able to write to the GPIO

No comments:

Post a Comment