This program periodically sends a sensor reading over the radio. A component of the same type on another node displays the lower three bits of the sensor reading on its LEDs.
/**
* Implementation of the RadioSenseToLeds application. RadioSenseToLeds periodically takes
* a sensor reading and broadcasts the sensor reading on the radio.
* A RadioSenseToLeds node that hears a broadcast displays the bottom three bits
* of the value it has received on its LEDs. This application is a useful to show that
* basic communication, timers, and sensors work.
*
*/
// Interface for Temperature Broadcaster
type ITempBroadcast is interface (
out bool tempRequest ;
in integer tempValue ;
out any broadcastSend ;
in integer button ;
in bool timerRecv ;
)
// Temperature Broadcaster component
component TempBroadcast presents ITempBroadcast {
//count = 0
test = true
constructor() {
}
behaviour {
//wait for a button press to start sending
if(test) then {
receive tick1 from button
test := false
}
//0.24 to meet the 250 units specified in tinyos
setTimer(timerRecv , 0.24 , false)
receive tick from timerRecv
// get temp sensor reading
send true on tempRequest
receive reading from tempValue
//count := count + 1
//if(count % 10 == 0) then {
send any(reading) on broadcastSend
//}
}
}
/***************************************************************************/
//Interface for Temperature Receiver
type ITempReceiver is interface ( in RadioPacket broadcastRecv )
//Temperature Reveicer Component
component TempRecv presents ITempReceiver {
constructor() {
}
behaviour {
// wait for packet from Radio
receive packet from broadcastRecv
project packet.payload as reading onto
integer : {
if (reading & 4) == 4 then {
setRedLedPower(true)
} else {
setRedLedPower(false)
}
if (reading & 2) == 2 then {
setBlueLedPower(true)
} else {
setBlueLedPower(false)
}
if (reading & 1) == 1 then {
setGreenLedPower(true)
} else {
setGreenLedPower(false)
}
}
default : { printString( "???" ) }
}
}
/***************************************************************************/
//Create the components
tbc = new TempBroadcast()
trc = new TempRecv()
//Connect the channels
connect tbc.button to buttonSensor.output
connect tbc.tempRequest to sensors.batteryRequest
connect tbc.tempValue to sensors.batteryOut
connect tbc.broadcastSend to radio.broadcastSend
connect trc.broadcastRecv to radio.received
The corresponding nesC program for TinyOS is shown below.
#ifndef RADIO_SENSE_TO_LEDS_H
#define RADIO_SENSE_TO_LEDS_H
typedef nx_struct radio_sense_msg {
nx_uint16_t error;
nx_uint16_t data;
} radio_sense_msg_t;
enum {
AM_RADIO_SENSE_MSG = 7,
};
#endif
/**************************************/
#include "RadioSenseToLeds.h"
configuration RadioSenseToLedsAppC {}
implementation {
components MainC, RadioSenseToLedsC as App, LedsC, new DemoSensorC();
components ActiveMessageC;
components new AMSenderC(AM_RADIO_SENSE_MSG);
components new AMReceiverC(AM_RADIO_SENSE_MSG);
components new TimerMilliC();
App.Boot -> MainC.Boot;
App.Receive -> AMReceiverC;
App.AMSend -> AMSenderC;
App.RadioControl -> ActiveMessageC;
App.Leds -> LedsC;
App.MilliTimer -> TimerMilliC;
App.Packet -> AMSenderC;
App.Read -> DemoSensorC;
}
/**************************************/
#include "Timer.h"
#include "RadioSenseToLeds.h"
module RadioSenseToLedsC @safe(){
uses {
interface Leds;
interface Boot;
interface Receive;
interface AMSend;
interface Timer as MilliTimer;
interface Packet;
interface Read;
interface SplitControl as RadioControl;
}
}
implementation {
message_t packet;
bool locked = FALSE;
event void Boot.booted() {
call RadioControl.start();
}
event void RadioControl.startDone(error_t err) {
if (err == SUCCESS) {
call MilliTimer.startPeriodic(250);
}
}
event void RadioControl.stopDone(error_t err) {}
event void MilliTimer.fired() {
call Read.read();
}
event void Read.readDone(error_t result, uint16_t data) {
if (locked) {
return;
}
else {
radio_sense_msg_t* rsm;
rsm = (radio_sense_msg_t*)call Packet.getPayload(&packet, sizeof(radio_sense_msg_t));
if (rsm == NULL) {
return;
}
rsm->error = result;
rsm->data = data;
if (call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(radio_sense_msg_t)) == SUCCESS) {
locked = TRUE;
}
}
}
event message_t* Receive.receive(message_t* bufPtr,
void* payload, uint8_t len) {
call Leds.led1Toggle();
if (len != sizeof(radio_sense_msg_t)) {return bufPtr;}
else {
radio_sense_msg_t* rsm = (radio_sense_msg_t*)payload;
uint16_t val = rsm->data;
if (val & 0x0004)
call Leds.led2On();
else
call Leds.led2Off();
if (val & 0x0002)
call Leds.led1On();
else
call Leds.led1Off();
if (val & 0x0001)
call Leds.led0On();
else
call Leds.led0Off();
return bufPtr;
}
}
event void AMSend.sendDone(message_t* bufPtr, error_t error) {
if (&packet == bufPtr) {
locked = FALSE;
}
}
}