The Synchronous Blog

A blog about reactive programming languages.

Céu + Wireless Sensor Networks

with one comment

Wireless Sensor Networks (WSNs) are composed of tiny devices (known as “motes”) that sense the environment and communicate via radio. The image on the right shows two “micaz” motes.

The restricted resources of motes and the unlimited possibilities for WSNs applications made this platform an interesting target for Céu [1]. We integrated Céu with TinyOS [2] in order to use the abstracted radio services the operating system already provides.

The following demo uses a fixed ring topology with three motes placed side by side within their radio ranges.
The motes should follow the same behavior: receive a message with an integer counter, show it on the leds, wait for 1 second, increment the counter, and forward it to the mote on its right.

As the topology constitutes a ring, the counter will be incremented forever while traversing the three motes. If a mote does not receive a message within 5 seconds, it should blink the red led every 500 milliseconds until a new message is received.
The mote with id=0 is responsible for initiating the process at boot time, and also when the network is down, after 10 seconds of inactivity.

Follows the video for the application executing:

 

The code

Let’s start with the code that receives the message and forwards it to the next mote:

 1:  loop do
 2:      _message_t* msg = await Radio_receive;
 3:      int* cnt = _Radio_getPayload(msg);
 4:      _Leds_set(*cnt);
 5:      await 1s;
 6:      *cnt = *cnt + 1;
 7:      _Radio_setDestination(msg, (_TOS_NODE_ID+1)%3);
 8:      emit Radio_send(msg);
 9:  end

 

The code is an endless loop that first awaits a radio message (line 2), gets a pointer to its data region (line 3), shows the received counter on the leds (line 4), and then awaits 1s (line 5) before incrementing the counter in the message (line 6) and forwarding it to the next mote (lines 7-8).
Because this code does not handle failures, it is straight to the point and easy to follow.
Actually, this is the final code for this task, as the handler for errors is placed in a parallel trail.

To handle failures, we use a monitoring trail in parallel with the communicating trail, as shown in the following code:

 0:  par do
1-9:    // COMMUNICATING TRAIL (previous code)
10:  with
11:     loop do
12:        par/or do
13:           await 5s;
14:           par do
15:              loop do
16:                 emit retry;
17:                 await 10s;
18:              end
19:           with
20:              _Leds_set(0);
21:              loop do
22:                 _Leds_led0Toggle();
23:                await 500ms;
24:              end
25:           end
26:        with
27:           await Radio_receive;
28:        end
29:     end
30:  end

 

The network-down behavior constitutes the lines 13 to 25. After 5 seconds of inactivity is detected (line 13), two new activities run parallel: one that retries the communication every 10 seconds by signaling the internal event retry (lines 15-18); and another that blinks the red led every 500 milliseconds (lines 20-24).

The trick to restore the normal behavior of the network is to await the Radio_receive event (line 27) in a par/or (line 12) with the network-down behavior to kill it whenever the network link is restored. By surrounding everything with a loop (line 11), we ensure that the error detection is continuous.

Finally, we need to code the initiating/retrying process that sends the first message from the mote with id=0. As expected we place the code in parallel with the other activities, as the follows:

 0:  par do
1-9:    // COMMUNICATING TRAIL
10:   with
11-29:  // MONITORING TRAIL
30:  with
31:     if _TOS_NODE_ID == 0 then
32:        loop do
33:           _message_t msg;
34:           int* cnt = _Radio_getPayload(&msg);
35:           *cnt = 1;
36:           _Radio_setDestination(&msg, 1);
37:           _Radio_setPayloadLength(&msg, sizeof);
38:           emit Radio_send(&msg);
39:           await retry;
40:        end
41:     else
42:        await Forever;
43:     end
44:  end

 

We start by checking if the mote has id=0 (line 31). If this is not the case, we simply await forever on this trail (line 42).
Otherwise, the loop (lines 32-40) sends the first message as soon as the mote is turned on (line 36-38).
It then waits for a retry emit (line 39) to loop and resend the initial message.

Conclusion

This demo shows how complementary activities in an application can be written in separate and need not to be mixed in the code.
The activities are then combined together through parallel compositions and communication via internal events to achieve the intended behavior.
The complete source code is less than 70 lines and includes all definitions and code to initialize the radio.
The generated code consumes 13.5 Kbytes of ROM and 450 bytes of SRAM.

[1]: http://www.ceu-lang.org/

[2]: http://www.tinyos.net/

Written by francisco

July 4, 2012 at 4:33 pm

Posted in Examples

Tagged with , , , , ,

One Response

Subscribe to comments with RSS.

  1. [...] See on thesynchronousblog.wordpress.com [...]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: