Friday, January 27, 2017

Over the air programming in Contiki

Objective

Here, i am going to redirect you to the Sparrow Application Layer and tools that provides over the air programming in Contiki.

Links

The Sparrow Application Layer and tools developed by Yanzi Networks and tested on the Zolertia Remotes provides over-the-air programming. I tested it and worked fine:

1) Tutorial from Zolertia:

https://github.com/Zolertia/Resources/wiki/Sparrow

2) Documentation and code from Yanzi Networks

https://github.com/sics-iot/sparrow/wiki/Sparrow-OTA

Monday, December 12, 2016

How to improve the packet reception rate of your sky nodes

Objective

The objective of this tutorial is to improve the packet reception rate of your sky nodes. For this tutorial, i am going to be using sky CM5000 nodes, Contiki V3.x and Lubuntu 16.04.

Problem

In this section i am going to describe the problem that i had with the CM5000 sky nodes. When i got my CM5000 nodes, the first thing that i wanted to test was sending a unicast message from node 2 to node 1. To that end, i used an example from the rime stack named example-unicast.c located in /home/YOUR_USER/Desktop/contiki/examples/rime. This example is very straightforward since it sends unicast messages from a node to node 1. However, when you run this example you have to make sure that a node within the network has address 1. In order to set one node with address 1, you can see the following tutorial:

http://contiki-iot.blogspot.com.co/2016/06/setting-node-id-for-sky-motes.html

The unicast rime example runs fine. You can see that the messages from node 2 to node 1 arrives. However, the problem is that a huge amount of messages are lost. You may wonder why. Why a huge amount of messages are lost in a simple unicast message sent from node 2 to node 1? What is the problem with the rime unicast example?

Solution to the problem

At first i thought that the wireless channel had a lot of interference. Then, i read in the book Internet of things in 5 days (link below) that wireless channels 15, 20, 25 and 26 do not overlap with WiFi. Besides, the default wireless channel used by Contiki rime is 26, hence, there should not be any interference problems. Additionally, i used the Spectrum Analizer Application available in Contiki, (which is explained in the link below) and i realized that there were no other transmissions in channel 26. In conclusion, the problem was not interference on the wireless channel. So, what was the problem? Why a huge amount of messages were lost when using the rime unicast example?

http://wireless.ictp.it/school_2015/book/#_ieee_802_15_4_channels_and_pan_id

After discarding wireless interference, i started reading about the Contiki stack (See link below). Then, i realized that there was a layer called Radio Duty Cycling which was in charge of turning the radio on and off to save energy.

http://anrg.usc.edu/contiki/index.php/Network_Stack

The default Radio Duty Cycling used by Contiki is called ContikiMAC. To understand the ContikiMAC, please go to the following link:

https://github.com/contiki-os/contiki/wiki/Radio-duty-cycling

After reading the above link, i understood that the receivers periodically turn on their radios to inspect for messages in the channel. So, the answer to my problem was: A lot of messages are lost in the rime unicast example because the receiver node (node 1) does not poll the radio medium with the appropriate frecuency. So, i increased the polling rate and no more messages were lost. In Contiki the polling rate is referred as RDC_CHANNEL_CHECK_RATE. It is important to notice that the RDC_CHANNEL_CHECK_RATE is proportional to the energy consumption of the nodes, i.e. if the node has a higher RDC_CHANNEL_CHECK_RATE, then it will consume more energy.

Implementation of the solution

Before you implement the solution, you must be aware that it will increase the energy consumption of the nodes.

In order to implement the solution all you have to do is to increase the RDC_CHANNEL_CHECK_RATE. In order to do so, you must first create a project configuration file project-conf.h (Please do the following tutorial) :

http://contiki-iot.blogspot.com.co/2016/07/project-configuration-example.html

In the above tutorial i created a project configuration file and changed the necessary stuff to make it work. Besides, in the above tutorial, i changed the radio channel from 26 to 20. But in this tutorial i want to change the RDC_CHANNEL_CHECK_RATE. To do so, just add the following line to your project-conf.h file.

#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 128 //Change the rate at which the node check for radio activity in the channel

The above line says that the node will turn the radio on 128 times per second to check whether there is a packet in the channel. The default RDC_CHANNEL_CHECK_RATE is 8. So, increasing the check frequency to 128 ensures that no packet is lost.

Verify the solution

To verify that the changes were made do this: 1) upload the unicast rime example to a sky node, 2) connect to it via a serial port, 3) the reboot the node manually. You can do the first 2 steps with this command line:

make clean && make TARGET=sky example-unicast.upload && make login

After manually rebooting the node, you should see this:

