The project described here creates a website hosted on the Phidget Single Board Computer (SBC). The website can both serve static pages, as well as pages that can send simple requests back and forth to the Phidgets attached to the SBC.
With this kind of system, you only need to develop cross-browser compatible web pages, as the code to control the Phidget runs on the SBC.
Note: The code examples in this article use Phidget21 code and may not work with newer versions of the Phidget library.
As with any of our described projects, Phidgets takes care of the electrical component design. This is a middle-ground solution to controlling Phidgets over a network using the SBC.
- If you just want data to go back and forth between Phidgets and your computer - via the SBC - over the network, you probably want the simple example in the Use Phidgets Wirelessly with the SBC guide.
- If you want something more powerful and flexible than the CGI in this guide to control Phidgets over a network, you may be interested in the full Web Server on the SBC guide coming soon.
About two hours
Materials and Phidgets:
- A Phidget SBC
- Ethernet and power cords (or Wireless)
- an LED
- your computer
You should also have:
The SBC already runs a web server, with the pages to be served located in the /var/www directory. We take advantage of this by creating a web page using a cgi-bin Python script. Since the script is in Python, it can also control any attached Phidgets, including the Interface Kit on the SBC.
The flow of the system we will build looks like this:
For this, you will need:
- A Phidget SBC2 or Phidget SBC3, set up as per the 1072 User Guide / 1073 User Guide. This is the SBC that this guide used; others will probably work fine as well
- An LED, such as one of the ones from Phidgets (many part numbers starting at 3600), attached to digital output port 0 (long wire) and ground (short wire)
First, we build a static web page with no Phidget involvement. If you just want to host a few pages on the SBC, that part of the example will help greatly.
Then we write a separate and unrelated Python script, save it in the SBC's cgi-bin directory, and run it over the network.
To create a web page hosted on the SBC, you simply have to create one and save it in the /var/www/ directory.
When you log into the SBC using SSH, you can move into that directory and start editing a simple HTML file by:cd /var/
Then, type in a simple web page structure, such as this:
Finally, go to that address in a browser on the same local network as the SBC, using the address http://phidgetsbc.local/helloworld.html (replace the link local address of the SBC and the filename if you've changed them). Which will give you something like this:
Script-generated web pages go in a special folder called cgi-bin/ within the /var/www/ directory. In addition, they end with an extension that tells the SBC how to run them. Python cgi scripts end with .py.
To enter the cgi-bin directory, and then create and edit (using nano) a file called led_state.py, you can type the following into an SSH terminal to the SBC:cd /var/www/cgi-bin/
Within the nano editor, you can enter this code:
#! /usr/bin/python from Phidgets.PhidgetException import * from Phidgets.Events.Events import * from Phidgets.Devices.InterfaceKit import * import cgi import cgitb cgitb.enable() errors = "" setLED = None form = cgi.FieldStorage() ledLocation = 0 # Print the HTML header print("Content-type: text/html\n\n") print("<html><title>LED CGI-BIN Control</title><body>\n") # Create, Open, and Attach the Interface Kit try: interfaceKit = InterfaceKit() except RuntimeError as e: errors = errors + "<h5>Runtime Exception on object creation: " + e.details + "</h5>\n" try: interfaceKit.openPhidget() except PhidgetException as e: errors = errors + "<h5>Phidget Exception on Open: " + e.details + "</h5>\n" try: interfaceKit.waitForAttach(10000) except PhidgetException as e: errors = errors + "<h5>Phidget Exception on Attach: " + e.details + "</h5>\n" errors = errors + "<h5>If Phidget is 'Not Physically Attached' it may be in use</h5>\n" # If we got a request to set the LED to a state, find out which state if "setLED" in form: setLED = int(form["setLED"].value) # Check the input we got to make sure it is either a 0 or 1 if not ((setLED is 0) or (setLED is 1)): setLED = None # If we are dealing with a request if setLED is not None: try: interfaceKit.setOutputState(ledLocation,setLED) print("<h3>LED state has been set to " + str(setLED) + "</h3>\n") except PhidgetException as e: errors = errors + "<h5>Phidget Exception on LED Set: " + e.details + "</h5>\n" # Otherwise, simply print the current LED state else: try: setLED = interfaceKit.getOutputState(ledLocation) print("<h3>LED state is currently " + str(setLED) + "</h3>\n") except PhidgetException as e: errors = errors + "<h5>Phidget Exception on LED Get: " + e.details + "</h5>\n" # Communicate with our user if need be print(errors) # If there are no errors, we can safely add the option to toggle the LED if errors is "": # The LED gets set by an int, but getState returns a bool, so we could have either if (setLED is 0) or (setLED is False): setLED = 1 else: setLED = 0 print("<a href='http://corasbc2.local/cgi-bin/led_state.py?setLED=" + str(setLED) + "'>Toggle LED</a>") print("</body></html>\n") interfaceKit.closePhidget() exit(0)
Save it, and your SBC is now ready to control the LED over the web!
Putting it All Together
Head over to the web address of your Python cgi script: http://phidgetsbc.local/cgi-bin/led_state.py - replacing the local link address and file name if you've changed them. You will arrive (depending on the initial LED state) at one of a few different pages.
There are essentially four different web pages that this script produces. There are two where we do not include any request in the http address. One where the LED is already on:
And one where the LED is already off:
Then there are two pages where we include a request for a new LED state in the http address. You can do this by tacking a ?setLED=0 or ?setLED=1 on to the end of the address.
Requesting that the LED turn on (?setLED=1) gives:
And requesting that the LED turn off (?setLED=0) gives:
The Toggle LED link is just generated in the Python script to be a request-type page with the request toggling the LED.
And you're done! Give the web page address to everyone on your local network, so they can have fun turning your LED on and off at random times.
These requests over the web are fast, but theoretically more than one can happen at one time. In that case, the Phidget Interface Kit will already be attached and bound to another program, so you will get an error. With the web script in this application guide, the error will probably look something like this:
How would you create a mutual exclusion setup to prevent this from happening on the web?
How would you create a different setup to prevent this from happening with other programs?