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. 

Attention:
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)

Attention:
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)

Attention:
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 today...so keep coding... :)

No comments:

Post a Comment