Rime started with address 2.0
MAC 02:00:00:00:00:00:00:00 Contiki 3.0 started. Node id is set to 2.
nullsec CSMA ContikiMAC, channel check rate 128 Hz, radio channel 20
Starting 'Example unicast'

This is the message shown by the node when it is rebooted. This message shows that the RDC_CHANNEL_CHECK_RATE is equal to 128: channel check rate 128 Hz . If you see that message then your problem is solved. You must not have any lost packets.

Friday, December 2, 2016

How to calculate the latency in Contiki OS

Objective

In this tutorial i am going to show you how to calculate the latency of a packet in a wireless link. I am using Contiki v3.x, sky (CM5000) nodes and lubuntu 16.04. First of all, to compute the latency of a packet you need to have the nodes synchronized. In order to synchronize the nodes of the network, you can use the Implicit Network Time Synchronization of Contiki, which i explain in the following tutorial:

http://contiki-iot.blogspot.com.co/2016/11/implicit-network-time-synchronization_28.html

It means that you must to do the above tutorial if you want to calculate the latency of a packet.

NOTE: Since the Implicit Network Time Synchronization mechanism of Contiki only works on sky nodes, this latency computation only works on sky nodes too.

Step 1: Synchronize your nodes

As mentioned above, you must have your nodes synchronized to calculate the latency of a packet. In order to synchronize your nodes, go to the following tutorial:

http://contiki-iot.blogspot.com.co/2016/11/implicit-network-time-synchronization_28.html

Step 2: Modify your example-broadcast.c

I am going to calculate the latency of a packet in the broadcast rime example. I got the basic idea from an example named shell-rime-debug.c which is located in /home/YOUR_USER/Desktop/contiki/apps/shell. So, you can go and check that file in order to get the information directly from a contiki source file.

Next, i am going to explain the changes that i made to the example-broadcast.c file:

  • Create a latency structure: We create a latency structure to save the timestamp of the message, i.e. the time when the message was sent.
  • Send a broadcast with the timestamp: The normal/original example-broadcast.c file sends a broadcast with a 'hello' message, in this tutorial, we are going to send a broadcast with the timestamp. So, we comment/delete the 'hello' message and add our timestamp to the broadcast.
  • Receive a broadcast with the timestamp and compute the latency: We receive the broadcast that includes the timestamp. Then, we compute the time difference between the current time (timesynch_time()) and the broadcast timestamp (msg.timestamp), that difference (timesynch_time() - msg.timestamp) is equal to the latency.

Now, we show you the full code:

/*
 * Copyright (c) 2007, Swedish Institute of Computer Science.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Institute nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * This file is part of the Contiki operating system.
 *
 */

/**
 * \file
 *         Testing the broadcast layer in Rime
 * \author
 *         Adam Dunkels 
 */

#include "contiki.h"
#include "net/rime/rime.h"
#include "random.h"

#include "dev/button-sensor.h"

#include "dev/leds.h"

#include 


/*--------------------------------------*/

struct latency_structure{ // Structure to save the time when the message was send

   rtimer_clock_t timestamp;// Time when the message was send

};
/*---------------------------------------------------------------------------*/
PROCESS(example_broadcast_process, "Broadcast example");
AUTOSTART_PROCESSES(&example_broadcast_process);
/*---------------------------------------------------------------------------*/

//Receive a broadcast with the timestamp and compute the latency
static void
broadcast_recv(struct broadcast_conn *c, const linkaddr_t *from)
{
  struct latency_structure msg;
  rtimer_clock_t latency;

  packetbuf_copyto( &msg ); // Copy the message from the packet buffer to the structure called msg

#if TIMESYNCH_CONF_ENABLED
  latency = timesynch_time() - msg.timestamp;
#else
  latency = 0;
#endif

  printf("broadcast message received from %d.%d with latency %lu ms\n",
         from->u8[0], from->u8[1], (1000L * latency) / RTIMER_ARCH_SECOND );
}
static const struct broadcast_callbacks broadcast_call = {broadcast_recv};
static struct broadcast_conn broadcast;
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(example_broadcast_process, ev, data)
{
  struct latency_structure *msg;

  static struct etimer et;

  PROCESS_EXITHANDLER(broadcast_close(&broadcast);)

  PROCESS_BEGIN();

  broadcast_open(&broadcast, 129, &broadcast_call);

  while(1) {

    /* Delay 2-4 seconds */
    etimer_set(&et, CLOCK_SECOND * 4 + random_rand() % (CLOCK_SECOND * 4));

    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));

#if TIMESYNCH_CONF_ENABLED
      msg->timestamp = timesynch_time();
#else
      msg->timestamp = 0;
