Wednesday, July 4, 2012

Select the Channel for transmission in TinyOS, NesC

Here i have described how to change the channel for Zigbee transmission in TinyOS. Programs i have done are for TelosB mote and so the methods are applicable to the Zigbee CC2420 only. I believe for other motes the methods are more or less the same.

By default in TinyOS the channel used for CC2420 transmission is 26th channel, and it is defined in CC2420.h file. Here i have described about three methods for selecting the channel.

(1) Change the channel by Makefile

  Add this line in Makefile and enjoy.
CFLAGS += -DCC2420_DEF_CHANNEL=25
Where 25 is the required channel.

(2) Change the channel dynamically in NesC programming

  Use the command CC2420Config.setChannel() in interface "CC2420Config", which is provided by the component "CC2420ControlC". Sample program is given below.

Configuration
configuration ChannelAppC {
}

implementation {
  components ChannelC;
  components MainC;
  components LedsC;
  components new TimerMilliC() as Timer;
  components CC2420ControlC;  //Component for Channel selection

  ChannelC.Boot -> MainC;
  ChannelC.Led  -> LedsC.Leds;
  ChannelC.Timer -> Timer;

  components ActiveMessageC;
  components new AMSenderC(6);

  ChannelC.SplitControl -> ActiveMessageC;
  ChannelC.Packet    -> AMSenderC;
  ChannelC.AMPacket  -> AMSenderC;
  ChannelC.AMSend    -> AMSenderC;

  ChannelC.CC2420Config -> CC2420ControlC; //Wiring for Channel selection
}

Module
#include "printf.h"

module ChannelC {
  uses interface Boot;
  uses interface Leds as Led;
  uses interface Timer;

  uses interface SplitControl;
  uses interface Packet;
  uses interface AMPacket;
  uses interface AMSend; 
  uses interface CC2420Config;
}

implementation {

  enum {
    AM_SIZE = 6,
  };

  typedef nx_struct MessageDef {
    nx_uint16_t counter;
  } MessageDef;

  uint16_t counter = 0;
  bool busy = FALSE;
  message_t pkt;
  uint8_t len;
  uint8_t channel;
  
  event void Boot.booted() {
    call SplitControl.start();
  }

  event void SplitControl.startDone(error_t err) {
    call CC2420Config.setChannel(25);
    call CC2420Config.sync();
    call Timer.startPeriodic(500);
  }

  event void Timer.fired() {
    MessageDef* ptrpkt = (MessageDef*)(call Packet.getPayload(&pkt, len));
    counter++;
    call Led.led0Toggle();
    ptrpkt -> counter = counter;
    if (!busy) {
      if (call AMSend.send(AM_BROADCAST_ADDR, &pkt, sizeof(MessageDef)) == SUCCESS) busy = TRUE;
    }
  }

  event void AMSend.sendDone(message_t* msg, error_t error) {
    if (&pkt == msg) {
      busy = FALSE;
      call Led.led1Toggle();
      channel = call CC2420Config.getChannel();
      printf("Channel : %d\n", channel);
      printf("Counter = %d\n\n",counter);
      printfflush();
    }
  }
  
  event void SplitControl.stopDone(error_t err) {
  }
  event void CC2420Config.syncDone( error_t error ) {
  }
}

(3) Change the channel in the TinyOS source

By default CC2420 is using 26th channel for transmission and it is defined in CC2420.h header file in /opt/tinyos-2.x/tos/chips/cc2420/. So by editing that header file and recompiling the program will change the channel. Edit the below given line
#ifndef CC2420_DEF_CHANNEL
#define CC2420_DEF_CHANNEL 25
#endif
 Where 25 is the required channel.

2 comments:

  1. thanks for the information. I have a question for you

    in case of two motes communications and after setting a new channel by the sender, how could the receiver know the new channel and change its own channel to synchronize again ?

    ReplyDelete
  2. Sender can send a message to receiver about information of channel it is going to choose next.

    ReplyDelete