The SMART(ER) Internet of Things Tutorial - simonduq/contiki-ng GitHub Wiki
This tutorial was built in the context of the SMART(ER) project: http://smarteredu.se.
Setup
This tutorial will get you started with Contiki-NG, both systems and networking aspects. As a development environment, you can use the virtual machine image we provide on a USB stick, or run everything natively on Linux (doc:toolchain-linux) or OSX (doc:toolchain-osx), or use the Docker image (doc:docker).
In this tutorial, we will be exploring different development tools:
- Real devices: you program use a Zolertia Firefly device. For convenience, set the following:
export TARGET=zoul
export BOARD=firefly-reva
- Native node: you will run Contiki-NG as a native Unix process, for simple testing of the network stack.
- Cooja simulation: you will use the Cooja network simulator to run networks without the need to program any physical device.
Getting started
First, run the hello-world
example, on real devices, native node, and Cooja:
Exercise
Let's play with buttons and LEDs.
The Firefly has a user button (there are two buttons, one that resets the node, the other one marked with USER
) and an RGB LED.
First try the existing examples examples/dev/button-hal
and examples/dev/leds.h
.
- From the two examples above, write your own that counts button presses, and sets the LED to the value in the counter.
- Extend your code such as whenever holding the button for 2s, the counter is reset.
NB: the documentation on Contiki-NG processes and events can come handy: doc:processes
Contiki-NG tools
We will now look into a number of tools provided by Contiki-NG:
Exercise
- In
contiki-ng/os/contiki-default-conf.h
, look for the configuration parameter that defines the routing table and neighbor table size. Set their value to different values, and observe the effect on the firmware size. What happens if you set it to a large number, say, 100? - Using the shell, find out the IPv6 address of your neighbors. Can you ping them?
Contiki-NG networking: IPv6 and RPL
We now turn our attention to the IPv6 stack:
Exercise
Let's now extend our button-LED counter example to now have the button trigger the LED on all neighbors in range. We will implement that over UDP. Take a look at the UDP API at doc:udp-communication.
Our protocol is simple: we use UDP port 6060, and the payload is one byte. To create a multicast address that all IPv6 nodes already listen to, use:
static uip_ip6addr_t allnodes_ipaddr;
uip_create_linklocal_allnodes_mcast(&allnodes_ipaddr);
Contiki-NG networking: upper layers
Let's take a look at CoAP and LWM2M:
Exercise
Let's write our own CoAP resource, that returns the current button counter. Start from examples/coap/coap-example-server/resources
, add your own resource and implement it. Test it simply from your local machine.
Preparation for Home Assignment
Exercise: Modify Hello World
The basic hello world program just prints 'Hello World' and then terminates. Your task is now to modify the program so that it forever prints our Hello World every 2 seconds. For this you need to use some Contiki-NG constructs:
- an "etimer" that you need to set and reset
- you need to wait for an event (the event that the timer expires)
Try to modify the hello world code and run it. Easiest is to compile to native.
You can look at the documentation in the Contiki-NG wiki (Processes and events and timers) or modify some example code.
If you get totally stuck, email Thiemo
UDP Communication
It might also be very helpful to read the UDP communication
Homework assignment
As homework assignment, you will investigate end-to-end retransmissions in a lossy 6LoWPAN+RPL network.
Your starting point is under contiki-ng/smarter-home-assignment
, in particular the Cooja simulation file simulation.csc
:
The setup is a RPL network, and a UDP client (node 6) sending data to a UDP server (node 1) five hops away. The network environment is set up such as only 10% of the packets are received! This is an extremely adverse scenario, to better challenge the various reliability mechanisms in Contiki-NG. RPL will manage to build a network in spite of the losses, but UDP traffic, on the other end, suffers losses. This can be observed from the logs: some of the requests sent are never received.
The assignment is twofold:
- Implement an end-to-end reliability mechanism on top of UDP. You will need to use ACKs or NACKs sent by the server to let the client know when retransmissions are needed. You can try different policies.
- Measure the performance of the baseline versus your reliable extension. Metrics of interest here are end-to-end packet delivery ratio (PDR) and end-to-end latency.
NB: you may not change the MAC layer nor MAC-layer configuration. In particular, leave the number of MAC-layer retranmissions to 3. The focus here is on end-to-end reliability.