Thursday, January 1, 2015

JavaFX on e-paper

Hi there,

Before christmas I was playing around with the following e-paper display from Embedded Artists...
E paper display
The nice thing about e-paper displays is the fact that they are very energy saving because they use an interesting approach to visualize data (wikipedia). The Embedded Artists display only needs power to change the screen content and after it has changed it will stay on the display even without power connected to the panel. 

If you hear this for the first time you's great I wanna use it for my embedded project...BUT...keep in mind that it has two major drawbacks...
  • It is only black and no colors, gradients etc.
  • The screen refresh is really slow compared to the TFT panels (this panel takes up to 2 sec to change the screen)
So an e-paper display is not useful for animated or colorful apps but if you think about a weather station or a price display in a supermarket it absolutely makes sense to use such a display. In these cases the content of the display only changes a couple of times a day (weather station) or week (price display).

For me it was only interesting to see if I would be able to use JavaFX to render something on this display. If people hear JavaFX they first of all think about animations, effects etc. but hey, it's just a simple UI toolkit which can create visual content.

So I wanted to use the e-paper display on an Odroid-W from Hardkernel (which is hardware compatible to the Raspberry Pi). Lucky me there was already a tutorial on the Embedded Artists website that describes how to hookup the e-paper panel to a Raspberry Pi. In principle it describes how to install the driver for the panel on the Pi and how to display some content on it. My idea was to visualize maybe a clock (without second pointer) and also some weather information. So I would have to change the content of the screen at least once a minute which should be ok.

The tool that was provided by Embedded Artists is able to display an image in XBM format which is a plain text binary image format to store bitmaps (wikipedia). To display the xbm image you simple clear the screen and copy the image to a special folder by using two shell commands.

Now to the idea on how to use JavaFX to visualize data on the e-paper panel...

1. Create the JavaFX scene
  • Make sure that the size of the scene is exactly the size of the e-paper display (264 x 176 px).
  • Instead of colors just use black on white (you could also use white on black).
  • Make sure that you don't use an AnimationTimer (it will lead to render on every pulse)
  • Update the scene from a scheduled task via Platform.runLater(()->{...}) once a minute
And this is how my JavaFX app looks like when connected to a standard display

Monosnap 2014 12 31 13 17 50

2. Create the XBM file
To create an xbm image file we first need to take a snapshot which is very easy in JavaFX. In fact it is just one line of code...

final WritableImage SNAPSHOT = NODE.snapshot(new SnapshotParameters(), null);

With the writable image in place we now can use a PixelReader to read out the color of every pixel in the image. This is needed to create the corresponding hex string for the xbm image. Creating the image is done by two loops that simply loop over all pixels, read out the rgb value of each pixel in the snapshot, convert it into a hex string (0x00 - 0xff) and write it into a file. To give you an idea on how the xbm file will look like, here are some lines from the file...

