Monday, November 28, 2016

Implicit Network Time Synchronization - timesynch file

Objective

In this tutorial, i am going to show you how to use the Implicit Network Time Synchronization of Contiki OS in real nodes. I am using the sky motes CM5000, Contiki OS v3.x and Lubuntu v16.04. It is important to notice that this synchronization mechanism only works in sky nodes.

Background

The Implicit Network Time Synchronization is implemented in Contiki via 2 files: timesynch.c and timesynch.h

/home/YOUR_USER/Desktop/contiki/core/net/rime/timesynch.c
/home/YOUR_USER/Desktop/contiki/core/net/rime/timesynch.h

If you want to get a deep understanding of the synchronization mechanism, please read the following 2 references:

http://anrg.usc.edu/contiki/images/f/fd/Time_Synchronization.pdf

http://dunkels.com/adam/chen07time.pdf

The first link is a presentation that explains the synchronization mechanism very clearly, and the second link is a paper of Adam Dunkels (The author of the timesynch.c.h files). Now, i am going to explain in my own words the synchronization mechanism.

Synchronization Mechanism in my own words

How the CM5000 sky mote counts the time? To count time the CM5000 sky node has a 16-bit timer (TIMER_A) capable of counting from 0 to 65535. In every clock tick the counter is incremented in 1. Besides, when the TIMER_A is equal to 32768, then 1 second has passed. And when the TIMER_A is equal to 65536, then 2 seconds has passed. Notices, than when TIMER_A = 65536, it overflows and goes back to 0 (because we have a 16-bit timer). Hence, this timer is only capable of counting up to 2 seconds, then it overflows.

How to synchronize 2 nodes? If you want to synchronize 2 nodes, then the TIMER_A of both of them must have the same value. Usually, both timers do not have the same value because it is virtually impossible to reset the 2 nodes at the same time to make that both timers start from 0 at the same time. Besides, the clock tick can be slightly different between the 2 sensor nodes. Hence, in order to synchronize the 2 nodes the timesynch file constantly sends a broadcast synchronization message that compares the TIMER_A from node 1 and the TIMER_A from node 2.

How does timesynch file work? This file constantly sends a broadcast synchonization message that compares the TIMER_A from node 1 and the TIMER_A from node 2. The difference between those values is called the offset. Let me say here, that the 2 nodes have an important parameter called Authority level, which is used to determine which node has the reference time. Here, i am going to establish that the Node ID is equal to the authority level (You can assign the authority level any way you want). The node whose authority level is lower will be the owner of the reference time. In this example (See Figure below), node 1 has an authority level of 1, hence, it is the owner of the reference time. It means that if node 1 has a TIMER_A = 15, this will be the actual time of the network, and the other nodes will have to modify their TIMER_A (by summing the offset) to agree with this time. In the next figure, i assume that node 2 has a TIMER_A = 10. Therefore, the offset (difference between node1's TIMER_A (15) and node2's TIMER_A (10) = 15 - 10 = 5 ) is equal to 5. In conclusion, the actual time of the network is node1's TIMER_A = 15, and node 2 corrects its timer by summing the offset (10 + 5 = 15), then both nodes think they synchronized (they have the same time of 15).

Test the rime broadcast example

In this section, i am just going to upload the rime broadcast example in 2 sensor nodes. In the next section i am going to enable the Implicit Network Time Synchronization for this broadcast example.

Here, i am going to use the broadcast example from rime, hence, open the following file:

cd /home/YOUR_USER/Desktop/contiki/examples/rime/
gedit /home/YOUR_USER/Desktop/contiki/examples/rime/example-broadcast.c

This file just sends a broadcast message every 2 to 4 seconds. Clean, compile and upload this file to 2 nodes using the following command:

make clean && make TARGET=sky example-broadcast.upload

Note that i am using TARGET=sky since i am working with sky CM5000 nodes (The Implicit Network Time Synchronization mechanism only works on sky nodes ). Then look to which serial your nodes are connected using this:

make TARGET=sky sky-motelist

Notice one device from the list, for example, the /dev/ttyUSB0. Then connect to one of your nodes to see the arriving broadcast messages:

make TARGET=sky login MOTES=/dev/ttyUSB0

If the broadcast messages are arriving correctly, then you should see this:

broadcast message received from X.X: 'hello'
broadcast message sent

where, X.X is the address of the node that sends the message, for example, 185.144 or another number ( This number does not really matter). Besides, you see that the node connected to /dev/ttyUSB0 is actually sending messages: broadcast message sent.

