Tossim仿真BlinkToRadio 节点相互通信

一、功能:

  使用Tossim仿真两个节点相互通信的过程,也就是发送和接收数据的过程。两个节点通信,必须存在拓扑结构,信道也有噪声

二、功能逻辑实现:

  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 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); 
          dbg("Boot", "Application booted\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;
      dbg("BlinkToRadioC", "%hhu mote send packet,time== %s.\n",TOS_NODE_ID,sim_time_string());
      }
  }
  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);
      dbg("BlinkToRadioC", "%hhu mote Receive packet,from node %hhu, counter= %hhu,time== %s.\n",
                                TOS_NODE_ID,btrpkt->nodeid,btrpkt->counter, sim_time_string());
      }
      return msg;
  }
}

  其实没什么,节点每个250ms发送一次数据,其余时间均处于接收状态,发送完和接收数据后都dbg一句话

三、仿真步骤

  1、进入Blink 所在目录  “cd xxx/BlinkToRadio”

  2、生成仿真框架,为后续的仿真做准备,   就像生成一个界面,等着你输入(命令或脚本)来交互  "make micaz sim"  目前仿真只支持micaz平台, 后面的"sim"代表生成仿真框架

  3、编辑test.py

    

#!/usr/bin/env python
#-*-coding:utf-8-*-            #解决编码问题

from TOSSIM import *
import sys

t=Tossim([])
r=t.radio()            #用于创建拓扑结构,通过r.add()创建链路
f=open("topo.txt","r")        #拓扑结构所在文件,每一行代表一条链路
                #每一行由三个数据组成:源节点,目标节点和增益(应该就是发射功率吧)

lines=f.readlines()        #下面这段只是打印拓扑结构,要不要无所谓
for line in lines:
    s = line.split()
    if (len(s)>0):
        print "",s[0],"",s[1],"",s[2];            
        r.add(int(s[0]),int(s[1]),float(s[2]))

f=open("log.txt",'w');
t.addChannel("Boot",f)
t.addChannel("BlinkToRadioC",f)            #将BlinkToRadioC输出通道绑定到log.txt
t.addChannel("BlinkToRadioC",sys.stdout)    #将BlinkToRadioC输出绑定到标准输出,也就是屏幕
t.addChannel("Boot",sys.stdout)
 
noise=open("meyer-heavy.txt","r")        #信道噪声文件
lines=noise.readlines()
for line in lines :                #这个for和下面的for共同完成读取噪声文件并构造信道噪声模型,你可以深究,我看不懂
    str= line.strip()
    if(str!=""):
        val=int(str)
        for i in range(1,3):
            t.getNode(i).addNoiseTraceReading(val)
 
for i in range(1,3):                    
    print"Creating noise model for",i;
    t.getNode(i).createNoiseModel()
    
    
t.getNode(1).bootAtTime(100001);        #设置节点boot时间
t.getNode(2).bootAtTime(800008);



for i in range(0,100):                #让每个节点仿真100个事件
     t.runNextEvent()

  其中,topotxt内容如下 

1 2 -54.0  
2 1 -55.0  
meyer-heavy.txt可以在tos/lib/tossim/noise目录下找到
  4、运行test.py文件,进行仿真,结果如下
    

5、小结:
  有点搞不懂,为什么第一条语句不是发送packet语句,而是接收呢?谁能给我答案

6、补充:
   将逻辑功能代码改成如下,就比较好理解了:
     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 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); 
          dbg("Boot", "Application booted\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;
      //dbg("BlinkToRadioC", "%hhu mote send packet,time== %s.\n",TOS_NODE_ID,sim_time_string());
      }
  }
  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发送出去
        dbg("BlinkToRadioC", "%hhu mote send packet,time== %s.\n",TOS_NODE_ID,sim_time_string());
        //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);
      dbg("BlinkToRadioC", "%hhu mote Receive packet,from node %hhu, counter= %hhu,time== %s.\n",
                                TOS_NODE_ID,btrpkt->nodeid,btrpkt->counter, sim_time_string());
      }
      return msg;
  }
}

 

 

  可以看到,其实就是将send  packet时的dbg放到发送sendDone里面,而不是像第一次一样放到send函数里面,我想可能就是这边一点一点发,那边一点一点收,并不用等发完已经收完了,哎呀呀,纯属我瞎扯的,

  大家可以自己想想,欢迎指点

  

posted @ 2017-11-01 15:24  XiaoBBai  阅读(1414)  评论(0编辑  收藏  举报