#endif

    // Do not send the normal/original 'hello' message. Instead, send a message with the timestamp.
    packetbuf_copyfrom(msg,   sizeof(*msg) ); // This message msg includes the timestamp
    //packetbuf_copyfrom("Hello", 6);
    broadcast_send(&broadcast);
    printf("broadcast message sent\n");
  }

  PROCESS_END();
}
/*---------------------------------------------------------------------------*/


Step 3: Upload the code to 2 or more sky nodes

Since the Implicit Network Time Synchronization mechanism of Contiki only works on sky nodes, this latency computation only works on sky nodes. In order to upload the code to the sky nodes, do this:

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

If everything is working correctly you should see a message like this:

broadcast message received from X.X with latency 1167 ms

When i tested the code the latency varies from 12ms to 1652 ms. Notice that X.X is the address of the node that sent the broadcast. In my example, the sky node has address 185.144

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.

Wednesday, August 10, 2016

Generate an improved interfering node in Contiki OS

Objective

The objective of this post is to make an improved version of the interfering node that i made in a previous tutorial:

http://contiki-iot.blogspot.com.co/2016/08/objective-to-create-interfering-node.html

The previous tutorial just generates an unmodulated carrier as noise, i would like to mention that i got the idea and part of the code from the paper [2]. Now, in this tutorial i improved this version of interfering node adding a model of interference called Bursty Interference described in the section 3.3 of paper [1]. The model just turns the unmodulated carrier on and off with different time periods (t1 and t2). For example, it turns the carrier on for 240ms (t1 = 240ms) and then it turns the carrier off for 510ms (t2 = 510ms); the times t1 and t2 follow a uniform distribution between 0 seconds and 1,5 seconds. I strongly recommend you to read the paper [1].

Code for the sky mote

Below i show you the code that implements the improved interfering node. I order to understand the code you must read section 3.3 of the paper [1], i try to add comments to the code and use the same variables that the paper did.

/*
 * Copyright (c) 2007, Swedish Institute of Computer Science.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Institute nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * This file is part of the Contiki operating system.
 *
 */

/**
 * \file
 *       Improved example of an interfering node
 * \author
 *        Sergio Diaz
 */


/*INCLUDES*/
#include "contiki.h"
#include "/home/sink/Desktop/contiki-3.0/dev/cc2420/cc2420_const.h" // Include the CC2420 constants 
#include "/home/sink/Desktop/contiki-3.0/core/dev/spi.h" // Include basic SPI macros
#include "dev/leds.h" // Include Leds to debbug
#include "sys/rtimer.h" //Include the real time library

/*DEFINES*/
#define INTERFERENCE  0x01 // I set the less significant bit to indicate there is interference (0x01 = 00000000 00000001)
#define CONSTANT_MICROS 300 // 300 us was defined by the paper [1]
#define TIME_TICK 31 // The time of 1 tick is 30,51 us in rtimer for sky motes in Contiki v3.0. TIME_TICK = 1 / RTIMER_ARCH_SECOND = 1 / 32768 s


/*STRUCT DEFINITIONS*/
struct states{
 unsigned char carrier; // Defines the state of the carrier: Either INTERFERENCE = 0x01 or Not INTERFERENCE = ~0x01
};

struct states state; //Create the state of the carrier
static struct rtimer rtimer; // Create the rtimer variable

/*FUNCTION DEFINITIONS*/

/*---------------------------------------------------------------------------*/
/*
* Generate a random number between 0 and (MaxValue - 1)
*/
unsigned int random_number(unsigned int MaxValue){
       return  rand() % MaxValue;
}
/*---------------------------------------------------------------------------*/
/** 
 * Writes to a register.
 * Note: the SPI_WRITE(0) seems to be needed for getting the
 * write reg working on the Z1 / MSP430X platform
 */
static void
setreg(enum cc2420_register regname, uint16_t value)
{
  CC2420_SPI_ENABLE();
  SPI_WRITE_FAST(regname);
  SPI_WRITE_FAST((uint8_t) (value >> 8));
  SPI_WRITE_FAST((uint8_t) (value & 0xff));
  SPI_WAITFORTx_ENDED();
  SPI_WRITE(0);
  CC2420_SPI_DISABLE();
}

/* Sends a strobe */
static void
strobe(enum cc2420_register regname)
{
  CC2420_SPI_ENABLE();
  SPI_WRITE(regname);
  CC2420_SPI_DISABLE();
}

