Raspberry Pi Web Server – RGB LED Control Over The Internet

Posted on Posted in Hardware, Software

Project Overview

In this project I use a Raspberry Pi 2 Model B and connect a tri-colour (RGB) light emitting diode (LED) to its GPIO ports. Then I will set up the Pi to became a web server. The .jsp front page has 3 sliders where the user can adjust the brightness of the red, green and blue colours. All user actions are handled with AJAX and sent through WebSocket API (SockJS library) to Java’s servlet; here it gets processed and visualized. My goal is to achieve all this with Java (Spring Boot) and Pi4J library.

Supported Devices

I developed this tutorial on a Raspberry Pi 2 Model B, however it should work on the following models too (not tested).

  • Raspberry Pi Model A+
  • Raspberry Pi Model B+
  • Raspberry Pi 2 Model B
  • Raspberry Pi 3 Model B
  • Raspberry Pi 3 Model B+
  • Raspberry Pi Zero
  • Raspberry Pi Zero W

Component List

List of components required for this project:

  • 1 x Raspberry Pi 2 Model B
  • 1 x 5mm RGB LED
  • 3 x Resistors (see the values later)
  • 1 x Solderless Breadboard
  • 4 x Male to Female Jumper Wires

More information about the hardware setup will be detailed below.

Setting Up The Raspberry Pi

Operating System & Network Setup

The operating system I choose was Raspbian Stretch Lite. The Lite means that the OS hasn’t got desktop interface – not required for this project – therefore it takes less space on the memory card. You can download it from the vendor’s website for free. The installation is fairly simple and straight forward. First you need to burn the image on a SD card. I used Win32 Disk Imager.

Burning Raspbian Stretch with Win32 Imager

When it’s done, pop the card into the Pi and wait until the operating system is booted up. The default username is pi and the password is raspberry. Before continue, it is recommended that you update the operating system.

This could take a few minutes.

I was planning to use the Raspberry Pi as a web server. Therefore it should have its own static IP address. The system default is dynamic, so every time the OS reboots we could end up with a different IP. You can use the IP address which was given by your DHCP server and set it as a static address. This will avoid any conflict on your network. You can check the network configuration with the ifconfig command.

Result:

On my network the dynamic IP address was 192.168.0.10. Later I will use this as a reference address. You can find yours after the inet label. Now we can set the IP as static by editing /etc/dhcpcd.conf.

Add the following lines at the end of the file:

static routers=192.168.0.1 is my gateway’s (router’s) IP address. static domain_name_servers=8.8.8.8 8.8.4.4 represents the DNS servers. They are Google’s Public DNS servers.

As I’m using a lite version of the OS; there is no need for a screen and keyboard to be connected to the Pi. Everything can be done via SSH which will leave us with only 2 cables connected to it; power supply and network. SSH server is disabled by default but you can enable it from the system’s configuration.

  1. Here select Interfacing Options
  2. Navigate to and select SSH
  3. Choose Yes
  4. Select Ok
  5. select Finish

It’s time to reboot to see if it worked.

You can connect now to the Raspberry Pi via SSH by using a client software. My favourite one is PuTTY. For the Host Name use the static IP on port 22. The credentials to login are the same.

Raspberry Pi SSH Access

Installing Required Packages

During the development, you will need to access to the Raspberry Pi via FTP to be able to upload files to it.

Installing the FTP server:

After successful installation, the FTP server should be up and running. It can be reached via the Pi’s static IP on port 21. The login credentials are the same again.

Now at this point, we need to install 3 additional packages too.

Java JDK

For this project it is essential to have Java JDK installed and properly configured on the system. As a start we can install Oracle Java JDK.

JAVA_HOME environmental variable must be added to the global PATH so all Java executable files can be reached from any directories. We need to edit ~/.bashrc and add the following lines at the end of the file.

JAVA_HOME is the name of the environmental variable. This is used by applications as the symbolic link to Java’s installation directory. Declared every time when the system boots up. During the boot process $PATH is extended with $JAVA_HOME/bin. The /bin directory contains the executable files which becomes global and the user can access it form any locations.

After a reboot you can check if the setup us correct by checking Java compiler’s version.

Java Version (javac -version)

WiringPi

WiringPi is a necessary package for Pi4J Java library. Before installing it, we need to install GIT on the Raspberry Pi because the package will be pulled from GitHub.

Now the WiringPi. Please not the capital ‘P’ in the address.

This is how you can check if the installation was successful.

WiringPi Version

Maven

Maven is a build automation software. It handles all the required packages (dependencies) and put all the source files together. Very efficient tool. The compile process should happen on the Raspberry Pi. Therefore Maven needs to be installed on it too.

On the Pi, download and extract the source code.

Move the extracted directory to an appropriate location.

Maven can be run from anywhere by setting an environmental variable to its location. We can create this shell script which will launch during the boot process…

…and add the following lines.

Log out from the Raspberrey Pi and back so you can test the script.

