Lucas Jackson / September 10, 2015

Raspberry Pi Light Switch

Star Download

Overview

This was a fun project I did that allows the control of a light-switch from my iPhone including the help of a RaspBerry Pi 2, a Lego motor, l9110s motor driver, and some Python code. With the raspberry pi, we can control the gpio pins from the RPi.GPIO python library and create a server to listen for commands sent from the iOS Device. The GPIO pins will interact with a motor driver control the motor that will interact with the light switch.

Raspberry Pi GPIO Pins

I will be using GPIO pins 11 and 12 on my Raspberry Pi and connecting them to pins A-1B and A-1A on the L9110s motor driver.

Connecting Pins

The L9110S 2-Channel motor driver module is a compact board that can be used to drive small robots. This module has two independent motor driver chips which can each drive up 800mA of continuous current. The boards can be operated from 2.5V to 12V enabling this module to be used with both 3.3V and 5V microcontrollers. After connecting the Raspberry Pi GPIO pins to the L9110S we add a power source to power the motors. A separate power source other than the Pi helps to avoid server problems and interference. If you try this, you may add any power source you want, I recommend a steady 5v source.

When all of the wires and power source are setup, it should look something like this. (Im using an adafruit trinket for a 5v power supply)

Lego Robotics

Limited on resources and making use with what I already have, I choose a Lego Mindstorms motor to act as the physical controller that can toggle the light switch. It would be frowned upon to mess up the paint in my room so I used a rubber band around the frame to hold the motor in place.

Some soldering was required to bridge the jumper cables to the lego wires. The lego motor will connect to “Motor A” on the L9110s. solderlego

Python Server

The code below is our python server. It will listen for connections and send power to either pin 11 or 12 based on the commands that are sent to it over port 50007. This script should be saved and run on the Raspberry Pi.

		#!/usr/bin/python
		import sys,os,socket,time
		import RPi.GPIO as GPIO
		
		GPIO.setmode(GPIO.BOARD) 
		GPIO.setup(11, GPIO.OUT)
		GPIO.setup(12, GPIO.OUT)
		try:
			while 1:
				HOST = ''			
				PORT = 50007
				s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
				s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
				s.bind((HOST, PORT))
				s.listen(1)
				conn, addr = s.accept()
				while 1:
					data = conn.recv(1024)
					if not data: break
					print data
					if "on" in data:
						GPIO.output(12, True)
		        		        time.sleep(0.2)
			        	        GPIO.output(12, False)
					elif "off" in data:
						GPIO.output(11, True)
		        	        	time.sleep(0.15)
			               		GPIO.output(11, False)
				conn.close()
		except KeyboardInterrupt:
			print "\nCleaning up gpio before exiting..."
			GPIO.cleanup();
		                

Interacting with the server from iOS

With Objective C, we can include the sys/socket.h library to connect to the Raspberry Pi. Creating the function below, allows us to connect to the ip and port of the Raspberry Pi server running the python script.

		-(void)switchon:(BOOL)on {
		    int mainsock = socket(AF_INET, SOCK_STREAM, 0);
		    struct sockaddr_in server_address;
		    struct hostent *host = gethostbyname("10.0.0.6"); //set host of our server
		    memcpy (&server_address.sin_addr.s_addr, host->h_addr, host->h_length); //set the host and length
		    server_address.sin_family = AF_INET;
		    server_address.sin_port = htons (50007); //set port of our server
		    
		    if (connect (mainsock, (struct sockaddr *) &server_address, sizeof (server_address)) < 0) {
		        NSLog(@"error connecting");
		    }
		    
		    NSString *returnval = @"off";
		    if (on) {
		        returnval = @"on";
		    }
		    long w = write(mainsock,[returnval UTF8String],strlen([returnval UTF8String]));
		    if (w < 0) {
		        NSLog(@"error connecting");
		    }
		    close(mainsock);
		}

We now decorate our UI with a LightSwitch UIImageView with the referencing outlet named “lightswitch”. I allocate a UISwipeGestureRecognizer that detects swipe direction on lightswitch.

- (void)viewDidLoad {
		    UISwipeGestureRecognizer *upgr = [[UISwipeGestureRecognizer alloc] 
		    	initWithTarget:self action:@selector(switchedlighton)];
		    upgr.delegate = self;
		    upgr.direction = UISwipeGestureRecognizerDirectionUp;
		    [lightswitch addGestureRecognizer:upgr];
		    
		    UISwipeGestureRecognizer *dngr = [[UISwipeGestureRecognizer alloc] 
		    	initWithTarget:self action:@selector(switchedlightoff)];
		    dngr.delegate = self;
		    dngr.direction = UISwipeGestureRecognizerDirectionDown;
		    [lightswitch addGestureRecognizer:dngr];
		    
		    [super viewDidLoad];
		}

Below are the functions for the UISwipeGestureRecognizer. For each swipe, the image for “lightswitch” will change to what command was sent to the server to make it look like the lightswitch is either on or off.

		-(void)switchedlighton {
		    [self switchon:true];
		    [lightswitch setImage:[UIImage imageNamed:@"switchon.png"] forState:UIControlStateNormal];
		}
		
		-(void)switchedlightoff {
		    [self switchon:false];
		    [lightswitch setImage:[UIImage imageNamed:@"switchoff.png"] forState:UIControlStateNormal];
		}

We can’t forget define our lightswitch UIImageView and add UIGestureRecognizerDelegate in our header file.

		@interface ViewController : UIViewController {
		    IBOutlet UIButton *lightswitch;
		}

I add a button in interface builder with the IBOutlet set to lightswitch;

Heres a quick video demonstration

Thanks for viewing!