Controlling the Raspberry Pi’s GPIO pins from a web browser

Wouldn’t it be cool to control things in your home from a web browser? I mean turn on and off the lights, adjust the music volume, open the gate or the garage door, start the garden sprinklers or give the dog a portion of food just by clicking a button in a web browser, perhaps from your smart phone? It certainly would be very exciting! And it is not only possible, but it can also be relatively easy. All you have to do is get a Raspberry Pi, connect some custom hardware which can do your custom task (switch lights on and off, drive motors, send wireless signals to other devices, etc.) to its GPIO pins and write some software which can control the Raspberry Pi’s GPIO pins based on requests received from a web browser. The hardware part heavily depends on what you wish to achieve exactly and will be different for every task. In this article we will address the software part, we will describe a relatively simple way of talking to the Raspberry Pi‘s GPIO pins from a web browser.

 

Raspberry Pi Cup

 

Used technologies/languages/frameworks/tools/applications

As you might have already guessed from the image above, we are going to write Java programs, which will run under a Java web server such as Tomcat and listen to requests from browsers. For the user interface that will appear in the browser we are going to use the excellent Vaadin framework. Our weapon of choice for accomplishing the communication with the Raspberry Pi‘s GPIO pins is a very nice little library called Pi4J.

I’m not going to talk about the benefits of using Java, as that may turn into an infinite discussion, but I am going to say a few words about the components that make up our application.

The Pi4J project is a blessing for those of us who prefer to program the Raspberry Pi‘s GPIO pins in Java. It is not only very straightforward to use and easy to understand, but also well structured. I personally prefer to use it because it offers a very clean object-oriented approach to talking to the hardware. Pi4J is essentially a Java wrapper for the WiringPi library (which is written in C). The Pi4J team runs a very nice website which is full of useful resources and contains everything you need  to know for making a start with Pi4J.

The Vaadin framework is an easy and yet powerful tool to create user interfaces for Java web applications. I am not a Java expert by far and I don’t know how many other good frameworks of this type are out there. What I do know is that with Vaadin you can write nice, clean UI code very fast and that the resulting UI looks good, so it is my preference to use it.

 

Application structure

  1. The Vaadin user interface receives user actions from the web browser.
  2. The event handlers of the Vaadin UI components call the Java user code in our web application, which runs on the Tomcat sever.
  3. Our Java code translates the requests to logical GPIO operations and calls functions from the Pi4J library accordingly.
  4. Pi4J sets the states of the Raspberry Pi‘s GPIO pins as specified.
  5. The state of the hardware connected to the GPIO pins is changed (an LED is turned on/off, a relay is switched on/off, a speaker is sent a signal, etc.).

According the above steps the user action travels from the web browser, through Vaadin, our Java code and Pi4J to the Raspberry Pi‘s GPIO pins and triggers some hardware action. It is also possible to go in the opposite direction:

  1. The state of the hardware connected to the GPIO pins changes.
  2. Pi4J triggers an event based on the change.
  3. Our Java code receives an event and handles the change by modifying the state of the Vaadin user interface components.
  4. The Tomcat sever sends a response to the web browser with the modified state of the Vaadin components.
  5. The web browser displays the change on the user interface (shows a notification, changes the text of some labels, shows/hides some components, etc.).

 

Example application: Turning an LED on/off from a web browser

We will be using the simplest possible hardware for our example application: an LED connected to GPIO pin 0, which will be turned on/off by clicking a button in a browser:

Raspberry Pi model B controlling one LED

Raspberry Pi model B controlling one LED

 

Downloading and installing the prerequisites

Step 1: Download and install your preferred version of the Java Development Kit on the machine on which you are going to develop the application  In our example we will create the application on a Windows system.

Step 2: Download and install the Eclipse development environment on the machine on which you are going to develop the application.

Step 3: Install Vaadin under Eclipse. Open Eclipse and go to the Eclipse Marketplace (Help -> Eclipse Marketplace…). On the Search tab type Vaadin into the Find box and hit Go. It should find “Vaadin Plugin for Eclipse”. Install it.

Step 4: Download and install the Java Runtime Environment or Java Development Kit of your choice on the Raspberry Pi (OpenJDK for example: apt-get install openjdk-7-jdk).

Step 5: Download and install Tomcat on the Raspberry Pi (apt-get install tomcat7). Configure it to listen on your preferred port (we will use 8080).

The Pi4J library will need root privileges in order to control the GPIO pins, so Tomcat must run under the user root and under the group root. On the Raspberry Pi edit your /etc/default/tomcat7 configuration file. Find  the TOMCAT7_USER and TOMCAT7_GROUP variables and make sure they are both set to root:

    • TOMCAT7_USER=root
    • TOMCAT7_GROUP=root

Restart Tomcat: service tomcat7 restart

 

Steps to write the Java web application which listens to web browser requests and communicates with the Raspberry Pi’s GPIO pins

