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).


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.


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:


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:


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:


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:


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


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:


Substitute the values with your own. Examples:


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!





Controlling the Raspberry Pi’s GPIO pins from a web browser — 41 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
    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.


    • 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!

  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 : This GPIO pin already exists: GPIO 1
    Should I “close” something on the Java code before quiting the application ? Thanks.


    • 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:
      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.


  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.

  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 and then compile it over my pi, using the {javac -classpath .:classes:/opt/pi4j/lib/’*’ -d .}
    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.

  12. hi,
    I have followed all your steps mention in tutorial. in last step when i am trying to access from browser i am getting the following error

    HTTP Status 500 – java.lang.RuntimeException: Unable to open GPIO export interface: Permission denied

    can you please help me on this issue ?

    • Hi Avinash!

      Tough one. Some access rights are not set well, but I can’t guess what exactly… Your Tomcat is trying to execute something which bumps into an access/privilege problem. My best guess is that the Pi4J library is trying to gain access to the GPIO interface but for some reason it fails. You should make sure that you have the latest Java and latest Pi4J on your system. If that does not help, please try to ask the Pi4J developers what they think about this. They might have a quick answer.

  13. Hi and thanks for share knowledge with us.
    I’m a really beginner with Pi and faced a problem. I’m tomcat6 (also tried with 7), jdk7 and when I tried to access my URL on tomcat, I receive this answer:


    Any ideas on how to solve this?

    Thanks again

    • Sounds like you’re using a newer version of Pi4J in which that method is no longer supported. Check the Pi4J documentation to see if the GpioFactory.getInstance() is still supported.

      • Hi iqjar, a local friend, who knows much more than me about Java helped me. The solution was to extract from pi4j-core.jar a file called and setted on /etc/default/tomcat7 to point to this file. On my example was something like this:

        JAVA_OPTS=”-Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC -Djava.library.path=/home/pi/lib/soft-float/”

        where my .so file is on /home/pi/lib/soft-float/.

        Thanks for your help.

  14. Hello,

    I’m a beginner with the raspberry pi and would like to know whether you are only able to control devices that’s in a LAN or from anywhere you have internet access?

  15. Hello

    I am stuck with the following error(s) after step 2:

    Multiple markers at this line
    The type java.util.Map$Entry cannot be resolved. It is indirectly referenced from required .class files.
    The type java.util.function.Consumer cannot be resolved. It is indirectly referenced from required .class files
    The type java.util.Map$Entry cannot be resolved. It is indirectly referenced from required .class files.

    I get this error on the default Vaadin code. I did include yhe jar file in the lib folder of webcontent. Can you please help me with this problem?


    Help would really be appreciated.

  16. Hi there,

    thanks a lot for your good Raspberry Pi/WiringPi/Tomcat 7/Java cooperation example, it indeed helps me!
    The only problem I have left it that the servlet just runs once blinking my LEDs. I tell the Gpio singleton instance created using the getInstance() call system to shutdown at the end of the process() method using gpio.shutdown();

    But the systems does then no longer work when I start the servlet the second time.

    Can you please give me a hint what I am doing incorrectly?

    When I run my program as a standalone app, it runs multiple times without a problem…

    Thx for help,

    Dirk Schesmer

    • Hello Dirk!

      I remember that I too has some problems with the shutdown, but I can’t really remember what it was, as at least 500 days have passed since I worked with this code… I wish I could help you, but my memory does not serve me well… You could ask the guys from the Pi4J development team, maybe they know what’s wrong. If you find out the answer, please post it here in a comment, somebody else might find it useful too.

      • Hi iqjar and Dirk

        i am also facing the same problem
        The LED is blinking for the first time and when I run for the second time it gives an error saying “gpio pin already exist gpio 1 error”

  17. Pingback: Getting LED strips to work with Beagleblock Black | Life in Linux Kernel

  18. Hello,
    i’m trying to run this application on a RPi 2 Model B. Raspbian is fresh installed and Tomcat 7 is running.
    I have installed Tomcat and JDK (with apt-get install openjdk-7-jdk and apt-get install tomcat7) and application is deployed in /var/lib/tomcat7/webapps.
    Everything is fine (application is showed in browser) but when i click the (On/Off) button nothing happens.
    I have connected LED + to a pin 17 (GPIO pin 0) and LED – over resistor to a pin 3 (GND). I can send you a picture with my setup if needed.

    Am i missing something here?

    Thanks for your response.

  19. Thank you iqjar for this post.

    I am testing your RaspberryPiGPIOExample01.war on my Raspberry Pi B+ with java version 1.8.0_65 and tomcat8, NOOBS v1.9.1.

    The webpage was loaded ok but I did not see any thing on the page, no button, no text … ???? So I can not click the button.I press F5 to refresh the page then I receive the HTTP Status 500 – This GPIO pin already existes: GPIO 0.

    Please help!!!
    Thank you in advance

    • Hi! Well, it looks like something is behaving differently on your computer with your setup. Unfortunately the only way I could help you with this is to deploy this whole thing all over again and debug it, but I won’t be able to do any such thing for quite a few weeks from now due to medical problems in my family and travel plans. If you have experience with debugging software, that’s the way to go. I’m sorry, but I can’t offer any truly valuable help right now.

  20. Hi, Thanks for such a nice tutorial.
    I have followed every step but when I run it on Raspberry Pi 3 (Model: B), it gave me following error:

    HTTP Status 500 – java.lang.UnsatisfiedLinkError:com.pi4j.wiringpi.Gpio.wiringPiSetup()I

    root cause:

    java.lang.UnsatisfiedLinkError: com.pi4j.wiringpi.Gpio.wiringPiSetup()I
    com.pi4j.wiringpi.Gpio.wiringPiSetup(Native Method)

    what can possibly go wrong??

    • Hi! Unfortunately it’s hard to know from this what’s wrong… I have no idea… it would have to be debugged… or try asking the guys at Pi4J, maybe they know something…

Leave a Reply

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

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