Friday, 22 February 2013

Controlling the Berry Clip/Raspberry Pi from a Java Web Service/Servlet

I wanted to see if I could control the GPIO port on the Raspberry Pi from a Web Service, since the Berry Clip is pretty much a solid piece of kit I and i can not connect it up wrong I decided that getting this working was a good first step and I could interface my own circuits after I had proved my concept.

I decide to use the Jetty Servlet engine. This is a light weight web server and would take less resources than using an instance of Apache Tomcat. This was downloaded from http://www.eclipse.org/jetty/ and installed onto the Pi .Once installed jetty can be started going to the installation directory and issuing the command:

sudo java -jar start.jar

Jetty on it's own does not require sudo access but to access the GPIO port on the pi requires root. This is  not a good idea for any production environments or internet facing services.

I then created my servlet code and configuration in Eclipse on my desktop pc. The code was exported from eclipse as a war file and then copied into the webapps directory of jetty on the pi. If jetty is running it will scan this directory and automatically install the servlet. I found if updating the war file it was a good idea to restart jetty or strange errors seem to creep in.

I added a basic html form to allow the number of the LED to be activated to be entered by the user and posted to the servlet.
The form allowing users to select an LED

This is accessible at :8080/BerryPi_Servlet/


The code is once again built using the Pi4J library from the Pi4J Project (http://pi4j.com/).

The Eclipse project including the exported WAR file can be found on bitbucket:

https://bitbucket.org/chughes42/berryclipws/src


The bulk of the java code is shown below

BerryPiWS.java

package com.qubecad.pi.berrypiws;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;

/**
 * Servlet class BerryPiWS to Control the Berry Clip for the raspberry Pi
 * available from http://www.raspberrypi-spy.co.uk/ 
 */

public class BerryPiWS extends HttpServlet {
 private static final long serialVersionUID = 1L;
 GpioController gpio;
 GpioPinDigitalOutput pina;
 GpioPinDigitalOutput pinb;
 GpioPinDigitalOutput pinc;
 GpioPinDigitalOutput pind;
 GpioPinDigitalOutput pine;
 GpioPinDigitalOutput pinf;

 /**
  * Default constructor.
  */
 public BerryPiWS() {

  GpioController gpio = GpioFactory.getInstance();

  // Set up the pins and set low to start
  System.out.println("Setting up GPIO Pins for output");
  pina = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_07, "Pin A",
    PinState.LOW);
  pinb = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_00, "Pin B",
    PinState.LOW);
  pinc = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_03, "Pin C",
    PinState.LOW);
  pind = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_12, "Pin D",
    PinState.LOW);
  pine = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_13, "Pin E",
    PinState.LOW);
  pinf = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_14, "Pin F",
    PinState.LOW);

 }


 /**
  * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
  *      response)
  */
 protected void doPost(HttpServletRequest request,
   HttpServletResponse response) throws ServletException, IOException {
  // get the number of the LED to turn on and print to console
  String action = request.getParameter("action");
  System.out.println("action=" + request.getParameter("action"));

  try {

   // activate the request light, pause and reset.
   if (action.equals("1")) {
    System.out.println("A high");
    pina.high();
    Thread.sleep(1000);
    pina.low();

   } else if (action.equals("2")) {
    System.out.println("B high");
    pinb.high();
    Thread.sleep(1000);
    pinb.low();

   } else if (action.equals("3")) {
    System.out.println("C high");
    pinc.high();
    Thread.sleep(1000);
    pinc.low();

   } else if (action.equals("4")) {
    System.out.println("D high");
    pind.high();
    Thread.sleep(1000);
    pind.low();

   } else if (action.equals("5")) {
    System.out.println("E high");
    pine.high();
    Thread.sleep(1000);
    pine.low();

   } else if (action.equals("6")) {
    System.out.println("F high");
    pinf.high();
    Thread.sleep(1000);
    pinf.low();

   }

  } catch (InterruptedException e) {

   System.out.print("Exception ");
  }

  // display the LED select form on the return page

  PrintWriter out = response.getWriter();

  String pagehtml = "";

  // if there was a valid LED number display a message

  if ("123456".contains(action)) {
   pagehtml = pagehtml + "
LED number " + action + " selected
";

  }
  String pagehtmlform = "
"; out.println(pagehtml + pagehtmlform); } }
Links:
The Pi4J Project http://pi4j.com/
Raspberry Pi Spy http://www.raspberrypi-spy.co.uk/berryclip-6-led-add-on-board/
Jetty Web Server http://www.eclipse.org/jetty/

1 comment:

Khristian said...

In Debian systems, you usually need to be a member of group "dialout" to use serial ports. Have you tried this yet?