Step 1: Create a new Vaadin project.

In Eclipse go to File -> New -> Other… and on the window that comes up select Vaadin/Vaadin 7 Project (or Vaadin/Vaadin 6 Project or whatever other version you have installed).

Vaadin-GPIO-Project-01---Create-new-Vaadin-project

On the Next page enter a name for your new project (we will use RaspberryPiGPIOExample01). Make sure that your Configuration and Vaadin version are set correctly, than hit Finish.

Vaadin-GPIO-Project-01---New-Vaadin-project-settings

Step 2: Add the Pi4J library to your web application.

    • Download Pi4J from here. If you choose the Direct Download option (easiest), you will receive a zip file. Look inside it and find pi4j-core.jar (for example in pi4j-0.0.5-SNAPSHOT/lib/pi4j-core.jar).
    • Using your file manager of choice, copy the pi4j-core.jar file into your newly crated project’s WEB-INF/lib directory. For example if your Java work space root directory is called JavaWS, then you need to copy the Pi4J file into JawaWS/RaspberryPiGPIOExample01/WebContent/WEB-INF/lib/ (obviously you will have to use here the project name that you have chosen in the previous step).
    • In the Eclipse Project Explorer select the root of your newly created application and refresh it (F5). The Pi4J JAR file should show up under WB-INF/lib.

Step 3: Check out the default Vaadin application code that has been generated automatically. In Eclipse open the Project Explorer and look into your project’s folder, inside Java Resources/src. Open your project’s .java file. You should find something like this:

Vaadin-GPIO-Project-01---The-automaticall-generated-Vaadin-code

Notice that the init() method, which initializes the Vaadin user interface has been generated and that it already contains a label which says “Hello Vaadin user“. We will replace this label with our button which toggles the LED on/off.

Step 4: Write the code which will allow us to control the LED through the Raspberry Pi’s GPIO pin 0. This is how your code should look like:

code_RaapberryPiGPIOExample01

The code can be downloaded from here.

The first essential step in controlling our LED is to acquire an instance of the Pi4J GPIOController class, which will send the signals to the Raspberry Pi‘s GPIO pins:

GpioController gpioController = GpioFactory.getInstance();

Through this instance of the GPIOController we can now initialize (provision) a GPIO pin:

final GpioPinDigitalOutput pin =
gpioController.provisionDigitalOutputPin(RaspiPin.GPIO_00, “MyLED”, PinState.LOW);

We use pin 0, we give it the name “MyLED” and we set it’s initial state to LOW (off)

Now all we have to do in the Vaadin button’s click event handler is to toggle the state of our LED:

pin.toggle();

That’s it! You application code is now ready.

 

Deploying your web application

Step1: Export your web application from Eclipse (File -> Export…) into a WAR file:

Vaadin-GPIO-Project-01---Export-WAR-file

On the Next page make sure that it has the same name as your project and hit Finish:

Vaadin-GPIO-Project-01---Export-WAR-file-settings

Step2: Copy the WAR file to the webapps folder of Tomcat (/var/lib/tomcat7/webapps) onto your Raspberry Pi. For this purpose you can use WinSCP for example.

Step3: Restart Tomcat. This step is most likely not needed, but just in case…

service tomcat7 restart

Give it a minute or two to restart properly.

 

Testing your web application

Your application should now be ready to use. Open a web browser and type in the address bar the following line:

YourDomainOrYourIP:TomcatPort/YourWebApplication

Substitute the values with your own. Examples:

example.com:8080/RaspberryPiGPIOExample01

1:1:1:1:8080/RaspberryPiGPIOExample01

Be patient the first time you load your application, it will take a few seconds.

You should be able to see in your browser an “On/Off” button. Clicking it should turn the LED which is hooked up to the Raspberry Pi‘s GPIO pin 0 On/Off.

Have fun!

 

Downloads

 


Comments