#define yotaclock_width 264
#define yotaclock_height 176
static unsigned char yotaclock_bits[] = {

3. Updating the e-paper display
Now we only have to update the display every time we create a xbm image file. To make it as easy as possible I simply call the shell commands via ProcessBuilder like follows...

Process p1 = new ProcessBuilder("/bin/bash", "-c""/PATH/TO/DRIVER/gratis/PlatformWithOS/driver-common/xbm2bin < /PATH/TO/IMAGE/YOUR_IMAGE.xbm > /PATH/TO/EPD/epd/display").start();
p1.waitFor(1, TimeUnit.SECONDS);

Process p2 = new ProcessBuilder("/bin/bash", "-c", "echo U > /PATH/TO/EPD/epd/command").start();
p2.waitFor(1, TimeUnit.SECONDS);

And that's all you have to do to use JavaFX with an e-paper display on a Raspberry Pi. This really more a quick hack than a really nice solution but it works :)

And here is an example image of the e-paper display...

There is definitely place for improvements like handling the whole image thing in memory and pass it directly to the driver instead of saving it to a file and calling the update via a shell command. But because I don't update the display very often this approach also works really well.

I've created a little gist that contains the code you need...

That's it for keep coding... :)

Friday, December 12, 2014

Friday Fun Component XXII

And another one...
Last weekend I took a closer look to the new Yotaphone 2 which in principle is just another Android mobile phone BUT it has a second screen on the backside. And this is not a standard screen, it's an e-paper display.
I really like the simplicity of the widgets that they use on the e-paper display and especially the clock looked good to me...
So I created a version in JavaFX and here it is...

As you can see this is a really simple clock but that's exactly what I like about it... :)
It has not many features, so one can update the time by calling updateTime() which will show the current time or you can update it with your own time with updateTime(LocalDateTime). In addition you can define the background and foreground color with setBackgroundColor(Color) and setForegroundColor(Color). And there is a method to invert the colors called setInvert(boolean) and that's it.
Like I said it has not many features but's just a simple clock :)

If you like it you can fork it on Bitbucket as always...

That's it for today...keep coding...

Friday, December 5, 2014

Friday Fun Component XXI

And another little fun component I've created for you...
There was a request for a JavaFX version of my TrafficLight Swing control from November 2011 (Friday Fun Component XIII) and so I've created one.
The basic control was done within a couple of hours but after I finished the control I had the idea to add some kind of masks. The reason for that is simple, if you take a look at the traffic lights in Germany (and also in other countries) you will not only find the following ones...

but also the next ones...

The traffic light on the last picture is a special version that can only be found in the eastern part of Germany (to be honest I only saw them in Berlin). Long story short, I've added the possibility to the traffic light and my version now looks like this...

The default traffic light control will not show any overlay and will look like the right version on the picture above (except the color which is customizable).
For each light one can switch on the overlay by calling e.g. 


If you switch the overlay on for all three lights you will see the version on the left side. One could also adjust the color for each light (available are RED, YELLOW and GREEN) by calling e.g. 


To change the background color of the traffic light one could call the method


To add a custom shape as a mask for one of the lights I've added a method that takes a SVG path as a string e.g.

setLowerOverlayShape("M 0 0 L 100 0 L 100 100 L 0 100 L 0 0 Z");

To get the result that you see in the middle traffic light I used the following picture...

Just to give you an idea how the SVG path looks it is...

"M 444.1487 333.8626 C 447.1197 330.8951 467.811 303.5027 467.811 303.5027 C 480.0558 287.159 493.702 267.7863 500.3011 254.4572 C 502.1896 249.9297 499.5399 243.5141 499.2354 239.1369 C 496.9518 206.3077 520.3127 193.7116 518.638 169.6369 C 518.1813 163.0711 502.0916 119.2731 501.5223 113.6345 C 500.9133 104.8801 520.4972 101.339 520.4972 101.339 C 526.1451 100.8593 533.1181 103.7161 538.4975 106.7027 C 542.8953 109.53 555.9396 120.9555 558.1721 136.1411 C 558.8104 140.4826 557.045 151.6116 555.4609 160.5164 C 571.1158 163.8417 605.2333 153.1114 611.9586 180.8343 C 613.4196 186.8573 606.6897 192.1831 602.6084 196.8609 C 609.9099 200.4362 618.6461 203.292 619.4073 214.2351 C 620.0162 222.9896 617.8053 233.2108 602.7593 238.64 C 602.7593 238.64 608.3714 241.0195 609.7949 244.755 C 612.9094 260.9012 597.6304 265.3755 589.0836 263.7666 C 584.7628 262.9532 564.3526 256.6652 557.7737 257.116 C 553.3879 257.4165 545.4089 261.7291 538.8488 263.4755 C 531.9924 264.9642 523.1437 266.0862 516.4128 264.3484 C 503.1337 280.9753 462.3076 335.7824 456.0219 352.145 C 453.2868 360.8542 452.2284 372.3198 452.8953 381.9073 C 453.4083 389.2823 454.8527 399.3723 458.3469 406.9135 C 462.3386 416.2732 467.4324 425.4647 471.8194 435.1678 C 477.9149 448.0883 482.9688 460.7098 488.0074 474.4438 C 499.87 506.2356 507.7894 537.3713 512.2889 570.0383 C 512.3915 571.5132 513.5253 578.4752 513.6023 579.5815 C 513.6023 579.5815 515.4518 598.1653 515.725 603.4263 C 516.1483 609.5108 516.6034 622.7253 516.6034 622.7253 C 516.2285 652.021 516.7795 693.2949 476.5109 696.0544 C 474.2943 696.2062 471.8006 696.3771 469.1376 695.4482 C 460.4096 692.7115 452.0024 681.2462 446.738 674.9379 C 440.2371 666.8616 434.08 658.3914 427.2353 650.7092 C 417.1015 638.4359 400.6964 625.3881 388.5665 621.7734 C 381.3677 619.6731 373.7903 618.8029 367.1404 619.2586 C 312.8331 622.98 274.3401 697.9595 238.5047 700.4152 C 229.6382 701.0228 219.4004 697.9266 216.3502 686.0942 C 215.4992 682.7933 214.403 676.7796 214.3517 676.0421 L 213.3578 661.753 L 213.2979 628.8745 C 212.0343 630.7211 210.6707 636.4648 206.7095 638.2183 C 205.9962 638.6377 204.4261 638.7453 203.3178 638.8212 C 202.579 638.8719 199.3143 638.6324 198.1804 638.3395 C 195.9381 638.1227 192.811 637.2314 190.5261 636.3632 C 185.5695 634.4798 181.2518 629.7738 180.6861 625.6443 L 180.2629 619.5599 C 180.8222 616.9282 181.878 613.4286 183.5456 610.7207 C 188.5229 602.2285 195.0292 594.3724 200.0321 586.249 C 204.6655 578.1507 207.1042 569.1841 207.2787 561.0209 L 206.6721 550.9662 C 205.832 545.5587 204.1082 539.6839 202.352 534.2188 C 200.5754 528.6903 194.7133 517.7916 193.4692 506.5763 L 192.6702 493.7559 C 191.3877 475.3184 211.6659 454.6624 220.7277 435.5161 C 232.042 411.3987 237.2157 387.0538 237.0775 363.7213 C 237.36 341.1009 237.6964 317.9211 237.6094 295.3261 L 236.3541 259.936 C 235.6938 237.1024 231.6087 191.7172 230.9276 185.9284 C 228.3365 175.3612 228.5252 163.3994 223.692 152.6154 C 267.2558 174.5468 319.5998 222.6457 354.9832 261.7179 C 371.0688 279.5115 387.1455 298.5099 400.6452 316.4807 C 411.646 330.5472 414.7373 341.6358 428.776 340.6738 C 434.1322 340.3068 439.5791 337.8033 444.1487 333.8626 ZM 0 400 C 0 620.9167 179.0833 800 400 800 C 620.9167 800 800 620.9167 800 400 C 800 179.0833 620.9167 0 400 0 C 179.0833 0 0 179.0833 0 400 ZM 263.7735 377.8755 C 273.6586 401.374 304.4725 410.7581 332.5463 398.7737 C 360.5947 386.8002 375.15 358.0852 365.1104 334.6976 C 355.1044 311.3885 324.424 302.1593 296.5297 314.0223 C 268.6104 325.8959 253.9216 354.456 263.7735 377.8755 ZM 495.5976 571.5526 C 486.0958 493.656 440.4304 397.4891 386.9657 322.6052 C 382.9275 323.2525 378.7046 323.9123 374.6921 324.9283 C 376.1082 329.2774 377.5757 334.3639 378.5966 338.3696 L 379.3033 351.1962 C 377.2644 391.2582 342.251 414.8691 311.2182 416.9957 C 294.963 418.1096 274.077 412.6864 260.1412 395.116 L 254.8433 398.9988 C 254.8433 398.9988 247.5887 448.1252 247.2089 453.3383 C 246.5366 459.683 245.1768 466.8159 244.5046 473.1605 C 242.9805 483.2687 241.9028 494.4578 240.4044 504.9347 C 239.568 514.2547 238.362 523.6001 237.1305 532.5766 C 236.294 541.8967 235.0881 551.2419 234.2259 560.1932 C 232.9584 573.9888 231.9614 587.6735 230.6938 601.4691 C 229.7958 615.2394 229.3659 629.0703 229.2066 642.7899 L 230.1454 661.6215 C 230.6174 663.0712 230.8083 683.1582 240.7831 682.4747 C 253.8981 681.576 271.3069 661.024 282.385 649.52 C 293.4375 637.6475 306.958 625.2352 318.6877 617.7622 C 323.9984 614.0637 330.8083 610.2503 336.6492 607.8245 C 343.5941 604.9402 350.1053 602.8469 357.3865 601.7721 C 362.0713 601.0807 363.2719 600.9984 364.3802 600.9224 C 372.5078 600.3655 383.7705 602.187 390.9694 604.2874 C 405.7622 608.8312 424.9676 623.4471 437.8926 638.4932 C 443.5007 644.4075 448.8164 651.4534 453.7114 657.7871 C 459.371 664.439 464.9072 673.3223 472.5563 677.8926 C 474.1456 678.8422 477.0472 678.4185 477.7862 678.3678 C 481.4805 678.1146 485.7483 678.1001 489.6069 674.8716 C 491.3514 673.2701 492.4959 671.329 493.1525 669.8121 C 500.5082 652.8204 497.5635 607.8202 497.2482 593.9478 L 495.5976 571.5526 ZM 225.3195 474.8457 C 225.2169 473.3707 225.3041 469.2892 222.3486 469.4917 C 220.5014 469.6183 217.0379 473.1902 215.7397 475.8727 C 210.7881 484.7337 206.3855 496.1507 207.0268 505.3694 C 207.7963 516.4319 213.6097 525.2963 218.8638 536.7924 L 225.3195 474.8457 Z"

As you can see that's a looooong string and the question is can I apply this string to a node in the scene graph???

Well first I thought I should use a SVGPath() node and set the string as the content of the node but to be honest the SVGPath() node is a bit special in the way that it doesn't support methods like setPrefSize(w,h) etc. but only setScaleX(n), setScaleY(n) which means I would have to calculate the scaling correctly for each SVG path string.
So I decided to go in another direction and simply parse the string and create a JavaFX Path from the SVG path string.
Therefor I've created a little class named SVGPathParser which only has one method that parses SVG path string and returns a JavaFX Path from it. Just to make that clear, this is NOT an SVG parser but only a parser for SVG paths.
Why I did this you ask ???
Well in JavaFX I can set a Shape to a Region by calling setShape(Shape) and for that Region I can call setPrefSize(w,h) etc. which makes it very handy.
So with this approach I'm able to set custom shapes as a mask (keep in mind that the shapes have to have a square form factor) and I can scale them very easily.
This approach might also be useful for other things...

I guess that's all I have to say...if you like it you can fork the project on bitbucket.

Keep coding...

Friday, November 28, 2014

Friday Fun Component XX

Hi again,

during the last weeks I was working on my JRunner project which is a wearable system based on an Odroid-W running on Java SE embedded. As you might guessed already the system was made to monitor a runner or bicycle rider. Especially the heart rate is very interesting to monitor and analyze. To visualize the recorded data and also to track the runner live during the run I've created a JavaFX based desktop application which shows all the different parameters.
And because I would like to have a gauge in the app (you know I love gauges) I was looking for a gauge that I can use to visualize the current heart rate and the average heart rate in one gauge.
To make it it is...

As you can see it has two bars and some text. The outer bar visualizes the current heart rate and the inner bar visualizes the average heart rate. Because I have a color scheme in my app to visualize the different heart rate zones I would like to color the bars dependend on the heart rate. Therefor I've used my little GradientLookup class that I've used before. To get an idea about the current value, the big number shows the current and the small number the average heart rate. For my use case I set the title always dependend on the current heart rate zone.
Both bars can be set independently and are animated. If you would like to use the mode where the bars change their color dependent on the value you have to enable it by calling setMultiColor(true). If not you can simply set the color for the outer and for the inner bar and the colors won't change dependent on the value.
You could also set the color of the inner background, the border and for each text of the gauge.
Like always I've created this control for one of my demos so don't expect it to be production ready but if you like you might want to fork it on bitbucket.
I've also recorded a very short video on youtube that shows the gauge in action.

That's it for keep coding...

Thursday, October 30, 2014

Sensor Networks with Java (Part II)

Hi there,

Getting back from GeeCON Prague and EclipseCon Europe I thought it might be time for part 2 of my Sensor Networks post.
In the last post I've explained how to setup the network and how to use Java to read out the data from the Coordinator Node.

For a session at Java One this year I've created a little demo project that also shows another example on how to connect to a XBee Series 2 using Java. You can find the code for that little demo here.

But now back to my Sensor Network, now that I've setup all the hardware I needed a way to store and visualize the data.

Storing data
To store the sensor data you have different options

  • local
  • cloud

Because a cloud solution was a bit overkill for the kind of stuff that I would like to do and I also like to keep as much data in-house as possible I've decided to go with solution one...local storage.
Well like I've mentioned in the last post I would like to use as many embedded devices as possible (at least because they are small, cheap and I can setup them up in my office easily). The easiest way would be installing a little database on a Raspberry Pi, BeagleBoneBlack or similar hardware and store the Sensor Network data in this database.
But because these devices are using SD-Cards as their hard-drive this would mean I would have to install the database on the SD-Card. In principle no problem BUT SD-Cards are not made for continuous file access which means your SD-Card will get corrupted very soon. One solution would be using an USB memory stick on these devices and store the data on the stick. The disadvantage of this approach might be the speed of the memory stick and to be honest I don't really like the idea :)
So I was looking for an embedded board that has a SATA port where I could attach a real hard-drive. Long story short I've decided to go with the CubieBoard 2 which you could see on the following picture

The CubieBoard 2 is a really nice board with following specs

  • DualCore ARM A7 1 GHz CPU
  • Mali-400 MP GPU
  • 1 GB RAM
  • 1 Micro SD slot
  • 1 SATA 2.0 connector
  • RJ45 Ethernet
  • I2C, SPI, LVDS and more

So with the ability to connect a SATA hard-drive I'll be able to put the database to the hard-drive which will give me more speed. Even if a SSD drive is also not the best solution for a database drive I decided to use one because it's faster and if you take a small size SSD it will be cheap (I'm using a 64GB SATA 2 drive from Sandisk which costs around 40 €).
As database I decided to go with mongoDB but you can use whatever you like. I used mongoDB because there was an ARM port available (which is not really up to date but works). 
The problem with mongoDB was that you have to build the version on your own, means there is no out of the box binary that you can use. You will find some blogposts on the web that describe how to do that (e.g. here).
After that was done my CubieBoard based database-server was ready to go.
So let's take a look at the current setup, we have the Raspberry Pi that acts as Coordinator Node in my Sensor Network and that get events everytime a XBee is sending data. Then I have the CubieBoard 2 which is running mongoDB and could store the data in that database.
The question is how should the data get from the Coordinator Node into the database?
Well the simplest solution would be using the mongoDB Java driver to store the data directly from the Raspberry Pi over my internal network into the mongoDB on the CubieBoard. But I used a different approach...

Because all the embedded devices are running on my local network at home I needed to find a way to access my internal network from the outside. I could have open ports for each device and access it from outside but I decided to use some kind of a central communication server.
Therefor I decided to go with MQTT (Message Queue Telemetry Transport). When using MQTT you need a so called MQTT broker that receives all incoming messages and forwards them to the subscribed clients. Lucky me there is a very small free MQTT broker available called Mosquitto. Because this broker is small and doesn't need huge hardware to run it was the perfect fit for my project. My broker is running on an Odroid-U3 from hardkernel which looks like this.

This board has more than enough power to run Mosquitto as you will find out when taking a look at the specs.
So with the MQTT broker in place I had a central communication server where all devices can talk to. 
The Coordinator Node now publishes a MQTT message every time it receives data from a XBee Sensor Node in the Sensor Network.
Because of the Publish-Subscribe model now everybody that is interested in that data can subscribe to the topic and can use it.
Instead of directly writing the data from the Coordinator Node into the mongoDB instance on the CubieBoard 2 I've wrote another small Java program that is running on the CubieBoard 2 and that is listening to data from the Coordinator Node.
With this approach I could also place the mongoDB server where ever I like. But the main reason for the additional Java program was the reason that I can now also do some data preprocessing on the CubieBoard 2 before storing the data to the database which is nice.
So now we have the Raspberry Pi Coordinator Node that receives the XBee data and publishes it via MQTT. Then there is the CubieBoard 2 that is running the mongoDB instance and is listening to MQTT messages from the Coordinator to store the preprocessed data in the mongoDB.

Ok now that I can measure the and store the data it was time to create something to visualize the data and because I love Java I decided to create a JavaFX based desktop client to visualize the measured data.
Instead of only monitoring the Sensor Network data I've added more features like getting the current weather conditions from the closest airport, showing weather information from my own weather station outside (because the airport is around 30km away) and more.
But here let's only focus on the Sensor Network Data...
Now that we have all the data available in the database we can use different kind of visualizations, first of all we can visualize the live Sensor Node data which I did like follows

As you can see I use a gauge to visualize the last measured temperature of each Sensor Node (the three gauges without a value are ran out of battery...waiting for new batteries at the moment :)). The color of the gauge will change with the temperature and in addition also the current supply voltage will be visualized with a little battery icon. The color of the battery also indicates the state of the battery.
Well it's nice to see the current situation but I'm interested in the temperature of the last 7 I simply used a line chart to visualize the data from the database like this...

Here you can see the temperature variation of each Sensor Node over the last 7 days which is useful to indicate weather trends etc.
Because we have the supply voltage also available in the database why not visualizing the voltage of each Sensor you go...

As you can see on this chart I can easily identify Sensor Nodes that will need a new battery soon (e.g. Anton in the chart above). This is very useful because the batteries will last for a long time but when they are going down the drain it will just take a fews days before they will die. So with this chart I can identify weak batteries by looking at the chart once a week.

Because the temperature do not only vary from day to day but also within one day I was interested in how the temperature in each room varies over the day. Therefor I've created a little RadarChart that shows the temperature for each room, here is a screenshot...

As you can see I can select each Sensor Node on the left side and one of the last 7 days on the bottom. With this you can monitor the temperature variation from each Sensor Node on each of the last 7 days which is really interesting some times.

All the controls that you see on the screen shots above are taking from the Enzo JavaFX controls library that you can find here.
Please keep in mind that all controls in that library are made for my personal demos and are not production ready (but might be useful as a start) :)

