Sunday 14 September 2014

RaspberryPi Web server: GPIO access

Controlling the RaspberryPi GPIO remotely, over a network or across the internet, seems like an interesting trick.

I copied some code from the net and gave it a try, but unfortunately it didn't want to play.

So I went back to basics and created my own simple test routine.

The web server

I built a fresh web server by installing Lighttpd and PHP as described in this earlier post. My new server can only be accessed on my personal network, and this is by using a browser on another networked computer.

The RaspberryPi web server IP is (in my case) and I've set the lighttpd port to 9080. So the url: takes me to the /var/www folder on the web server.

In order to communicate with the GPIO I also installed Gordon Henderson's wiringPi as covered in this post.

My php test program (which I've added to /var/www) is called gpio_test.php and looks like this:-

It basically reads the current output level (or status) of GPIO pin 7, and tries to invert it (e.g. toggle "0" to "1" or "1" to "0"). So each time I refresh the page in the web browser, I should see the output change state.

I haven't actually bothered to connect a light to pin 7, and it doesn't matter which GPIO pin I choose for this test.

When this is run by remotely entering: in a web browser, I get this simple black on white page:-

The program returns an error code each time it tries to read the state of GPIO Pin 7. Error code 127 is "command not found" and this is happening because the user account does not have permission to access the GPIO.

By adding "sudo" to each of the execute commands like this:-

...the output changes slightly to this:-

Now the error code is 1 which is a pretty non-specific Linux error, but I think it is being returned because I'm not providing a password after sudo. Obviously I don't want to code-in a password, but I can add the user to sudoers.

The "user" on the web server is called www-data, so I can open /etc/sudoers as root and add this line at the end of the file:-


Now when I refresh the page I get:-

...where the error code = 0 (no error) and each time I refresh the page, the output state/level changes.

However, it is not a great solution to allow the user www-data to run anything with root permissions. I need to find the location of the program "gpio" then restrict www-data accordingly.

I can find the path for gpio by using the "whereis" command in a terminal like this:-

whereis gpio

...which returns:-

gpio: /usr/local/bin/gpio

So back in the sudoers file I modify the previously entered line to:-

www-data ALL=NOPASSWD: /usr/local/bin/gpio

...and now user www-data has elevated permissions to control the gpio function, but nothing else.

Modifying the sudoers file

The sudoers file sets the security level sudo (super-user do this) policy. Normally a user issuing "sudo" is then asked for a password. But you can control this behaviour by editing the /etc/sudoers file.

You can do this on the RaspberryPi by navigating to /etc using the file manager, then selecting "Open current folder as root" from the tools menu, and then right-click to open sudoers with LeafPad.

People will tell you that the only way to edit sudo is by typing visudo in a terminal. This editor locks the file, stopping multiple user edits, and also checks for errors before the file is saved. But hey! this is a RaspberryPi, not an international banking system!

Changes to /etc/sudoers take immediate effect, so you don't have to reboot to test changes.

What next?

The next step is to build a useful (or maybe just an interesting) application...

No comments:

Post a Comment