Controlling the Raspberry Pi’s GPIO pins from a web browser — 17 Comments

  1. Sir,
    I tried to test your program; Everything went smooth. But when i test your example on Firefox, i get an error : java.lang.UnsupportedClassVersionError: com/pi4j/io/gpio/GpioFactory : Unsupported major.minor version 51.0 (unable to load class com.pi4j.io.gpio.GpioFactory)
    I create the war file on Windows 7 + eclipse (vaadin 7). I tried with Java 1.6 and Java 1.7. I installed both version of java on RPi. I get always the same error.
    Thank you in advance for your help.

    Regards,
    Gilmegviv

    • Hi there, Gilmegviv!

      Yes, I know this error. I’ve had it too. The problem is that the Java version with which the Pi4J library was built is different from the Java version installed on your Raspberry Pi. You need to find out which Java version your Pi4J library was built with and install the same Java version on Windows and on the Pi too. On Windows you need it to put together the JAR file with it and on the Pi you need it to run the program.
      Alternatively, you could try to get the sources of Pi4J form GitHub and build your own Pi4J library. That would ensure that it’s built with the same version of Java which you are trying to run it with. Obviously, this is the harder way. It would be easier if you could just find out the Java version of your Pi4J library and install the same version on your Windows machine and on your Pi.

      Let me know if it works or if I can assist you in some other way!
      Andras

  2. Hi Andras,
    Thanks for your answer. Indeed, the origin of the error was the versions of Java. As you say, the version of Java on development PC was newer than the one installed and used by Tomcat on RPi. I solved the problem by using Java 1.6 for the development of the war file on PC and on RPi, i used openjdk-7 (java-7-openjdk-armhf).
    But i am facing another problem : The application (switching on/off a led) works fine ONE time. When i try another application and come back to the LED application, the browser indicates the following error : com.pi4j.io.gpio.exception.GpioPinExistsException: This GPIO pin already exists: GPIO 1
    Should I “close” something on the Java code before quiting the application ? Thanks.

    Regards,
    Gilmegviv

    • Hello again!

      First of all, I’m happy to hear that you have managed to get around the Java version problem.
      As for the other problem related to the error when you come back to the LED application, I’ve never encountered it. Based on the error message I don’t know what might cause it. If you could provide a full call stack, perhaps I’d be able to offer more assistance.
      Also, by “coming back to the LED application”you mean that you close that browser window, do something else and reopen that browser window again?
      I don’t know if it has anything to do with your error, but check this out: http://pi4j.com/usage.html#Pin_Shutdown
      Maybe you need to shut down the pins somehow…
      Give me a more detailed call stack of the exception and I’ll hopefully be able to tell you more.

      Andras

  3. Hi Andras,
    Thank you once again for your kind mail. In fact, the pb was because the pin was “unprovisened”. Now I use gpioController.unprovisionPin(pin); when i want to quit the application, everything seems to be OK for the moment.
    And i use getSession().close(); to close the Vaadin session.
    Thanks a lot for your kind help.
    Regards,
    Gilmegviv

  4. Hi there, Gilmegviv!

    Thanks for letting me know about the conclusions you have reached! It’s good to know that not unprovisioning the pins can lead to trouble. Also, I didn’t think of calling the getSession().close() for the Vaadin session, but it makes sense totally. Good luck with your app and you’re welcome to come back here if I can help you with something or if you have something useful to share.

  5. Hi, Gilmegviv!

    I have had the same problems as you had a few months ago, and just out of curiosity, where did you call the “gpioController.unprovisionPin(pin)” function? Whenever i refresh the page I get the exception… I tried to understand your method, but I wasn’t successful…

  6. How is the performance with Tomcat7? I have heard tomcat takes a lot of memory and is very slow, but perhaps you have found optimized JVMs to use?

    • Well, I only used Tomcat7 for light projects such as the Raspberry Pi binary clock project and I have the 512 MB model. For me it worked fine, there was still free memory and the project ran fine. Tomcat startup is a bit slow (about 30 seconds I think), but other than that I did not encounter any problems. MySQL on the other hand does eat a lot of memory…

  7. Hello

    I am trying to use the PI4J via tomcat , and I followed your instructions

    in standard java software it works , in tomcat it doesn’t work and further more , I do not see any exceptions , it just gets stuck

    any ideas about which exceptions I need to catch in order to analyze the problem?

  8. Well, that’s a question that is hard to answer… Have you consulted the Tomcat log file? Anything relevant in it? What do you mean exactly by “it just gets stuck”?

  9. Hello, thanks the this great tutorial!

    I can connect the server on the browser but last step doesn’t work, server responses 404 error when i try to run RaspberryPiGPIOExample01.

    • Hi there!

      Are you able to run anything else? OR is the RaspberryPiGPIOExample01 the only one that does not run? What do you see in the server’s log files?

  10. Hello again,

    I can’t run anything. Just server responses the welcome message, not anymore. What do you mean about server’s log files? They are under /var/log/tomcat7

  11. Hi, I am beginner for pi. I am trying to understand and digest what you got going in on this post. I have installed the pi4j on my pi and jdk-7 on my pi. I ran a program that make the GPIO pin high when a button is press on the pi (used the swing GUI class). I put all this in a notepad.java and then compile it over my pi, using the {javac -classpath .:classes:/opt/pi4j/lib/’*’ -d . example.java}
    Since i can’t install eclipse on the pi, i heard it too slow etc etc.
    Lately i want to do the same thing but over the web. I have installed the tomcat7 and have it running. could you explain what should i do next. I am really lost……… thx in advance. (a link or tutorial would be great thx)

    • Hi!

      What I did was to develop the code in Eclipse on a Windows PC, also create the web java file (WAR file) on the windows machine, then coy it into Tomcat’s directory on the PI and restart Tomcat. After that the WAR file is read by Tomcat and it runs on the Pi, you can access it from the web using the YourIPOrDomainName:TomcatPortNumber/WARFileName format.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>