Interfacing with Java

Here is a Java library for interfacing Java programs (and hence also Processing programs) with mbed using the RPC. This could be used for:

  • Creating a GUI for mbed programs
  • Controlling actuators from and reading data into Java programs

Java is potentially a great choice for interfacing to mbed over a network as it can be run in a browser and across many different platforms. This page shows how to use the library to create Java applications using serial or HTTP. There are also demonstrations of how to use this library to create and deploy an Applet and how to use it in Processing.

Information

To use the mbedRPC library your mbed needs to be running code which can receive and execute RPC commands. Information and examples of this, can be found on the Interfacing-Using-RPC page. Compile and run the program for the type of transport mechanism you wish to use.

The mbedRPC Library

Here is the mbedRPC library as a jar file: mbedRPC.jar - (updated so RxTx no longer throws errors on Windows)

Here is an example of the code required to get started and flash some LEDs. This will run as a Java application.

mbedRPC_HelloWorld

import org.mbed.RPC.*;
public class HelloWorld implements mbedRPC{
	DigitalOut d1;
	DigitalOut d4;
	mbed mbed;
	
	public static void main(String[] args) {
		HelloWorld demo = new HelloWorld();
		demo.flash(10);
	}
	
	public HelloWorld(){	
		System.out.println("mbed RPC Hello World");
		//Create an mbed object for communication over serial
		mbed = new SerialRxTxRPC("COM5", 9600);
		//Or:   mbed = new HTTPRPC("http://192.168.2.2")
		
		//Create new Digital Outputs on the mbed
		d1 = new DigitalOut(mbed, LED1);
		d4 = new DigitalOut(mbed, LED4);
		
	}
	public void flash(int n){
		
		for(int i = 0; i< n; i++){
			//Call the DigitalOut objects' methods 
			d1.write(1);
			d4.write(0);
			wait(500);
			d1.write(0);
			d4.write(1);
			wait(500);
		}
		mbed.delete();
		System.out.println("Complete");
		
	}
	//A function to create a wait
	public static void wait (int n){
        long startTime,currentTime;
        startTime =System.currentTimeMillis();
        do{
            currentTime = System.currentTimeMillis();
        }
        while ((currentTime - startTime) < n);
	}
}

And here is this class for download: HelloWorld.java

The Code API

The aim in writing the library has been to mirror the mbed API so that programming in Java is very similar to programming for mbed.

The first thing you have to do is import the library into your program. Note that to do this you need to place the Jar in the Java library folders or if you're using an IDE then add it to the build path for that project. If you want to distribute the project you produce then you'll need to package this jar with it.

import org.mbed.RPC.*

You then need to create your class. To assist in using the mbedRPC library implement mbedRPC in the class declaration