Enable Implicit Network Time Synchronization for the rime broadcast example

To enable the Implicit Network Time Synchronization, you must create a project-conf.h file as follows:

cd /home/YOUR_USER/Desktop/contiki/examples/rime/
> project-conf.h
gedit /home/YOUR_USER/Desktop/contiki/examples/rime/project-conf.h

The above does: 1) go to the directory of rime, 2)Create the project-conf.h file, 3) Open the file. Then, in the recently opened file copy this:

#ifndef __PROJECT_CONF_H__
#define __PROJECT_CONF_H__

//Define the network stack
#define NETSTACK_CONF_NETWORK rime_driver // Define the network driver to use
#define NETSTACK_CONF_MAC     csma_driver // Define the MAC driver to use
#define NETSTACK_CONF_RDC     nullrdc_driver // Define the RDC driver to use. 
#define NETSTACK_CONF_FRAMER  framer_802154 // Define the framer driver to use
#define NETSTACK_CONF_RADIO   cc2420_driver // Define the radio driver to use. 

#undef TIMESYNCH_CONF_ENABLED  // TO ENABLE THE Implicit Network Time Synchronization
#define TIMESYNCH_CONF_ENABLED 1 // TO ENABLE THE Implicit Network Time Synchronization

//Define the channel to be used
#define RF_CHANNEL 20

#endif /* __PROJECT_CONF_H__ */

The lines that actually enable the Implicit Network Time Synchronization are only 2, and the rest is optional (Another configuration parameters). If you just want to enable the Synchronization mechanism, then copy the following lines in your project-conf.h file.

#ifndef __PROJECT_CONF_H__
#define __PROJECT_CONF_H__

#undef TIMESYNCH_CONF_ENABLED  // TO ENABLE THE Implicit Network Time Synchronization
#define TIMESYNCH_CONF_ENABLED 1 // TO ENABLE THE Implicit Network Time Synchronization

#endif /* __PROJECT_CONF_H__ */

Now, modify your Makefile, and include the following line:

CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"

To modify your Makefile do this:

cd /home/YOUR_USER/Desktop/contiki/examples/rime/
gedit /home/YOUR_USER/Desktop/contiki/examples/rime/Makefile

Copy and paste this line CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\", and your Makefile should look like this:

CONTIKI = ../..

all: unmodulated_carrier example-abc example-mesh example-collect example-trickle example-polite \
     example-rudolph1 example-rudolph2 example-rucb \
     example-runicast example-unicast example-neighbors 

CONTIKI_WITH_RIME = 1
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
include $(CONTIKI)/Makefile.include

Then, you need to modify the contiki-conf.h file by doing this:

cd /home/YOUR_USER/Desktop/contiki/platform/sky
gedit /home/YOUR_USER/Desktop/contiki/platform/sky/contiki-conf.h

In the recently opened file cut this lines:

/* include the project config */
/* PROJECT_CONF_H might be defined in the project Makefile */
#ifdef PROJECT_CONF_H
#include PROJECT_CONF_H
#endif /* PROJECT_CONF_H */

And paste them at the beginning of the contiki-conf.h file, then your file must look like this:


// START OF FILE (THIS IS A NOTE FROM THIS BLOG)

#ifndef CONTIKI_CONF_H
#define CONTIKI_CONF_H

/* include the project config */
/* PROJECT_CONF_H might be defined in the project Makefile */
#ifdef PROJECT_CONF_H
#include PROJECT_CONF_H
#endif /* PROJECT_CONF_H */

// ANOTHER STUFF (THIS IS A NOTE FROM THIS BLOG)

That's it. You have enabled the Implicit Network Time Synchronization in Contiki.

See Debug Messages for the Implicit Network Time Synchronization

To see debug messages open the timesynch.c and add the following line at the end of the broadcasr_recv function:

printf("broadcast_recv, timesynch_offset = %u timesynch_authority_level = %d \n\r", timesynch_offset(), timesynch_authority_level());

Hence, your broadcasr_recv function should look like this:

static void
broadcast_recv(struct broadcast_conn *c, const linkaddr_t *from)
{
  struct timesynch_msg msg;

  memcpy(&msg, packetbuf_dataptr(), sizeof(msg));

  /* We check the authority level of the sender of the incoming
       packet. If the sending node has a lower authority level than we
       have, we synchronize to the time of the sending node and set our
       own authority level to be one more than the sending node. */
  if(msg.authority_level < authority_level) {
    adjust_offset(msg.timestamp + msg.authority_offset,
                  packetbuf_attr(PACKETBUF_ATTR_TIMESTAMP));
    timesynch_set_authority_level(msg.authority_level + 1);
  }

  printf("broadcast_recv, timesynch_offset = %u timesynch_authority_level = %d \n\r", timesynch_offset(), timesynch_authority_level());

}

