BlinkToRadio 两个节点通信

一、实现功能:

  节点每隔250ms给自己的临节点发送一个packet(只包含一个id号和一个计数值),节点收到信息后,将计数值的低三位显示在LED上。

二、主要实现文件

  1、顶层配置文件:定义应用程序所有的组件,及组件和接口之间的绑定关系。

    BlinkToRadioAppC.nc

        

#include<Timer.h>
#include"BlinkToRadio.h"

configuration BlinkToRadioAppC{
}

implementation{
 
  components MainC;                //系统组件
  components LedsC;
  components BlinkToRadioC as App;        //用户自定义组件
  components new TimerMilliC() as Timer0;
 
  components ActiveMessageC;
  components new AMSenderC(AM_BLINKTORADIO);    //每个radio相当于一个电脑,AM_BLINKTORADIO相当于指定一个端口号,指定发送到radio的那个“应用程序”    
  
  components new AMReceiverC(AM_BLINKTORADIO);

  components SerialPrintfC;

  App.Boot->MainC;                //接口组件绑定
  App.Leds->LedsC;
  App.Timer0->Timer0;
  
  App.Packet->AMSenderC;
  //App.AMPacket->AMSenderC;
  App.AMSend->AMSenderC;
  App.AMControl->ActiveMessageC;

  App.Receive->AMReceiverC;
  
}

  2、核心处理模块:一般而言,就是将各个普通模块组合在一起,但是该程序比较简单,只有一个模块,所以就没有打工仔,都是大boss.

     普通模块:功能逻辑实现

     BlinkToRadioC.nc

      

#include<Timer.h>
#include <stdio.h>
#include<string.h>
#include "BlinkToRadio.h"


module BlinkToRadioC{
  uses interface Boot;
  uses interface Leds;
  uses interface Timer<TMilli> as Timer0;

  uses interface Packet;
  //uses interface AMPacket;
  uses interface AMSend;
  uses interface SplitControl as AMControl;

  uses interface Receive;
}

implementation{
  uint16_t counter = 0;

  bool busy = FALSE;
  message_t pkt;        //要发送的消息

  event void Boot.booted(){     //硬件上电后调用

      call AMControl.start();    //尽管可以把这些接口直接绑定到ActiveMessageC组件,但通常还是选择绑定AMSenderC组件。
                                //不过,必须使用ActiveMessageC组件的SplitControl接口来初始化无线模块
                                //开启这个组件和它的子组件 
  }
  
  event void AMControl.startDone(error_t err){        //AMControl.start()执行完成后signal的event,也就是要执行的代码
      if(err==SUCCESS){
          call Timer0.startPeriodic(TIMER_PERIOD_MILLI); 
          //printf("Timer0 start\r\n");                       
      }else{
          call AMControl.start();
      }
  }
 
  //貌似是用到SplitControl 这个接口必须定义该函数
  event void AMControl.stopDone(error_t err){
  }


  event void AMSend.sendDone(message_t *msg,error_t error){    //AMSend.send()执行完后signal
      if(&pkt==msg){    //msg是packet中消息,这里与本地消息比较一下,看是否是自己发的消息
          busy=FALSE;
      }
  }
  event void Timer0.fired(){    //Timer0到期后signal
      counter++;  
      if(!busy){
          BlinkToRadioMsg* btrpkt=(BlinkToRadioMsg*)(call Packet.getPayload(&pkt,NULL));   //获取一个Packet地址,
                                               //搞不懂为什么要这么多参数
      btrpkt->nodeid=TOS_NODE_ID;        //填充数据    
      btrpkt->counter=counter;
      if(call AMSend.send(AM_BROADCAST_ADDR,&pkt,sizeof(BlinkToRadioMsg))==SUCCESS){   //将packet发送出去
        //printf("send data\r\n"); 
          busy=TRUE;
      }
      }
  }
  
  event message_t* Receive.receive(message_t *msg,void * payload,uint8_t len){        //接收到数据signal
      if(len==sizeof(BlinkToRadioMsg)){
          BlinkToRadioMsg * btrpkt=(BlinkToRadioMsg *)payload;        //数据保存在payload中
            call Leds.set(btrpkt->counter);
      }
      return msg;
  }
}

   3、相关数据结构:  packet 中的payload 只要不是基本数据类型,最好用结构体来构造

      BlinkToRadio.h

          

#ifndef BLINKTORADIO_H
#define BLINKTORADIO_H

//常量最好用枚举,而不是define
enum{        
  AM_BLINKTORADIO=6,
  TIMER_PERIOD_MILLI=250
};

//发送的payload 数据结构
typedef nx_struct BlinkToRadioMsg{
  nx_uint16_t nodeid;
  nx_uint16_t counter;
}BlinkToRadioMsg;


#endif

  4、应该熟练掌握的组件及其接口:

    a、TimerMilliC组件(用法:components new TimerMilliC() as Timer0;)

      接口:

        i、Timer接口(用法:uses interface Timer<TMilli> as Timer0;):这里用来提供ms计数器

    b、ActiveMessageC组件:(用法:components ActiveMessageC;)

      接口:

        i、SplitControl接口:(用法:uses interface SplitControl as AMControl;):这里用来启动无线模块

          注意:貌似是用到SplitControl 这个接口必须定义该函数event void AMControl.stopDone(error_t err){}

  c、AMSenderC组件(用法:components new AMSenderC(AM_BLINKTORADIO); //每个radio相当于一个电脑,AM_BLINKTORADIO相当于指定一个端口号,指定发送到radio的那个“应用程序”)

    接口:

      i、Packet接口(用法:uses interface Packet;):这里主要用于发送packet之前,提供packet的地址,方便往里面填充数据,以便后续的发送

      ii、AMSend接口(用法:uses interface AMSend;)这里主要用来发送packet

  d、AMReceiverC组件(用法:components new AMReceiverC(AM_BLINKTORADIO);)

    接口:

      i、Receive接口(用法:uses interface Receive;)这里主要用于接收packet,并从packet中提取payload

 

 

    

 

        

posted @ 2017-10-29 10:22  XiaoBBai  阅读(1109)  评论(0编辑  收藏  举报