[CENTER]Welcome to the Internet of Things [/CENTER]
When we first talked about the Raspberry Pi and what it is, we saw that the GPIO (General Purpose Input Output) capabilities made it into more than just a board you can run a small server or desktop from. It's an extensible and powerful controller that's fairly easy to program and a lot of fun. The Pi is your gateway to your own Internet of Things, and we're going to have a look at how you can get started.
In the pictures above, I've used a small solderless bread board stuck to the top of my RPi enclosure and some male to female jumpers to get the GPIO signal from the header (the pins on the board itself) to the holes in the bread board. I did it this way because I want to use a string of UV LEDs and mount it to the back of my TV to give an eerie purple glow when I'm watching Game of Thrones reruns. My Internet of Things may not be your Internet of Things, and you can use any method you like. The only thing to keep in mind is that the components have bare metal legs, and can short out easily. It's very low voltage and under a very low load, so it's likely not going to hurt you, but it can make everything go pop or potentially start a fire. If you have questions about your wiring method, ask them and we'll figure it out.
Whatever you plan to do, I recommend you start small and prototype with one LED and one circuit on your desk. Once you get that working, a little copy paste magic and some editing can extend things from there.
The remainder of this tutorial is set up for you to have one LED circuit wired to GPIO 17.
[CENTER]Circuit diagram [/CENTER]
With the Pi turned OFF:
Connect GPIO 17 to the positive anode (the longer leg coming out of the bottom) of your LED
Connect the negative cathode (the shorter leg) to one end of your resistor
Connect the other end of your resistor to ground at physical pin 6 of the GPIO
Make sure you realize the difference between GPIO 17 and physical pin number 17. GPIO 17 is pin 11 on the header itself. SEE THE HANDY CHART. If you have any questions about this, ask them. We're here to help
Once you have everything wired up and connected well — you can use a continuity tester to check your connections if you're not sure — turn on your Pi. We've got some software to install!
Last edited by Jerry Hildenbrand; 05-25-2014 at 01:28 AM.
We need to have our Pi set up to use Python to communicate with the GPIO pins, and free up some resources since we're running a server and not a GUI. Finally, we need to install and configure the WebIOPi framework. Let's go through each step.
Freeing RAM from the GPU
SSH into your Pi now that it's up and running. During the initial set up we talked about the Memory Split that tells the Pi how much RAM to reserve for the GPU. We're going to free some of that up to make sure we have plenty for our headless server. this step is optional, because there won't be a lot of load on our server, but it's a good practice to remember.
At the command prompt, enter this to open the configuration utility:
In the menu that opens, use the arrow keys on your keyboard to scroll down to number 8 — Advanced Options and hit the enter or return key. You'll see this in your window: [CENTER][/CENTER] Set the number on the second line to 16 as shown. This allows the system to use the rest of the RAM for computation and overhead — a very good thing on any server. Use the tab key on your keyboard choose OK. This will put you back on the configuration menu. Use the tab key to choose Finish, choose Yes to reboot. When the Pi has rebooted, SSH back in and we'll continue.
Enter the above commands, one at a time to get everything we need to let Python talk to the GPIO. Without this, our project will do nothing except give us errors when we try to run it. Nobody likes errors.
Installing the WebIOPi framework
The GPIO pins can only be accessed via Python as the root user — this is why every time you run a Python script to make them do something, you need to append sudo to it. It's another of those security things. We could edit some permissions (chwon /dev/mem for those that just have to know) and let normal users control the pins with Python, but breaking security — even on a board that only sits on your desk isolated from the outside world — is not a good thing to do.
Because we need to run things as root, a standard webserver/php/cgi setup to run scripts via the network just won't work. You could write a daemon which runs as a user which has been granted access to /dev/mem and pipe things back and forth, but that's a LOT of work. Luckily, there is a ready-made framework that handles all this and more called WebIOPi.
You won't find it in your package manager, but installing it is still pretty easy. Make sure you're in your home folder:
When it's finished downloading, extract it into it's own directory:
tar -xvzf WebIOPi-0.7.0.tar.gz
Enter the directory you just created:
Run the setup script (as root):
Setup might take a few minutes, and will make sure you have everything needed to use the framework. If asked to install any dependencies, say yes. Once finished, you can test everything by running this command:
sudo webiopi -d -c /etc/webiopi/config
and pointing the web browser on your computer to http://YOUR.PI.IP.ADDRESS:8000 (make sure to enter your Pi's IP address and not those words ). The user name is webiopi and the password is raspberry (we'll get rid of that login requirement later). Look around, and be sure to have a look at the GPIO Header link. On that page, set GPIO 17 as an output and click the pin 11 button to toggle your LED on and off. For more information, see the wiki at the WebIOPi project page.
After you've blinked your LED a few times and explored things, go back to your SSH window and quit the service with CTRL+C and you're back at your command prompt.
Now it's time to interface with the webiopi service, and build a web app.
Last edited by Jerry Hildenbrand; 05-24-2014 at 05:37 PM.
Here, we're going to edit the default configuration of the webiopi service, and add our own code to run when it's called. You'll be editing files on your computer and moving them over to the Pi using an SCP client. I suggest you use Filezilla, but any SCP client will work.
Copying files back and forth from your computer to your Pi If you're using Filezilla (most FTP/SFTP/SCP clients are similar if you're using something different) setting it up is easy. Open it on your computer, and use the URL sftp://YOUR.PI.IP.ADDRESS; your Pi username and password; port 22 then press the quickconnect button.
You'll see your computers files on the left, and the Raspberry Pi's files on the left. Click a folder to open it. Click the two dots (..) next to the folder icon at the top of the list to move up one level. Drag files from one pane to the other to transfer them. Now you can edit the code on your computer, then transfer the files to your Pi easily.
Create your project folder Before we move any files, we have to have somewhere to move them. Let's build a project skeleton on our Pi. From the command prompt, do this to make sure you're in your home folder:
Create a Project folder:
Create a Webio project folder:
Move to the Webio project folder:
Inside our Webio project, make an html folder:
Inside the html folder, make a folder for images, scripts and stylesheets:
You can set up your project any way you like. It's always a good idea to set up projects the same way each time, and in an orderly fashion. If you set your project up differently, you'll need to adjust the path when we edit the webiopi service configuration, and when we write our html. This is just the way I recommend, and the path I'm using in this tutorial. If you followed along, you should have this: [CENTER][/CENTER] Of course your username and machine name will be different.
Let's try Filezilla and copy over the image file we use for a background in our app!
Don't be afraid of a little bit of code, this is simple stuff to communicate with JQuery and the webiopi framework. Let's look at what it's doing. webiopi().ready(function() — This says when the webiopi service is ready, this is the function we want to be created and started. webiopi().setFunction(17,"out") — We want the webio service to send a command to set GPIO 17 as an output, because we'll be sending signals out to it. var content, button — Set a variable named content, and make it a button. content = $("#content") — The content variable is also going to be defined in our css and html files as #content. When we refer to #content in our html or css, we want the webiopi framework to create what is defined with the content variable. button = webiopi().createGPIOButton(17,"My LED") — The button we want to create is a GPIO button (webiopi can make other kinds, for our purposes we want a GPIO interface) that controls GPIO 17 and has the label My LED. content.append(button) — Append this code for a button to any other code for other buttons. You can make more than one button using the same variables and same definition in CSS, which is handy when you're writing out your CSS and HTML. The webiopi framework will create them in the order they are listed in this file. We're using one to keep things simple.
When you have this file created and saved on your computer, copy it to Projects/Webio/html/scripts with Filezilla.
This link is your lifesaver when you have to write CSS. I'm not going to try and explain each and every line here, but we will take a look at each block to discuss what it does. In general, the css is what tells a web browser (or webview component in an app) how to draw the page. CSS is extremely powerful, and can be extremely complicated. Besides drawing some nice buttons on a tiny web page like we're doing, you can do this with it. I tip my hat to Derek Kessler, and thank the gods both old and new that I wasn't asked to build that. OK, let's look at this code a bit. The body block — this tells the browser engine to draw a page that's all black, use the LED-icon.png file in the /img folder as the background (centered and stretched to cover the screen without tiling), and use a light gray 18 point bold Arial font for any words written on the page that aren't styled themselves. As a fallback if the user does not have an Arial font defined, we can use a san-serif font at 25 points. The button block — This tells the browser engine to display a button that's 130 pixels wide and 40 pixels tall. It's a block and not inline, so each button needs to be on its own line. It also defines a little margin around the button and gives some external padding in case we position it right against something. It tells it to use the same font and style as the body block, but use black instead of light grey. It also has a few extras for text shadow and button shadow, as well as a slight transition effect so it looks pretty when we press it. Notice that these need defined separately for webkit (Chrome, Safari and new versions of Opera), Firefox, Internet Explorer and old versions of Opera. YOU NEVER KNOW WHAT BROWSER THE USER IS USING. It's telling that writing the CSS was the most complicated part of this whole tutorial. CSS is a huge PITA. But a powerful one. The input type block — The webiopi service wants this to tell it that this button is an input to the service. The #gpio.17 high and low blocks — The webiopi service will change the button and font color based on whether GPIO 17 is HIGH (on) or LOW (off). All we have to do define the colors, and when the state changes webiopi triggers the switch.
Indentation isn't as important in a css file, but the brackets and all the punctuation marks are. Copy this file exactly as it is written to your editor, and save it as bacon.css so it works with our html. When done, copy it to the Projects/Webio/html/styles folder on your Pi.
Why is this a picture and not something I can copy and paste? U SUCK HILDENBRAND!!! Security reasons keep us from uploading any and all raw html to the forums. This is what we do to keep everyone safe. You can download a plain-text version that's attached to this post as index.txt. Change the extension to .html and you're good to go.
Compared to the css, this is simple. There are some things worth talking about, so let's talk about it.
In the head section, you have a couple interesting lines:
meta name="mobile-web-app-capable" content="yes"
meta name="viewport" content = "height = device-height, width = device-width, user-scalable = no"
link rel="shortcut icon" sizes="196x196" href="/img/LED-icon.png"
The first line tells Chrome and mobile Safari that this can be saved to a mobile desktop as a web app, which is about a million Internet points worth of awesome. You do this through the Chrome menu, or the share menu in mobile Safari. The second line says that this should be displayed at the width and height of a mobile device's screen and not be resizable. The final line tells the OS what icon to use if you make a web app shortcut.
Or use a webview container and actually build a stand-alone app (easy and free to do on Android — I love sideloading)
Also in the head section are the lines that tell the browser where to find assets to build the page:
link rel="stylesheet" type="text/css" href="/styles/bacon.css"
Once you have this file all written up in your editor, save it as index.html. Then copy it to your Projects/Webio/html folder on your Pi. Note this is in the top level of the html folder, not in a sub folder. It should look like this:
I told you that was fairly easy.
Last edited by Jerry Hildenbrand; 05-24-2014 at 08:52 PM.
All that's left to do is edit the default webiopi service config, and fire it up. This is all done in your SSH window, and is the easy part. I like the easy parts.
The default username and password for the webiopi service is webiopi:raspberry . You have two options here — change it, or just get rid of the login altogether. I opted to remove the password completely. I've removed the default pi user account (changing the password is just as safe) and webiopi has no system-wide root permissions. Even with my little app exposed to the internet, I'm confident that nobody will try hard enough to get in, and if they do, they won't find anything important. They can just mess with my lighting behind the TV. Yes, this is the very definition of insecure, but in this one case I don't care because there is nothing on the machine worth caring about. Always consider the stored data on any server that you expose to the world, and decide from there how secure it has to be. /rant
To change the password: The webiopi service uses an encrypted file to store login. You can't just edit it by hand, but there's an included tool to recreate it.
The program will prompt you for a new username and password, which you will then verify. The file is encrypted, hashed and saved to /etc/webiopi/passwd , If you're using webiopi in a way that needs security, what's provided is excellent.
The server sees there is no valid password file, and allows anonymous connections.
Edit the default configuration By default the webiopi service looks for the user generated code in /home/username/WebIOPi/htdocs . That whole folder is worth exploring, but for all our work to show up we need to point it in the right direction.
Edit the configuration file with nano, as root:
sudo nano /etc/webiopi/config
You're looking for this section:
# HTTP Server configuration
enabled = true
port = 8000
# File containing sha256(base64("user:password"))
# Use webiopi-passwd command to generate it
passwd-file = /etc/webiopi/passwd
# Change login prompt message
prompt = "WebIOPi"
# Use doc-root to change default HTML and resource files location
#doc-root = /home/pi/webiopi/examples/scripts/macros
doc-root = /home/gbhil/Projects/Webio/html
# Use welcome-file to change the default "Welcome" file
#welcome-file = index.html
Notice the # Use doc-root to change default HTML and resource files location portion. Comment out any line under it by prefixing them with a # sign, then add the path to your html folder we created earlier. Don't use the line I have, because your username isn't gbhil (I hope). Place the right path there. If you are using the pi user, this will work:
doc-root = /home/pi/Projects/Webio/html
You can also change the default port from 8000 if you need to. You probably don't if you're not running any other servers on your Pi.
Save and exit nano by typing CRTL+X, sat Y that you DO want to save the file, and use the location that pops up by pressing enter. You're now ready to fire this bad boy up.
Starting the service with debugging at the console Until you know everything works, you will want to run the service with debugging enabled and logging to the console. To do this, run the following in your terminal:
sudo webiopi -d -c /etc/webiopi/config
Your terminal will start scrolling lines of text — that's normal. You won't be able to read all of it as it whooshes by, but you can watch it as you use the web app and see what it says if things do not work as expected. To quit, just press CTRL+C and it will end gracefully.
Starting webiopi as a proper service Once you have everything working the way you want it to work, you can have webiopi start as a background service. You'll still have log files written in /var/log when errors occur, but your console will be free and you'll get less verbosity while it runs. To do this:
sudo /etc/init.d/webiopi start
To check the status of the webiopi service (see if it's running):
sudo /etc/init.d/webiopi status
To halt the service:
sudo /etc/init.d/webiopi stop
To restart the service (maybe you changed the config):
sudo /etc/init.d/webiopi restart
Finally, to start the service at boot, every time your Pi boots up:
sudo update-rc.d webiopi defaults
If you changed your mind and want it to no longer start at boot:
sudo update-rc.d webiopi remove
Connecting [CENTER][/CENTER] This isn't very fun unless you can connect to it and control things, right? RIGHT? That's the best and easiest part.
Grab a web browser. It could be on your computer, or your tablet or your phone. Crummy old BREW java browsers probably won't work, but anything "modern" should. Enter the IP address of your Pi (the same one you use for SSH) followed by the port to talk to:
Use your IP address, not mine. If you changed the port in the config, adjust as needed. You should see your work in all it's glory, and pressing the button should turn the LED on and off.
If you're the type of person who builds apps, use this same address in your webview container.
To put your web app out in the Internet, you only have to enable port forwarding for port 8000 to the IP address of your Pi in your router settings, and use your external IP to connect instead of your internal IP. See the documentation for your router to get this sorted.
That's it! You now have your own little Internet of Things going on. Remember, LEDs are just the beginning. Be sure to change the look and feel of the web page once you have a handle on how all this works, and by all means show us screenshots!