If you have it working, then you should see Maven’s version number.

Maven Version

Setting Up The Pi’s Hardware

For this tutorial, we are using the WiringPi/Pi4J library. It has a different numbering for the GPIO pins. To find out more about the pin numbering, visit WiringPi’s website.

About The Components

RGB LEDs have four connections; three of them for the colours and one is the ground. The LED I chose is a 5mm Diffused RGB LED with common cathode connection. Common anode LEDs will work too, however the wiring differ to the other type.

Common Cathode vs Common Anode

Instead of diffused LED, clear ones can be used as well. The diffused LED’s lens look cloudy which helps the light to diffuse more evenly than the clear lens.

The LED requires 3 resistors which values depend on the manufacturer. This can be calculated from the specifications of the LED. The required values are the supply voltage (V), forward voltage (V) and the forward current (mA). The supply voltage is the same as the Raspberry Pi’s output which is 5V. Forward voltage and current are the values specified by the manufacturer and various to each makes. Also with the RGB LEDs, the red connection has a lower value than the green and the blue. The one I have has the following values:

  • Red: 1.8V / 20mA (0.02A)
  • Green: 3.1V / 20mA (0.02A)
  • Blue: 3.1V / 20mA (0.02A)

Use the formula below to determinate the required resistors.

R = (Vs – Vf) / If

  • Vs: Supply voltage (V)
  • Vf: Forward voltage (V)
  • If: Forward current (A)

Based on this my resistor values are:

  • Red: (5V – 1.8V) / 0.02A = 160Ω
  • Green: (5V – 3.1V) / 0.02A = 95Ω ≈ 100Ω
  • Blue: (5V – 3.1V) / 0.02A = 95Ω ≈ 100Ω

Wiring

As mentioned above, there are 2 different type of RGB LEDs; common cathode and common anode. The wiring is really similar. The only difference is that the common cathode’s (-) second pin is connected to the Pi’s ground and where the common anode (+) version is connected to the 5V power pin. In my tutorial I’m using a common cathode LED.

Common Cathode RGB LED Raspberry Pi

RGB LED Wiring to Raspberry Pi

The 3 RGB pins are wired to the Pi’s GPIO connectors. With WiringPi/Pi4J library the GPIO pin numbering is not the same as the manufacturer defines. We are using these numbers to set pins for the LED connections.

LED Pin Name (WiringPi/Pi4J) Physical Pin
RED GPIO 27 36
GROUND GND 34
GREEN GPIO 28 38
BLUE GPIO 29 40

You can pick different pins. You just need to modify the GPIO numbers in the source code accordingly.

For detailed pin layouts visit Pi4J website.

About The Application

To be able to control the RGB Led connected to the Raspberry Pi we will need to create some sort of application. I decided to use Java Spring Boot with embedded Tomcat Servlet. The advantage of this, is that it doesn’t require any third party server installed on the host (Raspberry Pi). Everything is packed into one WAR file (Java Classes, servlet, application settings,…). Pi4J library with WiringPi are responsible to control the Pi’s GPIOs. It uses software PWM (Pulse Width Modulation) to adjust the brightness of the colours of the RGB Led. The user input on the front web page is handled by the WebSocket communication protocol. It is a two-way channel between server and client. On the client side SockJS, a Javasript library is implemented.  The final application will only contain a .war file and by launching it on the Pi, the Tomcat servlet will be initialized.

Creating The Java Project With Maven

I presume that you have Java JDK 8 and Maven installed with the required environment variables on the developing machine. For this tutorial I used Eclipse IDE for Java with included Maven packages. Still an additional plugin from Eclipse Marketplace is required:

  • Eclipse Java EE Developer Tools 3.11 (by The Eclipse Foundation)

Template Setup

Create a new Maven Project and for archetype select maven-archetype-webapp.

On the next window, complete the required project details.

This will create a webapp template for the Maven project. At this point Eclipse will show some errors. You can ignore them for now.

It is important that the project has the correct settings. First we need to change some properties. Within the project’s properties – when you try to set the Dynamic Web Module version to 3.0 and Java to 1.8 – Eclipse may give you an error and the changes won’t get saved.

To bypass this you need to edit the org.eclipse.wst.common.project.facet.core.xml file directly. It can be found in the project folder under .settings. The file should look like this:

After saving the file Refresh the project.

Now we are ready to create the project’s folder and file structures, which at the end will look like this:

Spring Boot with Embedded Tomcat Servlet

First edit the pom.xml (Project Object Model) file. It contains the configuration details of  the Maven project.

Create the java folder within src/main/. This folder is not created with maven-archetype-webapp template. Once it’s done, right click on the new java folder and create a new Package.

Now right click on the newly created package com.gellai.raspiwebled and add a Class. I named it Application.java. This java class will contain our main method and will initialize the Spring Boot Application.

Also we add the PageController.java which is a controller to map HTTP requests. Here we only deal with the index request.