public class HelloWorld implements mbedRPC{....

The next step is to create an mbed object which sets up the communication and knows how to execute RPC methods. You can set this up using different transport mechanisms, currently serial or HTTP.

SerialRPC mbed = new SerialRPC("COM5", 9600);
OR:
SerialRxTx mbed = new SerialRxTx("COM5", 9600);
OR:
HTTPRPC mbed = new HTTPRPC("http://192.168.2.2");

For more information on using serial in Java see below.

You can now create objects on mbed. This is done in almost the same way as if you were programming on mbed but as well as specifying the pins you must also pass in the mbed object for the mbed you want to create the object on.

DigitalOut d1 = new DigitalOut(mbed, LED2);
DigitalOut d2 = new DigitalOut(mbed, p20);
AnalogIn ain = new AnalogIn(mbed, p20);
PwmOut p1 = new PwmOut(mbed, LED3);

Alternatively you can tie to objects already created on mbed and then execute their methods.

DigitalOut d3 = new DigitalOut(mbed, "myled");

Finally you can call methods on the objects you have created or tied to. The methods are those described in the Handbook. However unlike on mbed there are no overloaded operators so you have to call the methods by name.

d1.write(1);
d2.write(0);
float i = ain.read();
p1.period(1);
p1.write(1);

Information

If you want to make an RPC call which isn't wrapped by the classes we have provided then use:

String RPCresponse = mbed.RPC(<String ObjectName>,<String MethodName>,<String[] Arguments>);

Communicating with Custom Code

The mbedRPC Java Library supports the RPC-Interface-Library. This means that as well as controlling Digital and Analog I/O you can quickly add RPC to projects using other interfaces or libraries which are not accessible over RPC. The RPC-Interface-Library page shows the mbed code to do this with a RangeFinder, a Motor and the QEI library. Here is the Java Code which would be used to interact with mbed for these examples:

//The RPCVariables need to be given a type
RPCVariable<Double> motor;
RPCVariable<Double> QEI;

RPCFunction Range;

//Tie them to the RPC variables or Functions they correspond with on mbed
motor = new RPCVariable<Double>(mbed, "MotorOutput");
QEI = new RPCVariable<Double>(mbed, "Percentage");
Range = new RPCFunction(mbed, "RangeFinder");

//You can now read and write to the Variables or run the function
System.out.println(QEI.read_float());
motor.write(f);

System.out.println(Range.run("  "));

Setting Up Serial in Java

To use Java in serial and with the mbedRPC library you need to install either the Java Sun Communications API or use RxTx depending on operating system. You can then choose to create your mbed object according to the type of communication you have installed. RxTx would be the best choice for most users.

If you're working in Processing then you already have RxTx as it is packaged with Processing.

Applet demo

As mbed can run as a server it is possible to serve a Java applet from mbed which can then use the RPC to control mbed. This offers a great way to create a web based front end for your mbed project.

Here is an example of an applet controlling mbed:

Note that to send the RPC commands the Jar needs to know the address of mbed, the address is found by using the overloaded constructor for HTTPRPC. If you have created an Applet then you can create the mbed object as:

mbed = HTTPRPC(this);

Applet Security

In general Applets are only allowed to communicate with the domain they are downloaded from. This means that if you use an applet it must be hosted on mbed.

On mbed you need a HTML file with the applet embedded in it:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html>
<head>
<title>mbed Java Applet Example</title>
</head>
<body>
<h1>mbed Applet Demo</h1>
<P align = "CENTER">
<APPLET ARCHIVE="mbedapp.jar" code="HelloWorld" WIDTH="400" HEIGHT="200">
   The Applet should be here
</APPLET> 
</P>
</body>
</html>

To try this applet out download the zip from above. Save the 3 files in this zip to your mbed's drive (and make sure there arn't any bin files which will be detected as more recent). Connect your mbed to a router and then browse to http://<address of mbed>/launch.htm. The address mbed is assigned will be printed out over the serial port. You will be able to control the LEDs on the mbed by clicking in the applet. Note that this HTTP server program won't flash LED1 as I removed that so you can control all 4 LEDs over RPC, instead the program will show its alive over serial.

Applet init() start() stop() destroy()

When using an applet with the mbedRPC library it is important to think about what goes in each of the init() start() stop() and destroy() methods. These are general pointers about what to do when, though of course there are other ways of coding the applet that will work.

  • init() Create the mbed connection here and then tie to existing objects or create new objects.
  • start() If you are using a thread or timer to refresh the applet (see example below) start it here. Also start any processes on mbed which need to be running only whilst the user is interacting with the applet
  • stop() Stop any threads or timers here and leave the mbed's outputs in a suitable condition as the user has stopped interacting with them.
  • destroy() Leave the mbed in a suitable condition as the user has finished with the applet, delete any objects which this applet created to prevent a build up of objects each time someone loads the applet. Finally call the delete method on the mbed object. This isn't strictly necessary for HTTP but if this is included then it means the that the applet can be changed to use different transport mechanisms without problems (eg using serial for testing).

mbedRPC in Processing

Processing is a popular open source programming language for creating visual and interactive programs. This means it can be very quickly used to create a GUI for your projects as either an application or as an applet. Processing is just an extension of Java and so its very simple to use the mbedRPC library in a sketch:

  • First, on the menu bar, goto Sketch->Add File, and navigate to and select the mbedRPC.jar
  • You can now use the library as above with one or two exceptions.
    • To use serial you should use RxTx as it is packaged with Processing, as well as importing org.mbed.RPC.*, you should also import processing.serial.*;

