一、概述
就是一个点 对另一个点进行通信。
如:节点0发送数据给节点1。
二、源码分析
2.1 Makefile
COMPONENT=RadioCountToLedsAppC
CFLAGS += -DCC2420_DEF_CHANNEL=14
include $(MAKERULES)
注意:无线通信中很重要的一个参数的设置。
CFLAGS += -DCC2420_DEF_CHANNEL=14
可以区分其他频道,以防其他节点对该频道内的通信进行干扰。
也可以以此来区分不同的网络,免得以此干扰。
2.2 RadioCountToLeds.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
一个数据包的结构体
还有一个枚举类型。
2.3 RadioCountToLedsAppC.c
以下代码是radio的组件连接代码,搬移无线功能复制粘贴即可。
//radio
components ActiveMessageC;
components new AMSenderC(AM_RADIO_COUNT_MSG);
components new AMReceiverC(AM_RADIO_COUNT_MSG);
App.AMControl -> ActiveMessageC;
App.AMSend -> AMSenderC;
App.Packet -> AMSenderC;
App.Receive -> AMReceiverC;
以下是源代码
#include "RadioCountToLeds.h"
configuration RadioCountToLedsAppC {}
implementation {
//main leds
components MainC, RadioCountToLedsC as App,LedsC;
App.Boot -> MainC.Boot;
App.Leds -> LedsC;
//radio
components ActiveMessageC;
components new AMSenderC(AM_RADIO_COUNT_MSG);
components new AMReceiverC(AM_RADIO_COUNT_MSG);
App.AMControl -> ActiveMessageC;
App.AMSend -> AMSenderC;
App.Packet -> AMSenderC;
App.Receive -> AMReceiverC;
//timer
components new TimerMilliC();
App.MilliTimer -> TimerMilliC;
//serial
components SerialActiveMessageC as AM;
App.SerialControl -> AM;
App.SerialReceive -> AM.Receive[1];//1号通道
App.SerialAMSend -> AM.AMSend[1];//1号通道
App.SerialPacket -> AM;
components new TimerMilliC() as SerialTime;
App.SerialTimer -> SerialTime;
}
2.3 RadioCountToLedsC.c
主要步骤:
- 开机上电之后,开启AMcontrol、SerialControl
event void Boot.booted() {
call AMControl.start();
call SerialControl.start();//开启串口,对应事件为StartDone
}
- AMcontrol开启成功够,开启周期性定时器。
call MilliTimer.startPeriodic(1000);
- 定时器时间到,发送无线包
3.1 定义一个无线包全局变量message_t packet;
3.2 通过调用API,获取有效负载的指针,这个指针强制转换为radio_count_msg_t结构体类型,用来存储我们发送的数据。
radio_count_msg_t* rcm = (radio_count_msg_t*)call Packet.getPayload(&packet, sizeof(radio_count_msg_t));
3.3 若获取的指针有效,则赋值。
rcm->counter = counter;
3.4 无线发送数据包并且判断是否发送成功
if (call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(radio_count_msg_t)) == SUCCESS){}
- 接收无线数据包事件。
数据长度正确,则将payload强制转为数据包结构体格式的指针,然后通过->
运算符获取数据。
event message_t* Receive.receive(message_t* bufPtr, void* payload, uint8_t len)
{
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();
}
}
}
#include "Timer.h"
#include "RadioCountToLeds.h"
module RadioCountToLedsC @safe() {
uses {
interface Leds;
interface Boot;
interface Receive;
interface AMSend;
interface Timer<TMilli> as MilliTimer;
interface SplitControl as AMControl;
interface Packet;
//serial
interface SplitControl as SerialControl;
interface Receive as SerialReceive;
interface AMSend as SerialAMSend;
interface Timer<TMilli> as SerialTimer;
interface Packet as SerialPacket;
}
}
implementation {
message_t packet;
bool locked;
uint16_t counter = 0;
event void Boot.booted() {
call AMControl.start();
call SerialControl.start();//开启串口,对应事件为StartDone
}
//serial
event void SerialControl.startDone(error_t err) {
if (err == SUCCESS) {
call SerialTimer.startPeriodic(1000);
}
}
event void SerialControl.stopDone(error_t err) {}
event message_t* SerialReceive.receive(message_t* bufPtr, void* payload, uint8_t len) {return bufPtr;/*返回获取的数据包*/}
event void SerialTimer.fired() {
message_t serialPacket;
uint8_t * payload = (uint8_t*)call SerialPacket.getPayload(&serialPacket, sizeof(uint8_t ));
if (payload == NULL) {return;}
*payload = 88;
while (call AMSend.send(AM_BROADCAST_ADDR, &serialPacket, sizeof(uint8_t )) == SUCCESS);
}
event void SerialAMSend.sendDone(message_t* bufPtr, error_t error) {}
void printf(const char* format,...)
{
}
event void AMControl.startDone(error_t err) {
if (err == SUCCESS) {
call MilliTimer.startPeriodic(1000);
}
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 (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;
}
}
}