【问题标题】:Receive and Send in Tinyos在 Tinyos 中接收和发送
【发布时间】:2018-05-24 03:21:00
【问题描述】:

我有两个 telosb 之间的程序通信通信。这是 tinyos 的一个示例:https://github.com/tinyos/tinyos-release/tree/tinyos-2_1_2/apps/RadioCountToLeds。此代码将发送和接收一个值计数,如果条件满足,它将打开相应的 LED。我想将代码分成两部分:发送和接收。我创建了 2 个应用程序: 接收:

//RadioCountToLedC.nc
#include "Timer.h"
#include "RadioCountToLeds.h"

module RadioCountToLedsC @safe() {
  uses {
    interface Leds;
    interface Boot;
    interface Receive;
    interface Packet;
  }
}
implementation {

  message_t packet;
  uint16_t counter = 0;
  event void Boot.booted()
  {

  }
  event message_t* Receive.receive(message_t* bufPtr, 
                   void* payload, uint8_t len) {
    call Leds.led0On();
    dbg("RadioCountToLedsC", "Received packet of length %hhu.\n", len);
    if (len != sizeof(radio_count_msg_t)) {return bufPtr;}
    else {
      radio_count_msg_t* rcm = (radio_count_msg_t*)payload;
      if (rcm->counter%3 == 0) {
    call Leds.led0On();
      }
      else {
    call Leds.led0Off();
      }
      if (rcm->counter%3 == 1) {
    call Leds.led1On();
      }
      else {
    call Leds.led1Off();
      }
      if (rcm->counter%3 == 2) {
    call Leds.led2On();
      }
      else {
    call Leds.led2Off();
      }
      return bufPtr;
    }
  }

}


   //RadioToLedAppC.nc
    #include "RadioCountToLeds.h"

configuration RadioCountToLedsAppC {}
  implementation {
    components MainC, RadioCountToLedsC as App, LedsC;
    components new AMReceiverC(AM_RADIO_COUNT_MSG);
    components new TimerMilliC();
    components ActiveMessageC;

  }

发送:

//RadioCountToLedC.nc


#include "Timer.h"
#include "RadioCountToLeds.h"

module RadioCountToLedsC @safe() {
  uses {
    interface Leds;
    interface Boot;
    interface AMSend;
    interface Timer<TMilli> as MilliTimer;
    interface SplitControl as AMControl;
    interface Packet;
  }
}
implementation {

  message_t packet;

  bool locked;
  uint16_t counter = 0;

  event void Boot.booted() {
    call MilliTimer.startPeriodic(250);
    call AMControl.start();
  }

  event void AMControl.startDone(error_t err) {
    if (err == SUCCESS) {
      call MilliTimer.startPeriodic(250);
    }
    else {
      call AMControl.start();
    }
  }

  event void AMControl.stopDone(error_t err) {
    // do nothing
  }

  event void MilliTimer.fired() {
    if(counter<100){
       counter++;
    }else{
       counter=0;
    }
    dbg("RadioCountToLedsC", "RadioCountToLedsC: timer fired, counter is %hu.\n", counter);
    if (locked) {
      return;
    }
    else {
      radio_count_msg_t* rcm = (radio_count_msg_t*)call Packet.getPayload(&packet, sizeof(radio_count_msg_t));
      if (rcm == NULL) {
    return;
      }

      rcm->counter = counter;
      if (call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(radio_count_msg_t)) == SUCCESS) {
    dbg("RadioCountToLedsC", "RadioCountToLedsC: packet sent.\n", counter); 
    locked = TRUE;
      }
    }
  }

  event void AMSend.sendDone(message_t* bufPtr, error_t error) {
    if (&packet == bufPtr) {
      locked = FALSE;
    }
  }

}
//RadioToLedAppC.nc

    #include "RadioCountToLeds.h"

    configuration RadioCountToLedsAppC {}
    implementation {
      components MainC, RadioCountToLedsC as App, LedsC;
      components new AMSenderC(AM_RADIO_COUNT_MSG);
      components new AMReceiverC(AM_RADIO_COUNT_MSG);
      components new TimerMilliC();
      components ActiveMessageC;

      App.Boot -> MainC.Boot;

      App.AMSend -> AMSenderC;
      App.AMControl -> ActiveMessageC;
      App.Leds -> LedsC;
      App.MilliTimer -> TimerMilliC;
      App.Packet -> AMSenderC;
    }

RadioCountToLed.h

#ifndef RADIO_COUNT_TO_LEDS_H
#define RADIO_COUNT_TO_LEDS_H