Also we have to tell the application about the source folder and the extension of the web page file(s). Let’s use the base folder which is src/main/webapp/ and the general JavaServer Page extension .jsp. We create a file and name it application.properties in src/main/resources/.

I added server.port = 8080 which defines the access port of the running web application. This is optional and you can choose any other ports. The default is port 80.

To make index.jsp the welcome page, we edit the web.xml within src/main/webapp/WEB-INF/. The index.jsp was created with the template in src/main/webapp/.

You can now right click on the project and Maven then Update Project… or Alt + F5. This should clean all your error messages.

At this point you should have a working web application which you can test.

  1. Connect to the Raspberry Pi via FTP using your favourite client software
  2. Copy the whole Maven project’s folder on it
  3. Login to the Raspberry Pi via SSH

In SSH navigate to the project’s folder and build the package with this Maven command:

This will automatically download and compile the application on the Raspberry Pi. When it’s done navigate to the target/ directory. There, you should see the newly created raspiwebled.war file. You can run it to see if everything is working.

Java Spring Boot Loading Screen

Java Spring Boot Loading Screen

When the application is fully loaded the message “Started Application in...” will be displayed.

You can open a browser and navigate to the Pi’s IP address, which is in my case is: http://192.168.0.10:8080

Java Servlet Hello World Test

The “Hello World!” message indicates that your Tomcat servlet is running.

Extending Java Servlet With WebSocket

To communicate with the LEDs in real time via the web browser we need to add WebSocket to the Servlet. It helps to establish a tunnel between the front page and Pi4J library.

Let’s create the WebSocket’s configuration file RpiWebSocketConfig.java.

In this script I configured the endpoint with the URI "/gpio-websocket". On the front end the connection is established by SockJS which is a Javascript library and a WebSocket client. It also provides intelligent fallback options for older browsers. The class of the WebSocket handler is also instantiated here within a new method annotated as @Bean.

We can create the handler class RpiWebSocketHandler.java – just as declared above.

The handler as its name suggests handles the connection, incoming messages, packets and errors. After the LED’s GPIO controller class is instantiated and the connection is established and opened, the WebSocket session is set.

The next class is about to control the LED via the Pi’s GPIO by implementing the Pi4J library. LedGpioController.java This is where the actual colour change is happening. The brightness of a colour is set with software PWM. If you wish to change the GPIO pins on the Pi, you can do it here.

The class constructor initializes the pins of the RGB LED and sets the maximum PWM value to 100 as well as its default value to 0.

The session ID of the established WebSocket connection is registered. I use this session to return the value of the PWMs to the front page in case the browser gets refreshed.

public void setLedsPwm(String payLoad) method is responsible for the control of the brightness of red, green and blue. The payload is a JSON object, which therefore needs to be mapped to get the values. It is done with LedValueMapper.java.

The Front Page, CSS and JavaScript

In nutshell, that was it all about the backend. Here we will create the index page, style it with CSS and and write all the JavaScript functions to be able to open a WebSocket session and control the LEDs via it.

Edit the index.jsp file from src/main/webapp/ folder.

The frame of the front page is very simple and short. This is the only page we need to interfere with the LEDs. To dress it up, some CSS is needed.

Place style.css style sheet within src/main/resources/static/css. The folder needs to be created first.

Now the index page has some sort of layout and colour but it doesn’t work yet. This is where JavaScript comes to picture along with the SockJS functions. The source code is located in the file here: src/main/resources/static/js/app.js.

During the page initialization, connection (session) is set up with SockJS library. When the user makes an adjustment to one of the sliders, the current values of all the sliders are sent to the WebSocket server. It gets processed there. In case of browser refresh or closure the PWM values of the LEDs are remaining within the Raspberry Pi – if the Pi is not powered off or the application stops meanwhile. After page reload, the current values are retrieved and the sliders are set accordingly.

Launching The Application

Upload the finished application to the and connect to it via SSH. Navigate to the project’s folder and build the source code with Maven.

Again, launch raspiwebled.war from the target/ directory and wait until the application is fully loaded.

Open a web browser and navigate to the Pi’s address, just like before. If everything went well the following page should show up.

Raspberry Pi Web LED Welcome Page

RGB Colour Samples

Setting Up The Router

Now we have a running webserver, however it can only be accessed from the local network. My original plan was to be able to control the LED from anywhere via the internet. All we need to do is  set up a port forwarding on the router. So all the request made externally on port 8080 are redirected to the Raspberry Pi on the internally network.  This is various on different make routers; its user manual can explain how to do it.

Sample of port forwarding setup on a Netgear router:

Netgear Router Port Forwarding

Also a big advantages if you have a static IP from your ISP. Dynamic will do but after restarting the router the external IP will change. You can find out your current external IP from this website https://www.whatismyip.com. So if my IP comes up as 160.153.129.223 then I need to go to 160.153.129.223:8080 to open the Pi’s website. It all depends on what port is forwarded to 8080.

Download the source code from

 

Leave a Reply

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