Raspberry Pi Garage Door Opener

Required for this project is a Raspberry Pi Zero W or Raspberry Pi 3 Model B+ (other models, like the Raspberry Pi 3 Model A+, may also work), compatible power supply, button, 5 volt relay switch, solder and soldering gun, cables/wires, circuit board, a basic understanding of the HTTP (Hypertext Transfer Protocol), the Python programming language and the Linux operating system.

This tutorial assumes the use of Windows 10.

Setup the Raspberry Pi

If the Raspberry Pi's Raspbian OS is already installed and configured, skip this section.

  1. Download and install SD Card Formatter for Windows; download from sdcard.org.
  2. Quick format the Raspberry Pi's micro SD card.
  3. Download and install Win32 Disk Imager; download from sourceforge.net.
  4. Download Raspbian Lite from raspberrypi.org.
  5. Install Raspbian Lite image using Win32 Disk Imager.
  6. Install micro SD card and boot Raspberry Pi device.
  7. Login as: pi, password: raspberry
  8. Configure Raspbian by issuing a sudo raspi-config command from the command line prompt.
    1. Under Network Options, setup wireless networking.
    2. Under Interface Options, enable SSH.
    3. Under Localization Options, configure the keyboard.
    4. Under Advanced Options, expand filesystem.
    5. Reboot.
    6. Login.
  9. Issue a sudo apt-get update && sudo apt-get upgrade command to update the system.
  10. To access the Raspberry Pi file system over the network from a Windows machine, install Samba.
    1. Issue a sudo apt-get install samba samba-common-bin command at the command line.
    2. Issue a sudo nano /etc/samba/smb.conf command to edit the samba configuration.
      1. Go to the end of the file and enter this text on new lines:
        [user_pi]
        comment=User Pi
        path=/home/pi
        browseable=yes
        writeable=yes
        only guest=no
        create mask=0777
        directory mask=0777
        public=yes
        guest ok=yes
        
      2. Hit CTRL+X to exit.
      3. Save the file when prompted.
    3. Issue a sudo chmod 0777 /home/pi command at the command line.
    4. Reboot.
    5. Login.
  11. Type python at the command prompt. Python version 2.x should be in use.

Program the Raspberry Pi

relay's pin detail

All 5 volt relays for this application should look like this. For this project, pin number 7 is connected to IN on the relay while pin number 2, which is 5 volts, is connected to VCC. Finally, pin number 6, which is ground, is connected to GND.

circuit diagram under construction.

Python Coding

Run this code by issuing a sudo python garagedoor.py command at the command line. Then open a browser with access to the same network and enter the computer's IP address using port 8000 (something like http://192.168.1.5:8000/). The host name can also be used instead of the IP address (something like http://hostname:8000/).

import os
import RPi.GPIO as GPIO
from time import sleep
import SimpleHTTPServer
import SocketServer
import urlparse

def build_html_page(head_child):
	C = float(os.popen("vcgencmd measure_temp").readline().replace("temp=","").replace("'C","").replace("\n","")) # get cpu temp
	if(C >= 70.0):
		color = "#f00"
	else:
		color = "#00f"
	F = 1.8 * C + 32 # convert C to F
	return str("""<!DOCTYPE html>
	<html>
		<head>
			<style>
				label {
					margin:7px;
				}
				fieldset {
					border:1px solid #ccc;
				}
			</style>
			<title>Garage Door</title>
			<meta name="viewport" content="width=device-width" />
			""" + head_child + """
		</head>
		<body>
			<div style='margin-top:25px;text-align:center;'>
				<div style='text-align:left;margin:auto;border:1px solid #ccc;width:220px;padding:5px;'>
					<form method=POST action='/'>
					<fieldset><legend>garage door</legend><input type=password name=pin placeholder='Enter PIN' style='width:185px;' maxlength=25 /></fieldset>
					</form>
				</div>
			</div>
			<div style='text-align:center;color:""" + color + """;margin-top:20px;'>CPU temp: """ + str(F) + """'F</div>
	</body></html>""");

def http_trigger_door():
	GPIO.setup(7,GPIO.OUT) # use pin number 7 for the relay IN connection
	sleep(.33)
	GPIO.setup(7,GPIO.IN) # notice that just GPIO.setup is used, not GPIO.output which could damage the Raspberry Pi

def button_trigger_door(ev=None):
	http_trigger_door()

class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
	def __init__(self,req,client_addr,server):
		SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self,req,client_addr,server)
		
	def do_POST(self):
		post_body = self.rfile.read(int(self.headers['Content-Length']));
		qs = dict(urlparse.parse_qs(post_body)) # returns a dictionary
		if(qs.get("pin") != None):
			with open('GARAGE_DOOR_PIN.txt', 'r') as pin_file: # GARAGE_DOOR_PIN.txt must exist
				if(pin_file.read() == qs.get("pin")[0]):
					http_trigger_door()
		self.send_response(200)
		self.send_header("Content-type", "text/html")
		html = build_html_page("<meta http-equiv='refresh' content='0; url=/' />") # even if a browser does not support this, it will still work overall
		self.send_header("Content-length", len(html))
		self.end_headers()
		self.wfile.write(str.encode(html))
		
	def do_GET(self):
		self.send_response(200)
		self.send_header("Content-type", "text/html")
		self.send_header("Cache-control", "no-store")
		self.send_header("Pragma", "no-cache")
		html = build_html_page("")
		self.send_header("Content-length", len(html))
		self.end_headers()
		self.wfile.write(str.encode(html))

if __name__ == '__main__': # Program starts here
	GPIO.setmode(GPIO.BOARD) # set GPIO numbering mode
	GPIO.setup(8,GPIO.IN,pull_up_down=GPIO.PUD_UP) # Set the mode of 8 pin to input and pull up to high level (3.3v)
	GPIO.add_event_detect(8,GPIO.FALLING,callback=button_trigger_door,bouncetime=1000) # wait for falling and use bouncetime to prevent multiple calls to callback function
	try:
		port = 8000
		httpd = SocketServer.TCPServer(("0.0.0.0", port), Handler)
		httpd.serve_forever()
	finally:
		GPIO.cleanup()

GARAGE_DOOR_PIN.txt

1234
garage door page opened in Safari

Additional Configuring of the Raspberry Pi

Now, configure the Raspberry Pi to automatically run the above script at startup so that the device is more autonomous.

  1. Issue a sudo nano /etc/rc.local command.
  2. Go to the bottom of the page, before the exit 0 line.
  3. Enter a new line of text reading cd /home/pi. Substitute /home/pi with the actual directory to the script file.
  4. Enter another new line of text reading sudo python garagedoor.py & . Substitute garagedoor.py with the name of the actual script file name. Do not forget the ampersand at the end so that execution will return and not wait for the Python script to finish.
  5. Hit CTRL+X to exit.
  6. Save the file when prompted.
  7. Issue a sudo crontab -e command.
  8. Enter (at the end of the file, preferably) 0 12 * * * sudo reboot. This is to make the system restart every 24 hours to, as of the writing of this, fix a bug that causes the Python HTTP server to hang after some hours of use.