Because this post is long enough I won't show you all the mobile clients that I've also created like an iOS and Android client and also a SmartWatch client. But in principle they all look like the desktop version and thanx to Gradle I build all these versions for all these platforms in one Multiproject Gradle build which means more than 90% of the code is the same for all platforms...remember the credo of Java...write once run anywhere :)

That's it for today...keep coding...

Tuesday, October 21, 2014

Sensor Networks with Java (Part I)

Hi there,

End of last year I've started to build a little Sensor Network that I've placed in my house. I never thought that many people are interested in that but I was wrong, nearly every time I did a presentation about that topic many people asked me for a blog post about the project...and here it is :)

First of all this is not really about a Smart Home or something similar, this is simply a project to monitor data (temperature in my case). The original idea was monitoring multiple cold stores which seems to be something that is really useful :)
But because I didn't had the cold stores I've decided to measure the temperature in nearly every room of our house.
The things I was interested in have been the behavior of the room temperature compared to the temperature outside. Does the temperature in the rooms follow the temperature outside of the house and how fast does it follow. To be able to compare those values I had to measure the conditions outside and in inside of the house.
Well measuring is one thing but you also have to analyze the data right? This means I needed to store the data somewhere and also needed to visualize the data somehow. Because I'm working from home I don't have a big server room where I can put a computer that acts as a server so one other requirement was to use as many embedded devices as possible in the whole setup (means for communication, storage, etc.).

