This part focusses on controlling the gpio pins of the Pi using a web based user interface. Ive kept everything as simple as possible and also kept the page layout simple too.
Step 1
The webserver running on the Pi3 needs permission to access the gpio pins, this can be done easily by adding the webservers user account (www-data) to the gpio group
sudo adduser www-data gpio
now the pins can be controlled without the need of root permissions which makes things so much easier
Step 2
We need to create some Python scripts to run the Bash commands that controls the gpio pins, its likely that in a final application all of these commands will be put into a single Python file but to keep things segmented at this stage, a seperate file for each command was used. When Python files are added to the cgi-bin on the webserver make sure to use chown to change the owner of the file to the www-data user and chmod to make the files executable.
gpiodirectionin.py
#! /usr/bin/python # import os import sys os.getenv("QUERY_STRING") pinnumber = sys.stdin.read() p = os.popen("echo in > /sys/class/gpio/gpio"+pinnumber+"/direction") p.close() print "Content-Type: text/html\n\n" print '<html><head><meta content="text/html; charset=UTF-8" />' print "</body></html>"
gpiodirectionout.py
import os import sys os.getenv("QUERY_STRING") pinnumber = sys.stdin.read() p = os.popen("echo out > /sys/class/gpio/gpio"+pinnumber+"/direction") p.close() print "Content-Type: text/html\n\n" print '<html><head><meta content="text/html; charset=UTF-8" />' print "</body></html>"
gpioexport.py
#! /usr/bin/python # import os import sys os.getenv("QUERY_STRING") pinnumber = sys.stdin.read() p = os.popen("echo "+ pinnumber +" > /sys/class/gpio/export") p.close() print "Content-Type: text/html\n\n" print '<html><head><meta content="text/html; charset=UTF-8" />' print "</body></html>"
gpiounexport.py
#! /usr/bin/python # import os import sys os.getenv("QUERY_STRING") pinnumber = sys.stdin.read() p = os.popen("echo "+ pinnumber +" > /sys/class/gpio/unexport") p.close() print "Content-Type: text/html\n\n" print '<html><head><meta content="text/html; charset=UTF-8" />' print "</body></html>"
gpiovaluehigh.py
#! /usr/bin/python # import os import sys os.getenv("QUERY_STRING") pinnumber = sys.stdin.read() p = os.popen("echo 1 > /sys/class/gpio/gpio"+pinnumber+"/value") p.close() print "Content-Type: text/html\n\n" print '<html><head><meta content="text/html; charset=UTF-8" />' print "</body></html>"
gpiovaluelow.py
#! /usr/bin/python # import os import sys os.getenv("QUERY_STRING") pinnumber = sys.stdin.read() p = os.popen("echo 0 > /sys/class/gpio/gpio"+pinnumber+"/value") p.close() print "Content-Type: text/html\n\n" print '<html><head><meta content="text/html; charset=UTF-8" />' print "</body></html>"
Step 3
Rather than use the index.html file from the previous 2 blog posts, I made a new webpage to keep it easy to read. It contains a text field for a user to enter the gpio pin number to control and buttons to operate the pin exporting, direction control and set the high or low. The buttons call javascript functions which interact with the Python scripts above.
gpio.html
<html> <body> <input type="text" id="pinnumber" style="font-size:2.0em;" maxlength="2" size="1" value="1"> <input type="button" onClick="exportPin()" value="Export"> <input type="button" onClick="unexportPin()" value="Unexport"> <input type="button" onClick="setDirectionOut()" value="Set Output"> <input type="button" onClick="setPinHigh()" value="Set High"> <input type="button" onClick="setPinLow()" value="Set Low"> <script> function exportPin(){ var pinnumber = document.getElementById("pinnumber").value; var req = new XMLHttpRequest(); req.open("POST","/cgi-bin/gpioexport.py",true); req.send(pinnumber); } function unexportPin(){ var pinnumber = document.getElementById("pinnumber").value; var req = new XMLHttpRequest(); req.open("POST","/cgi-bin/gpiounexport.py",true); req.send(pinnumber); } function setDirectionOut(){ var pinnumber = document.getElementById("pinnumber").value; var req = new XMLHttpRequest(); req.open("POST","/cgi-bin/gpiodirectionout.py",true); req.send(pinnumber); } function setPinHigh(){ var pinnumber = document.getElementById("pinnumber").value; var req = new XMLHttpRequest(); req.open("POST","/cgi-bin/gpiovaluehigh.py",true); req.send(pinnumber); } function setPinLow(){ var pinnumber = document.getElementById("pinnumber").value; var req = new XMLHttpRequest(); req.open("POST","/cgi-bin/gpiovaluelow.py",true); req.send(pinnumber); } </script> </body> </html>
There's a video demonstrating the use of this system below, any questions please ask them in the comments and keep a look out for a follow up blog post showing how we can use the pins as input pins and display their values in the webpage!
Top Comments