Now, go to the step Test the rime broadcast example and run the broadcast example again. You should see the printf that we just added that shows the offset and the authority level of each node when a synchronization broadcast arrives:

broadcast_recv, timesynch_offset = {0-65535} timesynch_authority_level = {AUTHORITY_VALUE}

Notice that you can modify the timesynch_authority_level with the function timesynch_set_authority_level. If you see the message above, then you successfully configured your Implicit Network Time Synchronization mechanism.

NOTE: It is important that you notice that in this example there are 2 kinds of broadcasts. The first kind of broadcast is the 'hello' message sent by the rime example (example-broadcast.c). The second kind of broadcast is the synchronization message sent by the timesynch.c file

Wednesday, November 16, 2016

How to clone Contiki OS from Github using git

Objective

To clone the Contiki OS software from Github. Then, to upload the Contiki files to your own Github repository.

Step 1: Clone the Contiki OS software from Github

To clone Contiki OS from github, go to your desktop directory and clone Contiki as follows:

cd /home/YOUR_USER/Desktop/
git clone https://github.com/contiki-os/contiki.git

After this step, the following directory was created /home/YOUR_USER/Desktop/contiki. That's it, you are done! Now, you can develop your own applications under Contiki. If you want to upload the Contiki files to your own Github repository see the next step.

Step 2: Upload the Contiki files to your own Github repository

If you develop applications for Contiki and want to save this files in your own Github repository, read this section. First you need to create your own repository, and to do so, see the following link, specifically see the section Create a new repository on GitHub:

https://help.github.com/articles/create-a-repo/

Then, 1) Go to your contiki folder 2) Add your remote repository, 3) Verify that it was added, 4) upload the Contiki files to your repository with the push command:

cd /home/YOUR_USER/Desktop/contiki
git remote add NAME_YOU_CHOOSE https://github.com/YOUR_GITHUB_USER/YOUR_GITHUB_REPOSITORY.git
git remote -v
git push -u NAME_YOU_CHOOSE master

After the push command, you must introduce your Github user and password. Then, go to your Github repository and verify that the file were uploaded, you must see this:

Now, we are going to create a new folder named MyExample, and a file named example.c

cd /home/YOUR_USER/Desktop/contiki/examples/
mkdir MyExample
cd /home/YOUR_USER/Desktop/contiki/examples/MyExample
> example.c

Next, we are going to: 1) see the status of the git 2) Add all the changes to Github 3) Commit the changes 4) Upload the changes with the push command.

git status
git add -A
git commit -m "This is the Commit Message"
git push -u NAME_YOU_CHOOSE master

After the push command, you must introduce your Github user and password. That's it, you are done! Now, go to your Github page, and look for the folder /YOUR_GITHUB_REPOSITORY/examples/MyExample and its file example.c.

Sunday, November 13, 2016

Setting node ID for the re-mote (zoul)

Objective

The objective of this tutorial is to set up the id of the re-motes from Zolertia using Contiki-3.0. I am using the RIME stack for this example.

Procedure

To find a comprehensive explanation of how to set up the node ID of the re-motes please go to this link and see section Node IEEE/RIME/IPv6 Addresses

https://github.com/contiki-os/contiki/tree/master/platform/zoul

If you want to set up the re-mote address at compilation time you could simply add NODEID=YOUR_ADDRESS when uploading the code to the node, as follows:

make NODEID=0x0001 TARGET=zoul sink-channelQuality.upload

This line configured the rime address to 00:01, and when you reset the node, then you can see the following:

Contiki-2.6-4041-gaad203e
Zolertia RE-Mote revision B platform
CC2538: ID: 0xb964, rev.: PG2.0, Flash: 512 KiB, SRAM: 32 KiB, AES/SHA: 1, ECC/RSA: 1
System clock: 16000000 Hz
I/O clock: 16000000 Hz
Reset cause: External reset
Rime configured with address 00:01
Net: Rime
MAC: CSMA
RDC: ContikiMAC

It is important to notice the line Rime configured with address 00:01, which says that we just changed the rime address of the re-mote.