Wife factor
One very important (if not most important) factor in the whole project was what I call the "Wife factor". When I've started with the project I've used hardware like Raspberry Pi, BeagleBoneBlack and Arduino Yun to measure the temperature in different rooms in our house. It worked very nice BUT most of these devices have some kind of status led or I/O led which is blinking all the time. In addition all of those devices needed a power supply which means you have to place them close to a power plug. When my wife saw all these lights blinking and wires lying around she was not very amused.
I figured out that as long as she does not see the so called Sensor Nodes everything is fine.

Size matters
That said one thing was pretty clear, the Sensor Nodes have to be small and they should run on batteries...for months!!! I've tried different hardware like Raspberry Pi, Arduino Yun, Arduino + XBee but all of these approaches did not really work out well.
The biggest problem was the need for a power supply which limited the location I could place the Sensor Nodes. In the end I've took a closer look to the XBee itself which looks like follows...

XBee's are modules that provide a cost-effective wireless connectivity to devices in ZigBee mesh networks. They are produced by Digi and there are different modules available.
For my Sensor Network I'm using the XBee S2 or XBee ZB. If you take closer look to the XBee you will figure out that it does not only give you a cheap reliable wireless connection but also has pins for PWM, AD, RX/TX etc. 
So in principle this is a little micro controller with a wireless connection feature which made it the perfect fit for my Sensor Nodes.

