Overview

IoT with Java 8 and TinkerForge – 004

No Comments

Coffee in the office is often an insidious thing: First it is too hot, then too cold. Most of you will know this problem. We are going to tackle it today and sketch solution. Of course as always with JavaFX and the PTC-Bricklet from TinkerForge.

Software is made of coffee. At least I often hear things like that. It makes it even more infuriating that coffee never has the right temperature. This is very annoying – at least for me. At the beginning it is too hot so you wait and keep on doing your work.
Eventually you remember your coffee, take a sip – and then it is to cold. That does not have to be the case.

The PTC-Bricklet
================
The PTC-Bricklet from the TinkerForge tool kit measures temperatures via a Pt100– and Pt1000 element. This way 2, 3 and 4 conductor types are supported which provides great flexibility. The bricklet measures temperatureswith a resolution of 0,5% in a range of -246 to 849 degrees celsius. The values are decoded with 15 bit which equals a resolution of 0,03125?C which in turns displayed in 0,01 degree steps.
Now the resolution should be sufficient for most applications. Today i am using a PTC100 in our setup. It does not matter which one you use. But it should be a water proof version otherwise you might get a nasty surprise.

Using the PTC
=============
As usual (look at the previous articles) the bricklet is linked to the MasterBrick. Shortly after the sensor is shown in the display of the BrickViewer . It is always advisable to update the bricklet software via BrickViewer. Finally the sensor is useable. The PTC-Bricklet is also equipped with a Java interface which enables the implementation via ActionListener (listing1).

public class PTC implements Runnable {
 
    private String UID;
    private ObservableList seriesData;
    private SevenSegment sevenSegment = new SevenSegment("iW3");
 
    public PTC(final String UID, final XYChart.Series series) {
        this.UID = UID;
        this.seriesData = series.getData();
    }
 
    @Override
    public void run() {
        IPConnection ipcon = new IPConnection();
        BrickletPTC ptc = new BrickletPTC(UID, ipcon);
        try {
            ipcon.connect(Localhost.HOST, Localhost.PORT);
            ptc.setTemperatureCallbackPeriod(1000);
            ptc.addTemperatureListener(
              new BrickletPTC.TemperatureListener() {
                @Override
                public void temperature(int temperature) {
                    //schreibe temp in 7Seg
                    final double celcius = temperature / 100.0;
                    System.out.println("celcius = " + celcius);
 
                    Platform.runLater(()->{
                        final XYChart.Data data 
                            = new XYChart.Data(new Date(), celcius);
                        seriesData.add(data);
                    });
                    sevenSegment.printValue(celcius);
 
                }
            });
        } catch (IOException 
            | AlreadyConnectedException 
            | TimeoutException 
            | NotConnectedException e) {
            e.printStackTrace();
        }
    }
}

Within the ActionListener the necessary values is delivered. In our case it is the temperature in degrees Celcius multiplied by the factor 100. The delivered value has to be divided by 100 so it can be displayed.

The 7 Segment Bricklet
======================
Now what do we do with the measured values? On the one hand we display them in a LineChart – like we did in the previous articles. However, there is also the 7 segment bricklet at which we will take a look today as well.
This bricklet provides four 7 segment displays. Each of the 29 segements can be switched on and off – and it can be adjusted in brightness. The segments can be encoded via bits or bit patterns. This way it is necessary to first convert the displayed values into the respective segment pattern. The documentation of TinkerForge provides typical bit patterns for the most common characters (also contained in the example code).

public class SevenSegment {
 
    private String UID;
    private BrickletSegmentDisplay4x7 sevenSegment;
    private DecimalFormat myFormatter = new DecimalFormat("0000");
 
    private static final byte[] digits = {0x3f,0x06,0x5b,0x4f,
            0x66,0x6d,0x7d,0x07,
            0x7f,0x6f,0x77,0x7c,
            0x39,0x5e,0x79,0x71}; // 0~9,A,b,C,d,E,F
 
    public SevenSegment(String UID) {
        this.UID = UID;
        final IPConnection ipcon = new IPConnection();
        sevenSegment = new BrickletSegmentDisplay4x7(UID, ipcon);
        try {
            ipcon.connect(Localhost.HOST, Localhost.PORT);
 
            short[] segments = {digits[4], 
                digits[2], digits[2], digits[3]};
            sevenSegment.setSegments(segments, (short)7, false);
 
        } catch (IOException 
            | AlreadyConnectedException 
            | NotConnectedException 
            | TimeoutException e) {
            e.printStackTrace();
        }
    }
 
 
    public void printValue(final Double value){
        int intValue = value.intValue();
        final char[] chars = myFormatter.format(intValue).toCharArray();
        System.out.println(chars);
 
        final int aChar = chars[0];
        final byte d1 = digits[aChar-48];
        final byte d2 = digits[chars[1]-48];
        final byte d3 = digits[chars[2]-48];
        final byte d4 = digits[chars[3]-48];
        short[] segments = {d1, d2, d3, d4};
        try {
            sevenSegment.setSegments(   segments   ,(short)7, false);
        } catch (TimeoutException 
                    | NotConnectedException e) {
            e.printStackTrace();
        }
    }
 
}

In our case the conversion is fairly easy: Take the provided value of the PTC, divide it by 100 and create the necessary bit pattern. In our example i only show the numbers (including leading zeros) in front of the comma on the 7 segment display.
The formatting is done by an instance of the class DecimalFormat with the pattern “0000”.

Each number is then being transferred to the necessary bit pattern. After that the individual bit patterns are stored in a short-Array and passed to the sensor. This way the basic functionality is established.
Every time the PTC provides a value it is converted and transferred to the 7 segment display. Now the temperature can be read.

The usage

Now we have all parts together. The temperature can be measured and the value is shown in the LineChart as well as in the 7 segment display. Now only the test with the coffee itself is missing. So it is time to get a fresh hot coffee. Start the program and put the PTC in the coffee cup. In this example the temperature must be still observed manually. This does not solve the problem described in the beginning but is a first step towards it. Several steps will follow in the next article.

Listing 3 shows the complete JavaFX program.

public class PTCMaster extends Application {
 
    public static XYChart.Series seriesTemp = new XYChart.Series();
 
    public static void main(String args[]) throws Exception {
        launch(args);
    }
 
    @Override
    public void start(Stage stage) {
        stage.setTitle("Line Chart TinkerForge Sample");
 
        final VBox box = new VBox();
        seriesTemp.setName("Temp");
        final ObservableList boxChildren = box.getChildren();
        boxChildren.add(createLineChart("Temp", seriesTemp));
        Scene scene = new Scene(box);
 
        stage.setScene(scene);
        stage.show();
        Platform.runLater(new PTC("i2J", seriesTemp));
 
    }
 
    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
With the components you are able to build and use things within minutes. The reasonability of exactly this application is maybe questionable but one thing is for sure. You can build quickly prototypes with the TinkerForge elements. Due to the simple Java bindings an evaluation of the measured values is also available in a first version. In the next articles we are not only going to learn more elements but also develop more complex applications.
Stay tuned. Happy Coding!

Comment

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