PinName Arguments in Processing

As its not easy to implement an interface on a Processing sketch you cannot refer to the pins as LED1 or p20 as this requires your class to implement mbedRPC. Instead you must refer to them as mbedRPC.LED1 or mbedRPC.p20

DigitalOut led1 = new DigitalOut(mbed, mbedRPC.LED1);

Here is a small piece of example code which changes the brightness of LED1 and LED2 according to the mouse's position and whether the mouse is pressed or not.

//Processing Code
import processing.serial.*;
import org.mbed.RPC.*;

mbed mbed;
PwmOut led1;
PwmOut led2;
void setup() {
  size(480, 120);
  smooth();
  mbed = new SerialRxTxRPC("COM5", 9600);
  led1 = new PwmOut(mbed, mbedRPC.LED1);
  led2 = new PwmOut(mbed, mbedRPC.LED2);

}

void draw() {
  double Position = mouseX;
  double Brightness = (Position/480);
  if (mousePressed) {
    led1.write(Brightness);
  } else {
    led2.write(Brightness);
  }
}

Remote Sensing and Control Demo

This applet demonstrates some of the ways in which you might use an mbed on your network to allow you to view various sensors and control several outputs. The mbed is connected to temperature, pressure and light sensors. The program running on mbed contains just a few extensions to the example http server and uses several of the sensor libraries avaliable in the cook book. The java applet is hosted on mbed and uses RPC commands via the mbedRPC library to regularly update the sensor values.

/media/uploads/MichaelW/applet.jpg

Clicking on the colour wheel sets the RGB led to that colour and clicking on the "light" button turns on a LED. The graphs update with the new values at a rate specified by a parameter passed in to the applet from the HTML page which loads it. As the applet uses a timer to refresh itself at regular intervals its important to make sure this is stopped in the stop() method and restarted in the start() method.

Sensors and Outputs connected to mbed.

  • SCP1000 Pressure Sensor p5,p6,p7,p8
  • TMP102 Temperature Sensor p9, p10
  • An RGB LED p23, p24, p25
  • A PIR sensor p21
  • An analogue light sensor p20
  • A colour sensor p28,p27, p22

The program on mbed is mainly the HTTP server. However the following RPCFunctions are added to the code to allow RPC access to the sensors which otherwise wouldn't be avaliable over RPC.

//Set up the Sensors
TMP102 Temperature(p9, p10, 0x90);
ADJDColourSensor Colour(p28,p27, p22);
SCP1000 Pressure(p5,p6,p7,p8);
DigitalIn PIR(p21, "PIR");
AnalogIn Light(p20, "Light");

//Define functions to add RPC
void getColour(char * input, char * Output);
void getTemperature(char *input, char * Output);
void getPressure(char *input, char * Output);
void getSCPTemperature(char *input, char * Output);

//Set up custom RPC
RPCFunction GetTemp(&getTemperature, "Temperature");
RPCFunction GetPressure(&getPressure, "Pressure");
RPCFunction GetSCPTemperature(&getSCPTemperature, "SCPtemperature");
RPCFunction GetColour(&getColour, "Colour");

//** Rest of the program, ie the HTTP server is here  */


//RPC Functions  - these are used to wrap the sensor libraries that other wise would not be accessible over RPC.
void getTemperature(char *input, char * Output){
    float f = Temperature.read();
    sprintf(Output, "%f", f);
}
void getPressure(char *input, char * Output){
    float f = Pressure.read();
    sprintf(Output, "%f",f);
}
void getSCPTemperature(char *input, char * Output){
    float f = Pressure.readTemperature();
    sprintf(Output, "%f", f);
}
void getColour(char *input, char * Output){
    float clear = Colour.read();
    sprintf(Output, "%f,%f,%f,%f,", clear/500, Colour.red/500, Colour.green/500, Colour.blue/500);
}

Import programRPC_RemoteSensing

Remote Sensing demo. This is the code that runs on mbed to interface with the Remote Sensing Applet Demo

Here is a zip of the applet, the html file and the bin file that can be extracted to mbed RemoteSensingDemo.zip