Network Topology
For my approach I've used the simplest network setup that is supported, the Star Network. With this network topology I just need one XBee that acts as a so called Coordinator for the network and to that all Sensor Nodes connect to. Another advantage of the Star Network is the low power consumption because I don't have any Router Nodes (that have to be always on) between the Sensor Nodes and the Coordinator. To make it work every Sensor Node has to know the uniqe Serial Number of the Coordinator which has the advantage that the Sensor Nodes don't need to broadcast their data on the network but can directly "talk" to the Coordinator which again saves some energy.

Programming XBees
To let the Sensor Nodes know the Serial Number of the Coordinator Node you have to program them somehow. Lucky me that Digi created a nice tool that makes it very easy to setup the XBees. The tool is called XCTU and could be found here (btw it's a Java application :) ).
Now that we have the software to setup a XBee we somehow need to connect the XBee to our computer. Therefor the easiest solution is a little piece of hardware called XBee Explorer and can be find at SparkFun. It looks like follows...

You could also find other versions from other vendors. As you can see it has a socket for the XBee and a micro USB port that you can connect to your computer.
If you then start XTCU you should see something similar to the following...

If you follow the instructions you should be able to discover the XBee that is connected to your computer. 
The next step is the setup of the XBee, therefor you first should update the firmware of the XBee to the correct version. 

The Coordinator Node needs a different firmware than the Sensor Nodes!!!

If you also use a XBee S2 you should see something similar to this...

For the product family XB24-SB I've selected the firmware with the version 21A7 for the Coordinator Node as you can see on the following screenshot

As you can see on the screenshot there are firmwares for the so called API mode and the so called AT mode. The API (Application Programming Interface) mode is a frame-based method for sending and receiving data to and from a radio's serial UART. The API mode gives you more flexibility because you can send and receive packets to and from the XBee. In AT or transparent mode the XBee simply relays all serial data to the receiving XBee.
So I've choosen the API mode for my project.
After you've updated the firmware of your Coordinator XBee you have to program it using the XCTU software. Don't worry, programming in this case means simply set the right parameters in the Radio Configuration part of the XCTU window.

Setup of Coordinator Node:
For the Coordinator Node there are only a few things you have to set:

Variable    Name                Value                            
ID          PAN ID              A unique id that is the same for                                     all Nodes in your Sensor Network
                                (e.g. 312)

NI          Node Identifier     A name for this XBee
                                (e.g. coordinator)

Write down the variables SH and SL which is the Serial Number of the Coordinator Node because you will need it for the setup of the Sensor Nodes!!!

Don't forget to save the Coordinator Node profile from within the XCTU software. So you can re-use it later if needed.

Setup of Sensor Nodes:
For the Sensor Nodes you have to set up a few more things:

Variable    Name                Value                            
ID          PAN ID              The same PAN ID as on the 
                                Coordinator (e.g. 312)

NJ          Node Join Time      1 x 1 sec

DH          Destination High    High Address of Coordinator Node
            Address             e.g. 13A200

DL          Destination Low     Low Address of Coordinator Node
            Address             e.g. 40C05061

NI          Node Identifier     Some name (e.g. sensor-node0)

SM          Sleep Mode          Cyclic Sleep [4]

SN          Number of Cyclic    1E
            Sleep periods

SO          Sleep Options       4

AP          API Mode            2

SP          Cyclic Sleep Period 3E8 x 10 ms

ST          Time before Sleep   3E8 x 1 ms

D3          AD3/DIO3 Config.    ADC [2]

IR          IO Sampling Rate    400 x 1 ms

V+          Supply Voltage      0C00
            High Threshold

These are a lot of values that seems to be a bit cryptic but if you know what how it works it's logical. Let me try to explain the important parts.
First of all you have to know my setup to understand the settings above.
To measure the temperature I simply use a TMP36 temperature sensor and the circuit looks like this

You can see that this is a really simple circuit which could be very small. To get better results one could add an additional capacitor between +3.6V and the signal pin of the TMP36 but it also works without it. The signal pin of the TMP36 is connected to the AD3 pin of the XBee.
Because when measuring the temperature of a room you don't expect the temperature to change very fast it makes sense to measure the temperature only every couple of minutes and put the XBee to sleep between the measurements.
So the procedure that I use in my Sensor Network measures the temperature every 5 minutes (which still is to often :) ).