typedef nx_struct radio_count_msg {
  nx_uint16_t counter;
} radio_count_msg_t;

enum {
  AM_RADIO_COUNT_MSG = 6,
};

#endif

但是当我运行它时它不起作用。如果我像上面的例子一样在同一个文件 RadioCountToLedC.nc 中编写接收和发送。它会运作良好。我的申请有什么问题?

【问题讨论】:

    标签: tinyos


    【解决方案1】:

    我认为你需要

    call AMControl.start();
    

    在接收器的启动功能中。这将打开收音机并让您接收消息。

    PS 如果这不能完全解决您的问题,请提供更多关于您在运行时观察到的情况的详细信息。

    【讨论】:

      【解决方案2】:

      有很多简单的方法可以解决这个问题,最简单的方法是只使用一个控制程序流程的变量,或者使用每个节点 TinyOS ID 来控制流程。

      例如,您可以(仅进行了 4 处小改动):

      #include "Timer.h"
      #include "RadioCountToLeds.h"
      
      /**
       * Implementation of the RadioCountToLeds application. RadioCountToLeds 
       * maintains a 4Hz counter, broadcasting its value in an AM packet 
       * every time it gets updated. A RadioCountToLeds node that hears a counter 
       * displays the bottom three bits on its LEDs. This application is a useful 
       * test to show that basic AM communication and timers work.
       *
       * @author Philip Levis
       * @date   June 6 2005
       */
      
      module RadioCountToLedsC @safe() {
        uses {
          interface Leds;
          interface Boot;
          interface Receive;
          interface AMSend;
          interface Timer<TMilli> as MilliTimer;
          interface SplitControl as AMControl;
          interface Packet;
        }
      }
      implementation {
      
        message_t packet;
      
        bool locked;
        uint16_t counter = 0;
      
        enum state {TX, RX} mode; //Change 1: Define States
      
        event void Boot.booted() {
          call AMControl.start();
          mode = RX; // CHANGE 2: Set States - "RX" for receiver & "TX" for transmitter
        }
      
        event void AMControl.startDone(error_t err) {
          if (err == SUCCESS) {
            if(mode == TX) //CHANGE 3: Only the transmitter sends
                call MilliTimer.startPeriodic(250);
          }
          else {
            call AMControl.start();
          }
        }
      
        event void AMControl.stopDone(error_t err) {
          // do nothing
        }
      
        event void MilliTimer.fired() {
          counter++;
          dbg("RadioCountToLedsC", "RadioCountToLedsC: timer fired, counter is %hu.\n", counter);
          if (locked) {
            return;
          }
          else {
            radio_count_msg_t* rcm = (radio_count_msg_t*)call Packet.getPayload(&packet, sizeof(radio_count_msg_t));
            if (rcm == NULL) {
          return;
            }
      
            rcm->counter = counter;
            if (call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(radio_count_msg_t)) == SUCCESS) {
          dbg("RadioCountToLedsC", "RadioCountToLedsC: packet sent.\n", counter); 
          locked = TRUE;
            }
          }
        }
      
        event message_t* Receive.receive(message_t* bufPtr, 
                         void* payload, uint8_t len) {
          dbg("RadioCountToLedsC", "Received packet of length %hhu.\n", len);
      
          if(mode == TX) return bufPtr; //CHANGE 4: Only RX processes packets
      
          if (len != sizeof(radio_count_msg_t)) {return bufPtr;}
          else {
            radio_count_msg_t* rcm = (radio_count_msg_t*)payload;
            if (rcm->counter & 0x1) {
          call Leds.led0On();
            }
            else {
          call Leds.led0Off();
            }
            if (rcm->counter & 0x2) {
          call Leds.led1On();
            }
            else {
          call Leds.led1Off();
            }
            if (rcm->counter & 0x4) {
          call Leds.led2On();
            }
            else {
          call Leds.led2Off();
            }
            return bufPtr;
          }
        }
      
        event void AMSend.sendDone(message_t* bufPtr, error_t error) {
          if (&packet == bufPtr) {
            locked = FALSE;
          }
        }
      
      }
      

      除了在 Booted 事件中设置模式,您还可以根据需要使用 C 预处理器设置 mode 变量。

      您制作的接收器应用程序的问题在于它

      i) 不启动收发器,因为它没有在 Boot.Booted() 事件中调用 AMControl.start()

      ii) RadioCountToLedsAppC 中的接线不正确,因为没有连接任何接口。您需要连接所有接口(Boot、Leds、Receive 和 AMControl)。类似于您在发件人中连接它们的方式。

      【讨论】:

        猜你喜欢
        • 2020-04-14
        • 2015-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多