Wednesday, November 9, 2011

uOS/EPOS Termometer

Since we've put our hands in some nice EPOS-Motes came the idea of building a simple application to test-drive the gizmo.

The idea is not much original, but illustrate how the uOS and the EPOS mote can talk with each other using the SerialPort (of course the best option would be to use the 802.15.4, but it'll come in the future). Taking advantage of the fact that the StarterKit comes with a temperature sensor, we've created a simple Temperature Driver and Application in the uOS as follows.

The UART Communication


The EPOS code is very simple, consisting of a simple request-response serial communication that waits for the 'T' character as request token.


class UosUartTemperatureDriver {
private:
OStream cout;
UART uart;
Temperature_Sensor sensor;
public:
void run(){
while(true){
char c = uart.get();
if (c == 'T'){
int sample = sensor.sample();
uart.put(sample);
}
}
}
};


The Synchronous Temperature Service

For the synchronous (query) temperature service the driver side stays as follows:


public void sense(ServiceCall req, ServiceResponse res,
UOSMessageContext uosMessageContext) {
Integer temperature;
synchronized (communicator) {
communicator.send('T');
temperature = communicator.receive();
}
res.addParameter("temperature", temperature.toString());
}


The application side is just a driver check and a call.



String driverName = "org.unbiquitous.driver.temperature";
List<RemoteDriverData> drivers = gateway.listDrivers(driverName);
if (drivers != null && !drivers.isEmpty()) {
RemoteDriverData data = drivers.get(0);
ServiceCall call = new ServiceCall(driverName, "sense");
ServiceResponse response = gateway.callService(data.getDevice(), call);
System.out.println("Now is "+response.getResponseData("temperature")+"°C")



The Asynchronous Temperature Service


Asynchronous (publish-subscribe) happens in three steps. First the application need to register (subscribe) for the desired event (temperature change).


String driverName = "org.unbiquitous.driver.temperature";
List<RemoteDriverData> drivers = gateway.listDrivers(driverName);
if (drivers != null && !drivers.isEmpty()) {
RemoteDriverData data = drivers.get(0);
gateway.registerForEvent(this, data.getDevice(), driverName, data.getInstanceID(), "temperature_change");
}else{
System.out.println("No driver available.");
}


Then the driver must be able to respond for such changes. This is done in a temperature listener thread.


Thread sensor = new Thread(){
public void run() {
while (running) {
Integer temp;
synchronized (communicator) {
communicator.send('T');
temp = communicator.receive();
}
if (temp != lastTemp) {
lastTemp = temp;
Notify temperatureChange = new Notify("temperature_change", driver.getName(),TemperatureDriver.this.instanceId);
temperatureChange.addParameter("temperature", lastTemp.toString());
notifyListeners(temperatureChange);
}
}
}
private void notifyListeners(Notify temperatureChange) {
if (listeners != null){
for (NetworkDevice nd : listeners) {
UpDevice device = new UpDevice("DummyDevice");
device.addNetworkInterface(nd.getNetworkDeviceName(),nd.getNetworkDeviceType());
try {
TemperatureDriver.this.gateway.sendEventNotify(temperatureChange, device);
} catch (NotifyException e) {logger.error("Not posible to send event", e);}
}
}
};
};


Then the application is notified every time a temperature change happens.


public void handleEvent(Notify event) {
if (event.getEventKey().equals("temperature_change")){
System.out.println("Temperature changed to "+event.getParameter("temperature")+"°C");
}


The full code of both the application and the driver can be found at our github account.

1 comment:

  1. Thanks for sharing fabulous information. epos It's my pleasure to read it.I have also bookmarked you for checking out new posts.

    ReplyDelete