App Notes

Download zip archive

Key Ideas

  • Use the radio to run a ping-pong protocol between two eMote .NOWs.

Description

eMote .NOWs come with radio networking capabilities built in. This app note shows you how to use the radio to communicate between two motes. In this app note, the motes converge to a common number that is incremented alternately by each mote after it receives a message from the other. In case one mote goes down or goes out of range, they will reconverge when both are available again.

Compatibility

eMote.NOW 1.0, eMote version 4.3.68 and Visual Studio 2012 or 2013.

Complexity Level

Fairly introductory. There is some complexity with respect to radio setup.

Setup

You'll need two eMote .NOWs for this app note. Otherwise, the setup is the same as for the Hello World app note.

Getting Started

Connect both of your eMote .NOWs to your PC. Open this app note in Visual Studio and make sure it builds correctly. When all is well, deploy to the first mote, then change the deployment device to the second mote and deploy to it.

Running the Programs

Open two instances of MFDeploy; see the FAQ for tips on monitoring and debugging when you have more than one mote. Press the Reset button on both. You should see messages appearing in MFDeploy that track progress. On the LCD display of each mote you'll see the number that they have converged to.

Discussion

The basic idea behind this app note is pretty simple. Both motes are running the same program. When one starts, it chooses a number at random as its current value and sends it to the other via the radio. When a mote gets a message from the other, it uses the maximum of the current & received value, adds 1, and sends the new value back. This way, both converge on the same value and take turns incrementing it. Now we get into some of the details.

First, the radio. There are a variety of ways to use a radio to communicate between motes; these are called "protocols". The most common protocol is CSMA, which stands for Carrier Sense Multiple Access. The protocol tries to avoid situations where two motes are trying to transmit at the same time. When this collision happens, nothing gets through. It's rather like two people trying to talk at the same time: you'll have a hard time understanding either one. So CSMA listens before sending and only sends when the channel is clear. Of course, collisions can still happen, as is the case when two people, trying to be polite, nevertheless start talking at the same moment. In that case, the devices will back off randomly and try again later. See http://www.youtube.com/watch?v=oCYWpDTD8Dc for a short video about this or http://en.wikipedia.org/wiki/Carrier_sense_multiple_access_with_collision_avoidance for a longer description.

Another protocol is OMAC. With OMAC, a mote's neighbors each get assigned a time slot in which the mote is ready to listen to them. What's the advantage of OMAC over CSMA? A problem with CSMA is that it is "sender centric": a mote can transmit at any time and expect to be heard by the receiver. So motes have to be listening all the time since they don't know when a neighbor will be sending. This consumes a lot of energy, relatively speaking, and materially shortens battery life. OMAC by contrast is "listener-centric" so motes have the radio on to listen only at agreed-upon times. For more informaton, see https://pdfs.semanticscholar.org/9100/d319127023206a851ebc0c6b7180012b5667.pdf.

Before loading the program on a mote, you'll need to set the radio type, protocol, channel, and power. In the file "RadioConfiguration.cs", you'll see some #define statements at the top. Choose RF231, the .NOW radio type, by making sure it's #define statement is not commented out. Likewise, choose the protocol, CSMA or OMAC. Depending on your choices, you'll see different code enabled in the RadioConfiguration class. To set power, go to the RadioProperties class and set the variable Power to the power level you'd like; the larger the number, the higher the power. Likewise set the RadioChannel variable. This can be anything you choose; in some cases you can avoid interference with other radio transmitters (like a WiFi router) by changing the channel.

The two motes in this system have to be using the same radio, protocol and channel. They can have different power levels.

The program works by sending messages to all neighbors. Each message sent by this program has a header, the string "PingPong", as the first part of the payload, so if that's not present, we ignore it. Finally, it checks that the rest of the packet is an integer. If so, that's the value that was sent by the other node. In that case, the following happens:

  1. We compare the received value with our current value and choose the greater. That's how we converge to the same value.
  2. We increment the value by one and display it. This lets us confirm that the program is actually running.
  3. We start a timer. Upon the completion of the timer, our current value is sent out. This delay keeps the update process slow enough that we can watch it happen on the display.

Note the use of a timer to delay sending the message. It would be tempting to use a Thread.Sleep in the RadioReceive method. However, this method is called as part of an message-received interrupt call-back, which should complete as quickly as possible. So rather than delay it by sleeping in the method, a timer, which runs in a separate thread, assumes responsibility for the transmission and the RadioReceive method can exit without further delay.

Note that in what we've described so far, a mote will send it's value out once and then wait for the other to receive it and respond. What happens if the other mote is not available? In that case, when the mote has decided that the other one is not responding, it will send out another message, and continue to do so periodically until it hears back. Thus you can start one mote and after a while, start the other one, and they will get in step with each other. So a second timer, with a longer interval, is used in case the other mote is unresponsive. When it fires, the current value is resent and the timer is restarted. That timer gets reset whenever the mote hears from the other, so in the normal case when the motes are communicating, it will never fire. But if either mote becomes unresponsive, it will transmit periodically until it again hears from the other mote.

Suggestions

Connect one of the motes to a battery. Try moving it away until the motes are out of radio range from each other. See them stop updating. Move them back into radio range and see them begin again.

Try incorporating a switch (see the On-Off Switch app note). When the switch is pressed, choose a new random number. Watch the motes re-converge to the correct value.

Designate one of the motes as a base station and send the current value to a PC. See the On-Off Switch with Serial Link app note for an example of how to communicate with the PC.

What do you think would happen if you were to use three motes? If you have three, try it and see.