So now we know all parameters to understand the setup of the XBee, let's have a look:

We need to configure pin AD3 as an analog input pin which is done by the parameter:

D3          AD3/DIO3 Config.    ADC [2]

Enabling the cyclic sleep mode is done by the parameter:

SM          Sleep Mode          Cyclic Sleep [4]

Now we need to define the sleep cycle which is done by the following parameters:

SN          Number of Cyclic    1E
            Sleep periods

SO          Sleep Options       4
            Extended cyclic
            sleep (SN x SP)

SP          Cyclic Sleep Period 3E8 x 10 ms

ST          Time before Sleep   3E8 x 1 ms
                        1000ms wake time

IR          IO Sampling rate    400 x 1 ms
            Sample ever 1024ms
            (Should be a bit
            higher than ST to
            send 1 sample)

All numeric parameters in the XCTU software are in hexadecimal!!!

Means we define one sleep cycle as long as 

(SP) 0x3E8 => 10000 ms and the number of cycles to sleep should be (SN) 0x1E -> 30 which means the XBee should sleep 10000 x 30 ms = 300000 ms = 5 Minutes.

The sample time is set to (IR) 0x400 => 1024 ms and the time before the XBee goes to sleep again is set to (ST) 0x3E8 => 1000ms which means it will wake up after 5 Minutes, will sample data on pin AD3 and before it can sample data again it will fall a sleep again.

