Overview

IoT with Java 8 and TinkerForge – 002

No Comments

The last article of this series has covered an introduction to the hardware platform TinkerForge. This time we are going to handle a more specific example. One of the important features of TinkerForge is the possibility to link elements like lego-parts. And exactly that is what we demonstrate with two sensors today. Additionally we show you how can analyze in parallel two or more sensors can be analyzed parallel. The measured values will be analyzed in realtime and afterwards are shown in a simple JavaFX application.

The barometer sensor
====================
In this setup one MasterBrick is linked with two sensors. The first one is known from the first article of this series: It is the temperature sensor . Along with this we are adding the barometer sensor. With this bricklet you can measure the barometric pressure in range of 10 to 1200 mbar with a resolution of 0.012mbar whereby the measurement is temperature compensated internally. The bricklet is based on a MS5611-01BA01 sensor which also can be used as an altimeter. And with that we have an exception in comparison to the temperature sensor. The barometer sensor provides two measurements.

Linking of n sensors
====================
The link process of each sensor can be done with the configuration of an encapsulating sensor class and the implementation of a corresponding ActionListeners. Within the last the measured values can be analyzed. At this point Listing 1 is shown as a short reminder.

import com.tinkerforge.BrickletTemperature;
import com.tinkerforge.IPConnection;
 
public class ExampleCallback {
    private static final String host = "localhost";
    private static final int port = 4223;
    private static final String UID = "dXj"; 
    public static void main(String args[]) throws Exception {
        IPConnection ipcon = new IPConnection(); 
        BrickletTemperature temp = new BrickletTemperature(UID, ipcon); 
        ipcon.connect(host, port); 
        temp.setTemperatureCallbackPeriod(1000);
        temp.addTemperatureListener(new
          BrickletTemperature.TemperatureListener() {
            public void temperature(short temperature) {
                System.out.println("Temperature: "
                   + temperature/100.0 + " °C");
            }
        });
        ipcon.disconnect();
    }
}

It is the same way with the barometer sensor. There is also an encapsulating class, in this case the BrickletBarometer . As shown in Listing 2 the configuration is almost identical to the Listing1 except the UID. The reason for that is that both sensors are linked to the same MasterBrick . Additionally it is shown how both measurements can be processed. It is really simple because there exists an ActionListener for each measurement.

public class ExampleCallback {
    private static final String host = "localhost";
    private static final int port = 4223;
    private static final String UID = "jY4";
    public static void main(String args[]) throws Exception {
        IPConnection ipcon = new IPConnection(); 
        BrickletBarometer b = new BrickletBarometer(UID, ipcon); 
        ipcon.connect(host, port); 
        b.setAirPressureCallbackPeriod(1000);
        b.setAltitudeCallbackPeriod(1000);
        b.addAirPressureListener(
            new BrickletBarometer.AirPressureListener() {
                public void airPressure(int airPressure) {
                    System.out.println("Air Pressure: "
                        + airPressure/1000.0 + " mbar");
                }
            }
        );
        b.addAltitudeListener(new BrickletBarometer.AltitudeListener() {
            public void altitude(int altitude) {
                System.out.println("Altitude: " + altitude/100.0 + " m");
            }
        });
        ipcon.disconnect();
    }
}

Linking of JavaFX
=================
The link process of the sensors to JavaFX can be reached fairly easy. The basic principal is that a thread is started out of the JavaFX application in which the sensor is configured and the ActionListener is called (within the run()). Important with that is that all parts which will update JavaFX gui components must be encapsulated within Platform.runLater. Because we have more than one sensor in this example every sensor is outsourced in its own class. Listing3 shows the code for the temperature sensor. The usage is then fairly easy:

public static class Temp implements Runnable {
 
        private String UID;
        private ObservableList seriesData;
 
        public Temp(final String UID, final XYChart.Series series) {
            this.UID = UID;
            this.seriesData = series.getData();
        }
 
        @Override
        public void run() {
            IPConnection ipcon = new IPConnection();
            BrickletTemperature temp = new BrickletTemperature(UID, ipcon);
 
            try {
                ipcon.connect(host, port);
                temp.setTemperatureCallbackPeriod(1000);
                temp.addTemperatureListener(
                  new BrickletTemperature.TemperatureListener() {
                    public void temperature(short temperature) {
                        Platform.runLater(new Runnable() {
                            @Override
                            public void run() {
                                final double temp = temperature / 100.0;
                                System.out.println("Temperature: " + temp 
                                    + " °C");
                                final XYChart.Data data 
                                    = new XYChart.Data(new Date(), temp);
                                seriesData.add(data);
                            }
                        });
                    }
                });
            } catch (IOException 
                       | AlreadyConnectedException 
                       | TimeoutException 
                       | NotConnectedException e) {
                e.printStackTrace();
            }
        }
    }

For the barometer two of those classes are written: the class Luftdruck and the class Altitude. Both of them are equal except the ActionListener and both of them put der measured values in their own series. Every series is shown in its own LineChart. In this implementation it is approved that for each physical sensor two representations per thread exists. In the tests this combinations was stable. Additionally all examples i have refrained from closing the sensors via disconnect() when quitting the JavaFX-application.In Listing 4 you can see the JavaFX program.

public class Barometer extends Application {
    public static final String host = "localhost";
    public static final int port = 4223;
 
 
    public static void main(String args[]) throws Exception {
        launch(args);
    }
 
    public static XYChart.Series seriesTemp = new XYChart.Series();
    public static XYChart.Series seriesLuftdruck = new XYChart.Series();
    public static XYChart.Series seriesAltitude = new XYChart.Series();
 
    @Override
    public void start(Stage stage) {
        stage.setTitle("Line Chart TinkerForge Sample");
 
        final VBox box = new VBox();
        seriesTemp.setName("Temp");
        seriesLuftdruck.setName("Luftdruck");
        seriesAltitude.setName("Altitude");
 
        final ObservableList boxChildren = box.getChildren();
        boxChildren.add(createLineChart("Temp", seriesTemp));
        boxChildren.add(createLineChart("Luftdruck", seriesLuftdruck));
        boxChildren.add(createLineChart("Altitude", seriesAltitude));
 
        Scene scene = new Scene(box, 2000, 1500);
 
        stage.setScene(scene);
        stage.show();
        Platform.runLater(new Temp("dXj", seriesTemp));
        Platform.runLater(new Luftdruck("jY4", seriesLuftdruck));
        Platform.runLater(new Altitude("jY4", seriesAltitude));
 
    }
 
    private LineChart createLineChart(
        final String chartName,
        final XYChart.Series series ){
 
        final DateAxis dateAxis = new DateAxis();
        dateAxis.setLabel("Time");
        final NumberAxis yAxis = new NumberAxis();
 
        final LineChart lineChart 
            = new LineChart<>(dateAxis, yAxis);
        lineChart.setTitle(chartName);
        lineChart.getData().add(series);
 
        return lineChart;
    }
}

Conclusion

In this article we have described the first steps in the direction of the analyzation of n-sensors. In these tests you can quickly see that a middle freq of 1 measurment/second already leads to some percent CPU-load. Therefore in this form the scalarility is limited. In the next articles we will deal with the abstraction of the sensors as JavaFX-GUI-elements and with the storage of values in DBMS (SQL/noSQL).

The source code to this article can be found under https://bitbucket.org/rapidpm/jaxenter.de-0012-iot-tinkerforge .
For people who are interested in more complex examples I recommend the following https://bitbucket.org/rapidpm/modules .

Comment

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