Dada communication capabilities available on WSN motes enable the exchange of data among WSN motes. In this chapter, we will learn how Contiki-NG aids communication among WSN motes and from a WSN mote to a computer. We will also explore how to build middleware that enables WSN motes to communicate with other systems.
Communication models for Contiki-NG
Serial communication
Building communication among Contiki-NG motes
Building communication between computer and Contiki-NG motes
Developing middleware
Communication Models for Contiki-NG
How you want to communicate between WSN motes and computers will determine what kind of communication model you use. As you know, each WSN mote usually has network capability so it can exchange data with WSN motes and computers.
In this chapter, we will learn how WSN motes communicate with others. We need at least two motes to implement our demo.
Serial Communication
Serial communication can be defined as a process used to send and receive a bit at a time sequentially. Sometimes serial communication is called UART (Universal Asynchronous Receiver/Transmitter). Technically, we already used serial communication when we uploaded Contiki-NG programs to WSN motes in previous chapters. We also communicate with WSN motes via the printf() function. Then, we listen to the messages from printf() using the command make login.
Communication Between Contiki Mote and Computer
In this section, we will build Contiki and Contiki-NG programs to communicate between a Contiki mote and a computer. This is useful because we can control our Contiki motes from the computer. Running applications on a computer has benefits, such as interacting with the database server and communicating with the cloud server.
There are a lot of methods used to communicate between a computer and a Contiki mote. We will focus on two methods: serial communication and shell. We will explore these methods in the next section.
Let’s build!
Access Contiki Motes via Serial Communication
Since our WSN motes are attached to the computer through serial communication, we can initiate communication between the computer and a WSN mote. Some application platforms, such as C/C++, Java, Python, C#, and Node.js, provide libraries with which to implement serial communication.
In this section, we will try to access WSN motes using Python through serial communication. To implement serial communication in Python, we use the pyserial library. You can find this library at https://pypi.python.org/pypi/pyserial . This library can be installed using pip.
You can verify if your computer has installed pip or not. You can type this command in Terminal:
If you don’t get a response, it means your computer is missing the pip program. You can install pip using this command in Terminal:
Now, you can install the pyserial library by typing this command in Terminal:
You also can install the pyserial library using easy_install. You can type this command in Terminal:
Make sure your computer is connected to the Internet.
Next, you must write a Python program to listen for incoming messages on a specific serial port. You should know which serial port is used by the Contiki mote. You need it because you will use it on your program.
To find a serial port from the Contiki mote, you can open Terminal and type this command:
You should see a list of connected serial ports available on your computer. Depending on your Contiki mote model, you can verify the port by turning the mote on/off so you should which a new attached serial port. For instance, my Contiki mote is detected as /dev/ttyUSB0. You can see it in Figure 4-3.
Now, you will develop the Python program. You will print all incoming data from the serial port to the console. Set the baudrate to 115200 for the serial-port speed. Create a file, called contiki-viewer.py, and write these complete scripts. Change the PORT value to that for your Contiki-NG mote:
To simulate this demo, you should upload the Contiki-NG program to a Contiki-NG mote. You can use the same program from Chapter 1, Hello World. You should upload that program into the Contiki mote.
After Contiki-NG is deployed with a Contiki-NG program, you can run the Python program, contiki-viewer.py, by typing this command:
If you have error issues related to security access, you probably should run it with administrator privileges. Type this command:
How does this work?
This program starts by initializing the serial library and activating the serial port of the Contiki-NG mote:
After the serial port is activated, we listen for incoming message from that serial port. We call readline() to read data from the serial port. Once we receive data, we print the data to the console:
Last, we close our serial port by calling the close() method.
Contiki Shell
Contiki OS provides a shell API that we can utilize to communicate with internal Contiki-NG motes. We find the shell API in the Contiki source code in <Contiki-root>/apps/shell. You should see several API objects, shown in Figure 4-7.
Contiki shell is very useful. Let’s say you build and deploy a Contiki application onto a Contiki mote. Then, you want to analyze what is happening inside the Contiki mote. To do this, you can build a custom Contiki shell related to your needs. You call the shell from the Contiki-NG mote and perform your analysis.
One important thing that you should know is the limitations on Contiki mote storage and resources. Building more Contiki shell APIs means using more mote resources. Make sure your Contiki shell is optimal for your Contiki mote model.
In this section, we will learn how to build a Contiki shell application and then deploy it to a Contiki mote. For this simple demo, we will use a Contiki sample from the Contiki source code. You can see it at <Contiki-root>examples/example-shell. This program runs for native platforms such as a computer.
Open the example-shell.c file. You should see the PROCESS_THREAD(example_shell_process, ev, data) function, as follows:
Each shell API is defined as shell_xxx(). Remarked codes are not supported for native platforms such as a computer.
Now, you can compile and run this program. Open Terminal and navigate to the <Contiki-root>examples/example-shell folder. Then, type these commands:
For this demo, you call one of the Contiki shells. To get a list of Contiki shells, you can call the help shell command:
You have run a Contiki shell on the computer as a native application. Now, you will build a Contiki shell for a Contiki mote. For demo purposes, I will use TelosB hardware that’s type is Sky.
You will use a sample program from the Contiki source code. You can find shell-sky at <Contiki-root>examples/shell-sky folder. If you open the sky-shell.c file, you should see the PROCESS_THREAD(sky_shell_process, ev, data) code as follows:
You only use some essential shells due to the Contiki mote’s resource limitation. Other shell APIs are remarked.
Now, compile and upload this program into your Contiki mote. For instance, I use the Contiki-NG mote–based Sky. Open Terminal and navigate to the <Contiki-root>examples/shell-sky folder. You can type these commands to compile and upload the program to the Contiki-NG mote with sky as target:
After it has completed, you can monitor your Contiki mote. You can type this command:
Then, reset your Contiki mote in order to use the Contiki shell. If it succeeds, you should see the Contiki shell terminal as follows:
From the Contiki shell, you can test it using the commands help and echo. You can type these commands:
A sample of the program output from the Contiki shell can be seen in Figure 4-11.
Contiki-NG Shell
You can enable the shell module in the Makefile file from your projects. Put this script in to enable this module:
Then, you can compile and upload your project program into your Contiki mote. Since Contiki-NG needs more space on the Contiki mote, your mote probably does not fit the program, so you will get an error while compiling and flashing the program.
After you succeed in uploading program, you can test it by connecting to the Contiki mote via a serial tool. You should get “>” on the serial Terminal. Not all Contiki motes can run the Contiki-NG shell due to ROM space size. My TelosB board cannot work with this shell. So, I tested it with the TI CC2650 LaunchPad board. It works. I then run this command to access the Contiki-NG serial:
If you do not see “>,” try to reset the board. Then, press Enter. The program output can be seen in Figure 4-13.
Now, you can test Contiki-NG with several commands. Try to execute these shell commands:
Customizing Contiki Shell
In some cases you may need to customize the Contiki shell to fit your problems. The thing that you should be aware of is your space and resource usage while implementing a Contiki shell.
In this section, we will learn how to customize a Contiki shell on both Contiki and Contiki-NG. In Contiki-NG, a Contiki shell is called an NG shell. Each customizing shell topic will be explored in the next sections.
Custom Contiki Shell
In the previous section, we learned how to access Contiki and Contiki shells. Now, we will build our own Contiki shell API. For this simple demo, we will develop a Contiki shell with an addition math operation. This API will receive two number parameters. These number parameters will be added and then sent back as the Contiki shell output.
To build our own Contiki shell, we can add our shell objects to the <Contiki-root>/apps/shell folder. For our scenario, we add two files, shell-math.c and shell-math.h. You can see them in Figure 4-15.
There are two steps to building a custom Contiki shell. First, we create an object file (*.c) in which to declare all Contiki shell implementations. We declare the Contiki shell API using SHELL_COMMAND(). Then, we implement the shell API on a process by declaring it in PROCESS().
For implementation, we start to write the program in the shell-math.c file. We receive two number input parameters. Then, we perform the addition operation. The following is the complete program for the shell-math.c file:
Input data from the user can be obtained from the data variables in the function parameters. We parse the data into two number variables.
Next, we write a header file, called shell-math.h, for our Contiki shell API. We only declare our function, shell_math_init(). The following is the complete program for the shell-math.h file:
Save all the files.
Now, we should configure Makefile to include these files in compilation. You can open Makefile.shell in the same folder with the shell API files. Open this file and add your shell files. You can see them in the codes here:
Our Contiki shell API is now ready for compiling.
shell-math-demo.c
Makefile
The shell-math-demo.c file consists of a program to use the Contiki math shell API. The following is the complete program in the shell-math-demo.c file:
Furthermore, we write scripts in the Makefile. We include Contiki and the project path. You write these complete scripts as follows:
CONTIKI_WITH_RIME = 1 is used to enable the RIME protocol since Contiki shell uses it on some shell commands. We also supply a testing configuration by including this Makefile, /home/user/nes/testbed-scripts/Makefile.include, because some shell commands need it.
Save all files.
Now, we compile our program, shell-math-demo. Open Terminal and navigate to the shell-math-demo folder. Type these commands:
After our program is uploaded to Contiki mote, we can monitor the mote. You can type this command:
If it succeeds, you should see the Contiki shell. Now, we can call our Contiki shell API. We can type this command in the Contiki shell:
Custom Contiki-NG Shell
Contiki-NG applies shell with a different approach. To customize a shell, we can add our shell command to the shell-commands.c file. You can find that file in the <contiki-ng-root>/os/services/shell folder. You can see it in Figure 4-17.
We add a new shell command to the shell-commands.c file. We define a “hello” command. We print the message "Hi, this is a custom shell" to Terminal. Write this code:
Next, we also register our shell in the shell_command_t shell_commands struct. We define the shell name, method call, and description. For instance, you can see the code for our custom NG-shell here:
Now, you can use the NG shell on your project. For instance, we can use a hello-world project and enable the Contiki-NG shell. We only enable shell service on Makefile:
After that, we compile and flash this program onto the Contiki-NG mote. You can now remote into the Contiki mote Terminal using mote login. For instance, I remote access my TI LaunchPad CC2650 using this command:
You should change TARGET and PORT to reflect your Contiki board. Please press the Reset button on the Contiki mote if you do not see anything in Terminal. Now, you can test your own shell:
Communication among Contiki Motes
In this section, we will build a communication among Contiki-NG motes. There are a lot of methods for communicating among Contiki-NG motes. To show how to communicate among Contiki motes, we use broadcast via UDP protocol in Contiki-NG OS. UDP is a communication stack that provides a set of lightweight communication primitives ranging from local-area broadcast to reliable network flooding.
Our demo scenario is that a mote sends data to all motes. If a mote receives data, it will be shown in Terminal. We use a program sample from Contiki-NG.
Sending Broadcast Messages
The objective of a mote sender is to broadcast data to other motes. For this demo, we use the simple-udp module that is located in the <contiki-ng-root>/os/net folder. We can use the simple_udp_sendto() function to broadcast a message. This method is defined in the simple-udp.h header file:
simple_udp_connection is simple-udp object
data is data that will be sent
datalen is length of data
to is ip address of target
to_port is the port of the target
For instance, we send data to a specific IP address:
Receiving Broadcast Messages
A mote receiver listens for an incoming message that is sent by a mote sender. To build a mote receiver, we can listen for broadcast messages by creating a callback/event function. We can use simple_udp_register() to register our callback function.
For instance, we listen for incoming broadcast messages using this code:
Demo: Middleware Application
Now, we implement our sender and receiver program for Contiki-NG motes. We use a program sample from Contiki-NG, rpl-udp. You can find this project in the <contiki-ng-root>/examples/ folder.
The rpl-udp project consists of two programs, udp-client.c and udp-server.c. The UDP client app (udp-client.c) will send and receive broadcast messages. The UDP server (udp-server.c) will listen for incoming broadcast messages.
In the Makefile file, we configure our project and Contiki-NG paths. Write these scripts for the Makefile file:
Save all files.
Since we need at least two Contiki-NG motes, we should know the serial ports that are used by our Contiki-NG motes. You can check this using this command:
To compile and upload the program to a specific Contiki-NG mote, we should pass MOTES with the serial port of the targeted Contiki-NG mote. For instance, we flash a program to a Contiki mote on serial port /dev/ttyUSB0. You can type these commands:
For the second Contiki-NG mote, you can type these commands:
After all programs are uploaded to the Contiki-NG motes, we can monitor the data exchange among Contiki-NG motes. For Contiki-NG mote 1, we can monitor messages using this command:
For Contiki-NG mote 2, we can execute this command to see exchange data in Terminal. Type this command:
Middleware Application for Contiki-NG
In this section, we will explore using middleware for a Contiki-NG application. In our scenario, WSN motes will broadcast sensor data. Then, we will use a Java tool application from Contiki-NG to read these sensor data on a computer. The result of reading this data will be displayed in Terminal.
Let’s build!
What Is Middleware?
Implementing middleware for a Contiki-NG application could enhance Contiki-NG’s capabilities. As you know, Contiki-NG applications have a limitation in protocol stacks since they have limited hardware resources. Middleware can act as a bridge to connect Contiki-NG motes to other systems, such as database servers, external servers, and RESTful servers.
Middleware Architecture for Contiki-NG
Implementation
To implement our demo, we use our previous program, rpl-udp (<contiki-ng_root/examples/rpl-udp), to be flashed into the Contiki-NG motes. We also use a previous Python program (section: “Access Contiki Motes via Serial”) to listen on the serial port contiki-viewer.py.
Testing
Summary
We have learned to communicate among Contiki-NG motes. We also developed an application to communicate with Contiki-NG motes from a computer. Finally, we built simple middleware for a Contiki-NG application using a Python application tool.
In the next chapter, we will learn to focus on sensing and actuating in Contiki-NG motes.