Now you should save this profile in XCTU.

You have to repeat that procedure for each Sensor Node and because you saved the profile the only thing you have to change is the NI parameter which is the name of the Sensor Node. This name will later be part of the message and makes it easier to identify the Sensor Node.

Connecting the Coordinator:
Because I would like to use only embedded devices I've decided to use a Raspberry Pi as my "Coordinator Node Server". Means the Coordinator Node will be hooked up to the Raspberry Pi. The easiest way I found out was to use a little add-on board named "Slice of Pi" which looks like this

This board has a socket for the XBee which makes it really easy to connect the XBee to the Pi.

Talking to the XBees
Now that we have the hardware in place the Sensor Network is working already but how could we get the data?
Well there is a really nice Java project on GoogleCode named xbee-api. With this Java library it's really easy to connect to the XBee that acts as a Coordinator Node attached to the Raspberry Pi. To be able to connect to the XBee that is connected to the Slice of Pi board you need to make sure that the following settings on the Pi are set:

1. Remove all references to ttyAMA0 from /boot/cmdline.txt

2. Comment the line "T0:23respawn:/sbin/getty -L ttyAMA0 115200 vt100" in /etc/inittab

3. Sudo apt-get install librxtx-java

The nice thing about the xbee-api library is that you can attach a listener to the XBee Coordinator and you will get notified everytime a XBee Sensor Node sends it's data.

If you would like to play around with it you will find examples on how to use the API with a Receiver and Sender here.

This should be enough for keep coding... :)

Friday, September 12, 2014

Friday Fun Component XIX


Yesterday night I needed some time to relax and when I looked on my Galaxy S4 I saw a little widget installed called Minimal Clock which is a nice example of a simple flat ui clock.
So I've decided to clone that widget in JavaFX and here is the result:

As you can see it looks very similar to the original version but it doesn't have all the features. My version only shows the time and date but one could define the colors for all the elements.
Like I said this control was only created to relax but hey...if you like it...fork it on bitbucket

BitBucket Repository

That's it for today and don't forget...keep coding :)