/*
* Function called by the rtimer to turn the carrier on and off.
*/
static void carrier_OnOff(struct rtimer* timer, void* ptr)
{

    unsigned int R; // Uniformly distributed over [1,100]
    unsigned int Qx;  // Uniformly distributed over [1,x], where x = 50
    unsigned int randNum; // Random number between [1-10]
    uint32_t time_next_period; // Next time period. The duration of the interference or not interference state.
    uint32_t num_ticks; // Number of ticks of the time_next_period

    // Calculate a random number between [1-10]
    randNum = 1 + abs( random_number(10) ) ;
    
    // Decide whether to produce interference or not with equal probability (0.5)
    if( randNum <= 5) // If the random number is less than 5 generate no interference 
    {
        // In this case there will be no interference
        state.carrier &= ~INTERFERENCE; // Set the carrier state to no interference (NOT INTERFERENCE)
    }else{
        // In this case there will be interference
        state.carrier |= INTERFERENCE; // Set the carrier state to interference
    }

    // Turn the unmodulated carrier on or off depending on the carrier state (state.carrier)
    if( state.carrier & INTERFERENCE) // should the node generate interference?
    {
       //The node must generate interference. Turn the carrier on.
       // Creates an unmodulated carrier by setting the appropiate registers in the CC2420
       setreg(CC2420_MANOR, 0x0100); 
       setreg(CC2420_TOPTST, 0x0004);
       setreg(CC2420_MDMCTRL1, 0x0508);
       setreg(CC2420_DACTST, 0x1800);
       strobe(CC2420_STXON);
       // Turn the leds for debug. LEDS_RED on means there is interference
       leds_on(LEDS_RED);
       leds_off(LEDS_GREEN);

    }else{
       //The node must not generate interference. Turn the carrier off.
       //Reset the changes and set back the CC2420 radio chip in normal mode.
       //Not generate unmodulated carrier
       setreg(CC2420_MANOR, 0x0000);
       setreg(CC2420_TOPTST, 0x0010);
       setreg(CC2420_MDMCTRL1, 0x0500);
       setreg(CC2420_DACTST, 0x0000);
       strobe(CC2420_STXON);
       // Turn the leds for debug. LEDS_GREEN on means there is no interference
       leds_on(LEDS_GREEN);
       leds_off(LEDS_RED);
    }
    // Calculate the time of the next period ( time_next_period = R*Q(x)*CONSTANT_MICROS ) 
       R  = 1 +  abs( random_number(100) )  ; // Generate random numbers between [1,100]
       Qx = 1 +  abs(random_number(50))   ; // Generate random numbers between [1,50]
       time_next_period = R * Qx ; // Compute the next time period according to the paper [1]
       time_next_period = time_next_period * CONSTANT_MICROS ;  // Compute the next time period according to the paper [1]


    // Set the rtimer to the time_next_period (num_ticks)
       num_ticks = time_next_period / TIME_TICK; // Compute the number of ticks that corresponds to time_next_period
       printf("Interference = %d ,R = %d, Qx = %d, time = %lu, ticks =  %lu \n", state.carrier & INTERFERENCE, R, Qx, time_next_period, num_ticks); // View the results in console
       rtimer_set(&rtimer, RTIMER_NOW() + num_ticks , 1, carrier_OnOff, NULL);// Set the rtimer again to the time_next_period (num_ticks)
}


/*---------------------------------------------------------------------------*/

PROCESS(turn_carrier_OnOff, "Turn Carrier On Off"); // Declares the process to turn the carrier on and off
AUTOSTART_PROCESSES( &turn_carrier_OnOff); // Load the process on boot

PROCESS_THREAD(turn_carrier_OnOff, ev, data) // Process to turn carrier on and off
{ 
   
  PROCESS_BEGIN(); // Says where the process starts

  rtimer_set(&rtimer, RTIMER_NOW() + RTIMER_ARCH_SECOND, 1, carrier_OnOff, NULL); //Initiates the rtimer 1 second after boot

  PROCESS_END();  //Says where the process ends
}

/*---------------------------------------------------------------------------*/


Video

I created an unmodulated carrier at channel 20 and to visualize the signal i am using the rssi-scanner provided by Contiki. The vertical node is the interfering one. When the interfering node's red led is on, then the carrier at channel 20 appears; and when the interfering node's green led is on, then the carrier at channel 20 disappears. The time of carrier on/off is a uniform distribution between 0 and 1,5 seconds.

References

[1] Boano, Carlo Alberto; Voigt, Thiemo; Tsiftes, Nicolas; Mottola, Luca; Römer, Kay; Zúñiga, Marco Antonio. Making Sensornet MAC Protocols Robust against Interference. Proceedings of the Wireless Sensor Networks: 7th European Conference - EWSN, Coimbra, Portugal, February 17-19, 2010, pp. 272-288.

[2] C. A. Boano, Z. He, Y. Li, T. Voigt, M. Zúñniga and A. Willig, "Controllable radio interference for experimental and testing purposes in Wireless Sensor Networks," 2009 IEEE 34th Conference on Local Computer Networks, Zurich, 2009, pp. 865-872.