Control Raspi GPIO Pins In The Browser

Now instead of wrangling Python or PHP to do your bidding, [Eric] came up with a way to control the GPIO pins on his Raspberry Pi in a browser.

[Eric] calls his project WebIOPi, and it’s the perfect tool if you’d just like to blink a LED or control a relay over the internet. Simply by pointing his browser to the IP of his Raspi, [Eric] can turn GPIO pins on and off, directly from his desktop browser.

All the code for WebIOPi is available on [Eric]’s Google code page. The UI of [Eric]’s project is fully customizable, so it’s entirely possible to control your garage door from a smart phone simply by loading up a web page hosted on your Raspi and pressing a button.

Right now WebIOPi is only able to turn GPIO pins on and off. That will change as [Eric] implements UART, SPI, and I2C in his project, making it possible to do a lot of cool stuff without having to write much – if any – code.

30 thoughts on “Control Raspi GPIO Pins In The Browser

  1. What would be the easiest way to run a solid state relay off of this? Currently I have one running directly from a serial port using the dtr and rts lines with a small program that toggles it, but this would be much more simple especially for a webpage. Any ideas?

  2. Use one of the pins (say, pin 3) as the input to your SSR, same as the DTR/RTS lines. Pin 3 will be 0 or 5v (iirc) depending on how you set it in the GUI. If you are using DTR/RTS after a TTL to RS 232 adapter, you’ll need to build yourself a single pin adapter to connect to pin 3.

    Poof, all done.

  3. This is a PHP wrapper around the sysfs gpio interface… I don’t have a raspberry pi to check.. but the gpio nodes are only writeable by root on all of my machines.. so does this mean you have to have whatever is running PHP as root to run this thing? :/

    1. @candido, yes you’re right :( If you don’t want PHP to be root, you can use the standalone python version. I’m looking for a way to remove the need of www-data user to be in the sudoers, but it will certainly require another process

      thanks hackaday for the post !

      1. Just realized I should have probably added a bit more detail…sorry.

        I’d probably only change permissions on /sys/class/gpioX/value. If you’ve got a project that’s controlling a relay, no need to let your script/web service (or bugs within them ;) ) touching other items, like active_low, or direction.

        You could also consider adding an init script to configure your gpio sysfs entires (direction, level, edge, etc), and set the permissions. I haven’t used a Rasberry Pi, but I imagine they have /etc/rcX.d/ entires (linking to /etc/init.d scripts). Drop a script in /etc/init.d/, and a symlink, such as /etc/rc5.d/S50my-gpio-setup to point to it.

    2. it’s a linux, so yes we can change the permissions but it’s not so easy. the kernel creates files for each GPIO when enabling them, and we need ownership on that files too. enabling gpios at the boot process doesn’t sound good for me. I want something more flexible with as less as possible configuration outside the web.

      1. Are you sure the sysfs nodes aren’t populated by the time init scripts are created? I’m pretty sure they are…but I could be wrong. :)

        I really think a quick udev script is the tool for the job, as far as dynamically setting up your gpioX/* permissions. I’m a fan of the principle of least privilege; having www-data in your sudoers is just asking for trouble. ;)


      2. $ whoami
        www-data
        $ groups
        www-data gpio
        $ ls -l /sys/class/gpio
        total 0
        --w--w---- 1 root gpio 4096 août 22 23:52 export
        lrwxrwxrwx 1 root gpio 0 août 22 20:08 gpiochip0 -> ../../devices/virtual/gpio/gpiochip0
        --w--w---- 1 root gpio 4096 août 22 23:53 unexport
        $ ls -lh /sys/devices/virtual/gpio
        total 0
        drwxr-xr-x 3 root root 0 août 11 00:12 gpiochip0
        $ echo 0 > /sys/class/gpio/export
        $ ls -l /sys/class/gpio
        total 0
        --w--w---- 1 root gpio 4096 août 22 23:54 export
        lrwxrwxrwx 1 root root 0 août 22 23:54 gpio0 -> ../../devices/virtual/gpio/gpio0
        lrwxrwxrwx 1 root gpio 0 août 22 20:08 gpiochip0 -> ../../devices/virtual/gpio/gpiochip0
        --w--w---- 1 root gpio 4096 août 22 23:53 unexport
        $ ls -lh /sys/devices/virtual/gpio
        total 0
        drwxr-xr-x 3 root root 0 août 22 23:54 gpio0
        drwxr-xr-x 3 root root 0 août 11 00:12 gpiochip0

      3. @trouch: From what you posted there, I assume the issue you’re facing is that gpio0 is root.root, instead of root.gpio.

        I may have not been clear above…my apologies. What I meant to suggest is to have an init script (which runs at boot) export the gpios you want to provide via the web interface, and then set the group permissions on the relevant gpioX/’s. From there, your web app should still have all the flexibility you need.

        Below is a script intended to show this better. Granted, I haven’t tested it as I don’t have a platform on me right now. (I can check in Fridayish if something’s wrong with this.) Let me know if I can clarify any further. Personally, I find this easier than hacking up a complex udev rule…


        #!/bin/sh
        #
        # init_gpios.sh
        #
        # This script is an example of how one might export some GPIO pins and
        # allow members of a "gpio" group the ability to read/write gpioX/direction
        # and gpioX/value
        #
        # Drop something like this in /etc/init.d, and then add a symlink in the
        # appropriate /etc/rcX.d directory (for example, /etc/rd2.c/S50init-gpios.
        #
        # I don't have an embedded Linux platform at home with me at the moment,
        # so I haven't tested this. If something's wrong please do correct me or
        # feel free to ask!
        ###############################################################################

        # Define which GPIOs you want exported and made accessible to users in the
        # gpio group
        GPIO_0_LIST="1 3 7 31"

        for n in $GPIO_0_LIST;
        do
        echo Setting up /sys/class/gpio/gpio$n...
        echo $n > /sys/class/gpio/export

        # Rather than grant permissions to everything, we'll just allow
        # members of the gpio group to change the direction and value.
        # This assumes your system already has a gpio group
        #
        # iirc these are actually symlinks back to ../../devices...
        # if this doesn't work feel free to poke me and I'll look into
        # it today/tomorrow. (Or I'll post back when I get a chance)
        chown root.gpio /sys/class/gpio/gpio$n/direction
        chown root.gpio /sys/class/gpio/gpio$n/value
        done

        Please don’t feel like I’m harrassing you here by the way — I just really want to stress to all my fellow Hackaday’ers that granting www-data root privilages via a “www-data ALL=(ALL) NOPASSWD: ALL” in /etc/sudoers is *really* a dangerous practice. If web application has a remote command execution (even worse, a shell injection) vulnerability (e.g., [1])

        With that said, keep up hackin’ dude — I look forward to seeing the cool stuff you do with your Raspberry Pi! :)

        [1]

      4. Oh good gracious, how did I fail to proof read so miserably. There should be intendations in that script, and here’s a completed statement:

        If web application has a remote command execution (or even worse, a shell injection) vulnerability (e.g., https://jhalderm.com/pub/papers/dcvoting-fc12.pdf), an attacker can effectively gain www-data access.

        However, if one does something like making system calls (generally frowned upon) with a sudo (and a NOPASSWD:ALL in /etc/sudoers), that attacker now has root.

  4. Excellent work there Eric.
    I’d definitely look at using this if you can get a whole bunch protocols working too, plus some way of soft configuring it for particular I2C/SPI/UART devices.
    As far as I’m concerned, the more that can be ‘webified’ the better. I dream of the day that complex software such as, I dunno, Photoshop, can be fully webified, without any compromises that is.

    1. If those have a sysfs interface for their GPIO then you should be able to “port” this… but it’s written in PHP so you’ll have all of that overhead for what is basically echo “1” > /sys/class/gpio/blah/blah. Probably better to write something in C with a little in-built webserver.

  5. Set resistor depending on the gain of the transistor used.
    So if it is a typical NPN small signal ie BC548 with gain of around 200, a 1K should enable a current of approx. 0.88 A assuming that the transistor can handle it.
    You want to set the resistor value to achieve hard switching so that the dissipation in the transistor is minimum, consult the datasheet.

  6. Excellent work. I did something like this myself (just to get a basic understanding what happens with GPIO), but your webui looks far better, so im happy to use your project from now on. Thanks for sharing, ill keep an eye on your project site!

  7. very nice put can you run it from php direct and not needed this sql database,
    if you can make script like

    and in open_close_ports.sh
    you can use above code and may add options like
    open_close_ports.sh -port 1 -do open

    thanks you very much

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.