[Tutorial Home] [Lesson 1] [Lesson 2] [Lesson 3] [Lesson 4] [Lesson 5] [Lesson 6]

Lesson 3: Networking

Last modified: Sun Feb 13 16:22:03 PST 2005
This lesson introduces networking in the Bombilla VM. In it, you'll send raw sensor readings up an ad-hoc collection tree, then use local VM communication to send spatially averaged sensor readings.
Introduction

In lesson 2, you learned the basics of TinyScript programming, including some basic language structure. You also learned how to sample sensor readings, send those readings over the UART, and read them on a PC. In this lesson, you will learn how to route data over a multihop network and how to program motes to communicate with one another.

Building a Collection Tree

Note: BombillaLight (for 2KB Teloi) does not support the send function. If you are using Teloi, then you can either skip to the Broadcast handler below, or go through this part of the tutorial with TOSSIM.

Bombilla VMs automatically build and maintain an ad-hoc routing tree, which for micas uses the "MintRoute" algorithm implemented in tinyos-1.x/tos/lib/MintRoute and for Teloi uses the LQI-based algorithm in tinyos-1.x/contrib/ucb/tos/lib/MultiHopLQI. In both, the mote with address zero is the tree collection point, which forwards packets over the UART. To build a routing tree, install Bombilla on a few nodes and plug mote 0 (the base station) into your serial port. It will take a little while (a minute or two) for the nodes to discover one another and build the tree.

A mote can route a buffer to the base station with a function that takes a buffer as a parameter. On mica nodes, the function is send; on Telos RevB nodes it is sendlqi (Telos RevA nodes do not have enough RAM to support collection routing in Maté). Running VMBufferReader as in the previous lesson will allow you to see the data the motes route to the base station, which forwards it to the serial port. Stop Timer0 and Timer1, if they are running, with a Once handler. Then install this code as Timer0, and start it with a rate of 1Hz (setttimer0(10)):

private i;
buffer buf;

bclear(buf);
for i=0 until bfull(buf)
  buf[] = light();
next i

send(buf)   ! if TelosB, use sendlqi(buf)
		    

This program fills a buffer with light readings and sends it. Make sure you sensor boards are attached. You should see output in VMBufferReader like this:

Received multihop buffer of type PHOTO, size 10 from mote 0
  [131][1023][42][939][669][371][716][527][485][443]
Received multihop buffer of type PHOTO, size 10 from mote 1
  [218][892][538][260][807][183][632][499][710][93]
		    

The above readings were generated from TOSSIM with a randomized sensor model: readings from real motes should be much more uniform.

Once a mote passes a buffer to the ad-hoc routing subsystem with send, all of the routing occurs below the VM, in TinyOS code. If you want to make VMs communicate with one another, you need to use the Broadcast handler, which the next section introduces.

Maté Networking: The Broadcast Handler

Bombilla can broadcast a buffer over the radio with the bcast function. If Bombilla hears a broadcast packet, it triggers the Broadcast handler, which can retrieve the buffer with the bcastbuf function.

You can use bcast to build a simple combination of the traditional TinyOS apps SenseToRfm and RfmToLeds. This program periodically samples the local sensor and broadcasts it; if it hears a sensor reading, it displays the top three bits on the leds. Write the following handlers and inject them:

Timer0
Broadcast
Once
buffer buf;

bclear(buf);
buf[]= light();
bcast(buf);
			
private val;
buffer received;

received = bcastbuf();
val = int(received[0]);
leds(val / 128);
			
settimer0(5);
			

You can use the single-hop communication primitive to locally aggregate sensor readings. The following program periodically sends spatially averaged sensor readings up a routing tree:

Timer0
Broadcast
Once
shared avg;
shared avgCount;
buffer buf;

if (avgCount > 0) then
  bclear(buf);  
  buf[0] = avgCount;
  buf[1] = avg;
  send(buf);     ! TelosB, use sendlqi()
end if

avg = int(light());
avgCount = 1;
bclear(buf);
buf[] = avg;
bcast(buf);
			
shared avg;
shared avgCount;
buffer received;

received = bcastbuf();
avg = avg + received[0];
avgCount = avgCount + 1;
			
shared avgCount;

avgCount = 0;
settimer0(20);
			

The Once context has to set avgCount to 0 for the first time when Timer0 runs; otherwise it will have no type and the comparison (avgCount > 0) will throw a type error.

This program has variables that several handlers share. The VM automatically schedules the handlers so these variables do not have race conditions. For example, in the above program a race condition could occur if the Broadcast and Timer0 handler were running concurrently. If Timer0 set avg to be a single reading, but Broadcast then reads both avg and avgCount, then it can read the new value for avg and the old value for avgCount, and produce erroneus values. In this case, the VM won't let the two handlers run concurrently. If a packet arrives while Timer0 is running, the Broadcast handler will wait until Timer0 completes, and if Timer0 fires while Broadcast is running, then Timer0 will wait until Broadcast completes.

Conclusion

This concludes the tutorials on programming Bombilla in TinyScript. Lesson 4 deals with building your own VM, and lesson 5 deals with writing new functions or event handlers to incorporate into VMs.


< Previous Lesson | Next Lesson > | Top