Céu + Wireless Sensor Networks
The restricted resources of motes and the unlimited possibilities for WSNs applications made this platform an interesting target for Céu . We integrated Céu with TinyOS  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:
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.
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.
Subscribe to comments with RSS.