📄 agrimonitorc.nc
字号:
#include "Timer.h"
#include "Datastructure.h"
module AgriMonitorC {
uses {
interface Boot;
interface StdControl as CollectionControl;
interface StdControl as DisseminationControl;
interface SplitControl as RadioControl;
interface DisseminationValue<rootDissemination_t> as SettingsValue;
interface Send as SensorDataSend;
interface Send as TopologyDataSend;
interface Send as StateDataSend;
interface Receive as BcastReceive; //接收广播数据
interface Timer<TMilli> as SensorData_Interval;
interface Timer<TMilli> as TopologyData_Interval;
interface Timer<TMilli> as StateData_Interval;
interface Leds;
interface CtpInfo;
interface Random;
interface Read<uint16_t> as voltageRead;
interface Timer<TMilli> as DisSensor_delay;
interface Timer<TMilli> as DisState_delay;
interface Timer<TMilli> as Retransmit_delay;
interface Timer<TMilli> as BcastSensor_delay;
interface Timer<TMilli> as BcastState_delay;
//interface LowPowerListening;
}
}
implementation {
void startTimer(uint8_t type);
void getSensorData();
void getTopologyData();
void getStateData();
bool needRetransmit();
// bool isExist(am_addr_t addr);
uint8_t routingTableFind(am_addr_t neighbor);
task void sendSensordataMsg();
task void sendTopologydataMsg();
task void sendStatedataMsg();
enum {
SENSORDATA_TIMER = 1,
TOPOLOGYDATA_TIMER = 2,
STATEDATA_TIMER = 4,
SENSORDATA_MESSAGE = 1,
TOPOLOGYDATA_MESSAGE = 2,
STATEDATA_MESSAGE = 4,
//LPL_INTERVAL = 250
};
message_t SensorData_Msg, TopologyData_Msg , StateData_Msg ; //消息缓冲区
rootDissemination_t Dissemination_buf;
BroadCastMsg_t Bcast_buf;
uint8_t Node_Type = 7;
/* 默认情况下节点只包含温度、湿度和光强传感器,每一种传感器对应一位,
依次为空气温度传感器、湿度传感器、光强传感器、二氧化碳传感器、
土壤温度传感器、土壤水分传感器,例如NODE_TYPE = 7则表示只有前三种传感器
*/
/* 由于路由表项较多,一个数据包无法将所有邻居的拓扑信息上传上去,
因此采用循环发送的方式
*/
uint8_t currentIndex = 0;
uint16_t SensorData_Cycle,TopologyData_Cycle,StateData_Cycle;
bool SensorDataVaild = FALSE;//SendBusy = FALSE ;
uint8_t seq_sensorData ; // 传感器数据序列号
event void Boot.booted() {
seq_sensorData = 0;
TopologyData_Cycle = DEFAULT_TOPOLOGY_INTERVAL;
StateData_Cycle = DEFAULT_STATE_INTERVAL;
call RadioControl.start();
// call LowPowerListening.setLocalSleepInterval(LPL_INTERVAL);//lowpower listening interval
}
event void RadioControl.startDone(error_t ok) {
if (ok == SUCCESS){
call DisseminationControl.start();
call CollectionControl.start();
startTimer(TOPOLOGYDATA_TIMER | STATEDATA_TIMER);
}
else {
call RadioControl.start();
//call Leds.led0On();
}
}
event void SensorData_Interval.fired(){
seq_sensorData++;
getSensorData();
post sendSensordataMsg();
}
event void TopologyData_Interval.fired(){
//call Leds.led1Toggle();
getTopologyData();
post sendTopologydataMsg();
}
event void StateData_Interval.fired(){
//call Leds.led2Toggle();
getStateData();
post sendStatedataMsg();
}
/* 获取传感器数据*/
void getSensorData(){
sensorData_t* msg_sensor;
uint8_t index = 0;
uint8_t len = 1 ;
msg_sensor = (sensorData_t* )call SensorDataSend.getPayload(&SensorData_Msg, sizeof(sensorData_t));
if(Node_Type & 1) {
len += 3;
msg_sensor -> data[index].Sen_type = DATA_TEMPERATURE;
msg_sensor -> data[index].Sen_data = 0xaaaa;
index++;
}
if(Node_Type & 2) {
len += 3;
msg_sensor -> data[index].Sen_type = DATA_HUMIDITY;
msg_sensor -> data[index].Sen_data = 0xbbbb;
index++;
}
if(Node_Type & 4) {
len += 3;
msg_sensor -> data[index].Sen_type = DATA_LIGHT;
msg_sensor -> data[index].Sen_data = 0xcccc;
index++;
}
if(Node_Type & 8) {
len += 3;
msg_sensor -> data[index].Sen_type = DATA_CARBON_DIOXIDE;
msg_sensor -> data[index].Sen_data = 0xdddd;
index++;
}
if(Node_Type & 16) {
len += 3;
msg_sensor -> data[index].Sen_type = DATA_SOIL_MOISTURE;
msg_sensor -> data[index].Sen_data = 0xeeee;
index++;
}
if(Node_Type & 32) {
len += 3;
msg_sensor -> data[index].Sen_type = DATA_SOIL_MOISTURE;
msg_sensor -> data[index].Sen_data = 0xffff;
index++;
}
msg_sensor -> length = len;
SensorDataVaild = TRUE;
}
/* 获取拓扑数据*/
void getTopologyData(){
uint8_t i,numNeighbor,index,temp;
topologyData_t* msg_topology;
uint16_t lqi ;
am_addr_t parent , neighbor_id;
msg_topology = (topologyData_t* )call TopologyDataSend.getPayload(&TopologyData_Msg , sizeof(topologyData_t));
call CtpInfo.getParent(&parent); //获取父节点地址
index = routingTableFind(parent);//获取父节点在路由表中的索引
lqi = call CtpInfo.getNeighborLinkQuality(index);//获得当前节点与父节点之间的链路质量
msg_topology -> parnt_ID = parent;
msg_topology -> parnt_lqi = lqi;
numNeighbor = call CtpInfo.numNeighbors();//获得路由表中有效的邻居节点的个数
temp = currentIndex;
if(numNeighbor >= 4) {
if(currentIndex < numNeighbor){
for (i = 0 ; i < 3 ; i++){
neighbor_id = call CtpInfo.getNeighborAddr(currentIndex);
if(neighbor_id != parent){
msg_topology -> info[i].id = neighbor_id;
msg_topology -> info[i].lqi = call CtpInfo.getNeighborLinkQuality(currentIndex);
}
else
i--;
currentIndex++;
currentIndex = currentIndex % numNeighbor ;
}
}
else {
currentIndex = 0;
for (i=0 ; i < 3 ; i++){
neighbor_id = call CtpInfo.getNeighborAddr(currentIndex);
if(neighbor_id != parent){
msg_topology -> info[i].id = neighbor_id;
msg_topology -> info[i].lqi = call CtpInfo.getNeighborLinkQuality(currentIndex);
}
else
i--;
currentIndex++;
currentIndex = currentIndex % numNeighbor ;
}
}
msg_topology -> length = sizeof(topologyData_t) - 1 ;//去除length域本身
}
else {
if(currentIndex < numNeighbor){
for (i = 0 ; i < numNeighbor -1 ; i++){
neighbor_id = call CtpInfo.getNeighborAddr(currentIndex);
if(neighbor_id != parent){
msg_topology -> info[i].id = neighbor_id;
msg_topology -> info[i].lqi = call CtpInfo.getNeighborLinkQuality(currentIndex);
}
else
i--;
currentIndex++;
currentIndex = currentIndex % numNeighbor ;
}
}
else {
currentIndex = 0;
for (i=0 ; i < numNeighbor - 1 ; i++){
neighbor_id = call CtpInfo.getNeighborAddr(currentIndex);
if(neighbor_id != parent){
msg_topology -> info[i].id = neighbor_id;
msg_topology -> info[i].lqi = call CtpInfo.getNeighborLinkQuality(currentIndex);
}
else
i--;
currentIndex++;
currentIndex = currentIndex % numNeighbor ;
}
}
msg_topology -> length = sizeof(neighbour_info)* (numNeighbor-1) + 4 ;// 4 : 父节点地址和链路质量的长度;sizeof(neighbour_info)* numNeighbor:实际邻居节点信息所占的长度
}
}
/*获得状态数据*/
void getStateData(){
stateData_t* msg_state;
msg_state = (stateData_t* )call StateDataSend.getPayload(&StateData_Msg, sizeof(stateData_t));
call voltageRead.read();
msg_state -> length = sizeof(stateData_t) - 1 ; //去除length本身的长度
msg_state -> data[0].state_type = STATE_NODE_TYPE ;
msg_state -> data[0].state = Node_Type ;
}
/*返回节点地址在路由表中对应的索引号*/
uint8_t routingTableFind(am_addr_t neighbor) {
uint8_t i , numNeighbor;
numNeighbor = call CtpInfo.numNeighbors();
for (i = 0; i < numNeighbor; i++) {
if (call CtpInfo.getNeighborAddr(i) == neighbor)
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -