ZigBee无线传感器网络远程数据采集系统

1、实验内容:协调器建立网络,路由器和终端节点加入网络,然后周期性地采集温度和电压发送给协调器,协调器通过串口发送给PC的串口调试助手

2、补充:(为了便于数据的传输和管理,传输的数据用一个结构体表示)如下

//NewCoordinator.h
typedef union h
{unsigned char databuf[18];struct RFRXBUF{unsigned char head[2];  //  "&&"unsigned char type[3];  //  "ROU"或 "END"unsigned char myNWK[4]; //  自身的网络地址unsigned char pNWK[4];  //  父节点的网络地址unsigned char value[4];  // value[0]表采集数据的类型  如:W表温度  V表电压 后面几位表数值unsigned char tail;     //"&"}BUF;
}RFTX;
上面是个联合结构体,便于数据的强制类型转换。

3、程序设计

协调器程序设计(负责接收来自路由或终端节点发送来的数据,并通过串口发送到PC的串口助手进行显示)

/**************************** INCLUDES*/
#include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"
#include "NewCoordinator.h"
//#include "GenericApp.h"
#include "DebugTrace.h"#if !defined( WIN32 )#include "OnBoard.h"
#endif/* HAL */
#include "hal_lcd.h"
#include "hal_led.h"
#include "hal_key.h"
#include "hal_uart.h"
#include "aps_groups.h"#define SEND_TO_ALL_EVENT 0x01/********************************************************************** MACROS*//********************************************************************** CONSTANTS*//********************************************************************** TYPEDEFS*//********************************************************************** GLOBAL VARIABLES*/// This list should be filled with Application specific Cluster IDs.
const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS] =
{GENERICAPP_CLUSTERID
};const SimpleDescriptionFormat_t GenericApp_SimpleDesc =
{GENERICAPP_ENDPOINT,              //  int Endpoint;GENERICAPP_PROFID,                //  uint16 AppProfId[2];GENERICAPP_DEVICEID,              //  uint16 AppDeviceId[2];GENERICAPP_DEVICE_VERSION,        //  int   AppDevVer:4;GENERICAPP_FLAGS,                 //  int   AppFlags:4;//下面的初始化 二选一!!!!!!!!GENERICAPP_MAX_CLUSTERS,          //  byte  AppNumInClusters;(cId_t *)GenericApp_ClusterList,  //  byte *pAppInClusterList;// GENERICAPP_MAX_CLUSTERS,          //  byte  AppNumInClusters;// (cId_t *)GenericApp_ClusterList   //  byte *pAppInClusterList;0,(cId_t *)NULL
};// This is the Endpoint/Interface description.  It is defined here, but
// filled-in in GenericApp_Init().  Another way to go would be to fill
// in the structure here and make it a "const" (in code space).  The
// way it's defined in this sample app it is define in RAM.
endPointDesc_t GenericApp_epDesc;/********************************************************************** EXTERNAL VARIABLES*//********************************************************************** EXTERNAL FUNCTIONS*//********************************************************************** LOCAL VARIABLES*/
byte GenericApp_TaskID;   // Task ID for internal task/event processing// This variable will be received when// GenericApp_Init() is called.
devStates_t GenericApp_NwkState;byte GenericApp_TransID;  // This is the unique message ID (counter)//afAddrType_t GenericApp_DstAddr;/********************************************************************** LOCAL FUNCTIONS*/
//void GenericApp_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg );
//void GenericApp_HandleKeys( byte shift, byte keys );
void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );//处理事件
void GenericApp_SendTheMessage( void );//发送数据
static void rxCB(uint8 port,uint8 envent);/********************************************************************** NETWORK LAYER CALLBACKS*//********************************************************************** PUBLIC FUNCTIONS*//********************************************************************** @fn      GenericApp_Init** @brief   Initialization function for the Generic App Task.*          This is called during initialization and should contain*          any application specific initialization (ie. hardware*          initialization/setup, table initialization, power up*          notificaiton ... ).** @param   task_id - the ID assigned by OSAL.  This ID should be*                    used to send messages and set timers.** @return  none*/
void GenericApp_Init( byte task_id )
{GenericApp_TaskID = task_id;// GenericApp_NwkState = DEV_INIT;   //这句不注释掉 会怎样???GenericApp_TransID = 0;// Fill out the endpoint description.GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;GenericApp_epDesc.task_id = &GenericApp_TaskID;GenericApp_epDesc.simpleDesc= (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;GenericApp_epDesc.latencyReq = noLatencyReqs;// Register the endpoint description with the AFafRegister( &GenericApp_epDesc );//串口的设置,并打开串口halUARTCfg_t uartConfig;uartConfig.configured =TRUE;uartConfig.baudRate   =HAL_UART_BR_115200;uartConfig.flowControl=FALSE;uartConfig.callBackFunc=NULL;//???????????????????????????????????//uartConfig.callBackFunc=rxCB;HalUARTOpen(0,&uartConfig);   //打开串口
}/********************************************************************** @fn      GenericApp_ProcessEvent** @brief   Generic Application Task event processor.  This function*          is called to process all events for the task.  Events*          include timers, messages and any other user defined events.** @param   task_id  - The OSAL assigned task ID.* @param   events - events to process.  This is a bit map and can*                   contain more than one event.** @return  none*/
UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events )
{afIncomingMSGPacket_t *MSGpkt;// HalLedBlink(HAL_LED_1,0,50,500);if ( events & SYS_EVENT_MSG ){MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );while ( MSGpkt ){switch ( MSGpkt->hdr.event ){case AF_INCOMING_MSG_CMD:  //天线接收到数据//  HalLedBlink(HAL_LED_2,0,50,500);GenericApp_MessageMSGCB( MSGpkt );   //接收数据并把数据发送到UARTbreak;             default:break;}// Release the memoryosal_msg_deallocate( (uint8 *)MSGpkt );// NextMSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );}// return unprocessed eventsreturn (events ^ SYS_EVENT_MSG);}return 0;
}/********************************************************************** LOCAL FUNCTIONS*//********************************************************************** @fn      GenericApp_MessageMSGCB** @brief   Data message processor callback.  This function processes*          any incoming data - probably from other devices.  So, based*          on cluster ID, perform the intended action.** @param   none** @return  none*/
void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{RFTX rftx;unsigned char changeline[2]={0x0A,0x0D};switch ( pkt->clusterId ){case GENERICAPP_CLUSTERID:osal_memcpy(&rftx,pkt->cmd.Data,sizeof(rftx));HalUARTWrite(0,rftx.databuf,sizeof(rftx));  //从这一行你就能看到联合体的作用、好处HalUARTWrite(0,changeline,2);  break;}
}

路由器节点或终端节点(共用的Sonsor.h、Sonsor.c、NewEnddevice.c文件)

//Sensor.h
#ifndef SENSOR_H
#define SENSOR_H
#include <hal_types.h>
extern int8 readTemp(void);
extern unsigned int getVddvalue(void);
#endif

Sensor.c主要用于传感器采集的实现

#include "Sensor.h"
#include <ioCC2530.h>//你知道下面宏的具体含义是什么吗???
#define ADC_REF_115V 0x00
#define ADC_DEC_256  0x20
#define ADC_CHN_TEMP 0x0e
#define ADC_DEC_064      0x00
#define ADC_CHN_VDD3     0x0fint8 readTemp(void)
{static uint16 reference_voltage;static uint8  bCalibrate=TRUE;unsigned char tmpADCCON3=ADCCON3;//????????uint16 value;int8 temp;ATEST=0x01;  //使能温度传感器TR0|=0x01;   //连接温度传感器ADCIF=0;     //?????ADCCON3=(ADC_REF_115V|ADC_DEC_256|ADC_CHN_TEMP);//???????while(!ADCIF)//???????;ADCIF=0;value=ADCL;                   //这里应该是取低位value |=((uint16)ADCH)<<8;   //这里应该是取高位value>>=4;//除以16???if(bCalibrate)//记录第一次读取的温度值,用于校正温度数据{reference_voltage=value;bCalibrate=FALSE;   }temp=22+((value-reference_voltage)/4);//温度校正函数return temp;}unsigned int getVddvalue(void)
{unsigned int value;unsigned char tmpADCCON3=ADCCON3;ADCIF=0;ADCCON3=(ADC_REF_115V|ADC_DEC_064|ADC_CHN_VDD3);while(!ADCIF);value=ADCH;ADCCON3=tmpADCCON3;return (value);
}

NewEndDevice.c

/********************************************************************** INCLUDES*/
#include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"#include "NewCoordinator.h"
//#include "GenericApp.h"
#include "DebugTrace.h"#if !defined( WIN32 )#include "OnBoard.h"
#endif/* HAL */
#include "hal_lcd.h"
#include "hal_led.h"
#include "hal_key.h"
#include "hal_uart.h"#define SEND_DATA_EVENT 0x01
#include "Sensor.h"
/********************************************************************** MACROS*//********************************************************************** CONSTANTS*//********************************************************************** TYPEDEFS*//********************************************************************** GLOBAL VARIABLES*/// This list should be filled with Application specific Cluster IDs.
const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS] =
{GENERICAPP_CLUSTERID
};const SimpleDescriptionFormat_t GenericApp_SimpleDesc =
{GENERICAPP_ENDPOINT,              //  int Endpoint;GENERICAPP_PROFID,                //  uint16 AppProfId[2];GENERICAPP_DEVICEID,              //  uint16 AppDeviceId[2];GENERICAPP_DEVICE_VERSION,        //  int   AppDevVer:4;GENERICAPP_FLAGS,                 //  int   AppFlags:4;//下面是二选一0,(cId_t*)0,//GENERICAPP_MAX_CLUSTERS,          //  byte  AppNumInClusters;// (cId_t *)GenericApp_ClusterList,  //  byte *pAppInClusterList;GENERICAPP_MAX_CLUSTERS,          //  byte  AppNumInClusters;(cId_t *)GenericApp_ClusterList   //  byte *pAppInClusterList;
};// This is the Endpoint/Interface description.  It is defined here, but
// filled-in in GenericApp_Init().  Another way to go would be to fill
// in the structure here and make it a "const" (in code space).  The
// way it's defined in this sample app it is define in RAM.
endPointDesc_t GenericApp_epDesc;/********************************************************************** EXTERNAL VARIABLES*//********************************************************************** EXTERNAL FUNCTIONS*//********************************************************************** LOCAL VARIABLES*/
byte GenericApp_TaskID;   // Task ID for internal task/event processing// This variable will be received when// GenericApp_Init() is called.
devStates_t GenericApp_NwkState;byte GenericApp_TransID;  // This is the unique message ID (counter)//afAddrType_t GenericApp_DstAddr;  //???????????????/********************************************************************** LOCAL FUNCTIONS*/
//void GenericApp_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg );
//void GenericApp_HandleKeys( byte shift, byte keys );
void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );
void GenericApp_SendTheMessage( void );void SendInfo(void);
void sendVdd(void);
void sendTemp(void);void To_string(uint8 *dest,char* src,uint8 length);//二进制书转化为十六进制数  //static void rxCB(uint8 port,uint8 envent);/********************************************************************** NETWORK LAYER CALLBACKS*//********************************************************************** PUBLIC FUNCTIONS*//********************************************************************** @fn      GenericApp_Init** @brief   Initialization function for the Generic App Task.*          This is called during initialization and should contain*          any application specific initialization (ie. hardware*          initialization/setup, table initialization, power up*          notificaiton ... ).** @param   task_id - the ID assigned by OSAL.  This ID should be*                    used to send messages and set timers.** @return  none*/void GenericApp_Init( byte task_id )
{GenericApp_TaskID = task_id;GenericApp_NwkState = DEV_INIT;GenericApp_TransID = 0;// Fill out the endpoint description.GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;GenericApp_epDesc.task_id = &GenericApp_TaskID;GenericApp_epDesc.simpleDesc= (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;GenericApp_epDesc.latencyReq = noLatencyReqs;// Register the endpoint description with the AFafRegister( &GenericApp_epDesc );
}/********************************************************************** @fn      GenericApp_ProcessEvent** @brief   Generic Application Task event processor.  This function*          is called to process all events for the task.  Events*          include timers, messages and any other user defined events.** @param   task_id  - The OSAL assigned task ID.* @param   events - events to process.  This is a bit map and can*                   contain more than one event.** @return  none*/
UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events )
{afIncomingMSGPacket_t *MSGpkt;if ( events & SYS_EVENT_MSG ){MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );while ( MSGpkt ){switch ( MSGpkt->hdr.event ){        case ZDO_STATE_CHANGE:GenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status);if ( (GenericApp_NwkState == DEV_ROUTER)|| (GenericApp_NwkState == DEV_END_DEVICE) ){osal_set_event(GenericApp_TaskID,SEND_DATA_EVENT);}break;default:break;}// Release the memoryosal_msg_deallocate( (uint8 *)MSGpkt );// NextMSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );}// return unprocessed eventsreturn (events ^ SYS_EVENT_MSG);}if ( events &  SEND_DATA_EVENT ){sendTemp();sendVdd();osal_start_timerEx( GenericApp_TaskID,SEND_DATA_EVENT,    //事件GENERICAPP_SEND_MSG_TIMEOUT );//定时时间return (events ^ SEND_DATA_EVENT);}// Discard unknown eventsreturn 0;
}void sendTemp(void)
{RFTX rftx;uint16 nwk;osal_memcpy(rftx.BUF.head,"&&",2);if(GenericApp_NwkState==DEV_ROUTER)osal_memcpy(rftx.BUF.type,"ROU",3);if(GenericApp_NwkState==DEV_END_DEVICE)osal_memcpy(rftx.BUF.type,"END",3);nwk=NLME_GetShortAddr();To_string(rftx.BUF.myNWK,(uint8*)&nwk,2);nwk=NLME_GetCoordShortAddr();To_string(rftx.BUF.pNWK,(uint8*)&nwk,2);uint16 tempvalue;tempvalue=readTemp();rftx.BUF.value[0]='W';rftx.BUF.value[1]=tempvalue/10+'0';rftx.BUF.value[2]=tempvalue%10+'0';rftx.BUF.value[3]='*';rftx.BUF.tail='&';afAddrType_t my_DstAddr;my_DstAddr.addrMode=(afAddrMode_t)Addr16Bit;my_DstAddr.endPoint=GENERICAPP_ENDPOINT;my_DstAddr.addr.shortAddr=0x0000;AF_DataRequest(&my_DstAddr,&GenericApp_epDesc,GENERICAPP_CLUSTERID,18,(uint8*)&rftx,&GenericApp_TransID,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS);
}void sendVdd(void)
{RFTX rftx;uint16 nwk;osal_memcpy(rftx.BUF.head,"&&",2);if(GenericApp_NwkState==DEV_ROUTER)osal_memcpy(rftx.BUF.type,"ROU",3);if(GenericApp_NwkState==DEV_END_DEVICE)osal_memcpy(rftx.BUF.type,"END",3);nwk=NLME_GetShortAddr();To_string(rftx.BUF.myNWK,(uint8*)&nwk,2);nwk=NLME_GetCoordShortAddr();To_string(rftx.BUF.pNWK,(uint8*)&nwk,2);uint16 vddvalue;vddvalue=69*getVddvalue()/256;rftx.BUF.value[0]='V';rftx.BUF.value[1]=vddvalue/10+'0';rftx.BUF.value[2]='.';rftx.BUF.value[3]=vddvalue%10+'0'; rftx.BUF.tail='&';afAddrType_t my_DstAddr;my_DstAddr.addrMode=(afAddrMode_t)Addr16Bit;my_DstAddr.endPoint=GENERICAPP_ENDPOINT;my_DstAddr.addr.shortAddr=0x0000;if(AF_DataRequest(&my_DstAddr,&GenericApp_epDesc,GENERICAPP_CLUSTERID,18,(uint8*)&rftx,&GenericApp_TransID,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS)== afStatus_SUCCESS ){HalLedBlink(HAL_LED_1,0,50,500);}
}void To_string(uint8 *dest,char* src,uint8 length)//二进制书转化为十六进制数
{  uint8* xad;  uint8 i=0;  uint8 ch;  xad=src+length-1;  for(i=0;i<length;i++,xad--)  {  ch=(*xad>>4)&0x0F;  //除以十六  dest[i<<1]=ch+((ch<10)?'0':'7');  ch=*xad&0x0F;  dest[(i<<1)+1]=ch+((ch<10)?'0':'7');  }
}

4、实验结果

1-15 实验12 ZigBee无线传感器网络远程数据采集系统相关推荐

  1. ZigBee无线传感器网络远程数据采集系统设计

       ZigBee无线传感器网络远程数据采集系统设计             原理: 在实验中,协调器节点负责建立网络,路由器节点与终端节点申请加入网络,然后周期性地采集温度.电压等发送给协调器,协调 ...

  2. ZigBee学习(7)————Zigbee无线传感器网络远程数据采集

    目录 在开发ZigBee无线传感器网络过程中,需解决以下几个问题: 网络拓扑结构 传感器数据采集 网络节点能量供应问题 数据传输距离 设计原理图如下: 协调器编程: //Coordinator.hty ...

  3. 基于Zigbee的SHT10温湿度数据采集系统(已实现控制12个终端节点)——Zigbee协调器主要代码解析

    之前实现了基于Zigbee的SHT10温湿度数据采集系统,这里来重新复盘一些主要的知识和代码. 写在前面: 1 功能介绍:使用Zigbee终端节点采集环境的温度和湿度数据,然后将数据无线发送的Zigb ...

  4. 基于ZigBee的物联网环境数据采集系统

    1.概述 鉴于ZigBee技术适合用于数据采集系统的的特点, 提出了基于ZigBee的数据采集系统的设计方案, 着重探讨ZigBee节点的硬件设计及其组网设计. 并详细讨论了基于CC2530芯片的数据 ...

  5. 以太网接口 数据采集 matlab,基于以太网的远程数据采集系统

    项目背景及可行性分析 项目名称:基于以太网的远程数据采集系统 主要内容:课题研究的基于以太网的嵌入式数据采集系统,通过设计MicroBlaze IP核,将ADC控制器,以太网控制器,以及其它I/O设备 ...

  6. ZigBee无线传感器网络知识点总结

    第一章 无线传感器网络 Wireless Sensor Network (WSN) 1 无线传感器网络定义 无线传感器是一种大规模.自组织.多跳.无基础设施支持的无线网络,网络节点是同构的.成本较低, ...

  7. 基于arduino与raspberry的远程数据采集系统

    前言 该课题是毕业时做的一个远程数据采集课题,今天无意翻看到这份报告,不禁勾起满满的怀念.重新看了一遍报告,感觉做的确实是挺low的,但想起当时自己查了无数的资料,才完成这个设计,尤其是人在学校,然后 ...

  8. ZigBee无线传感器网络入门

    目录 1.物联网的体系结构简介 1.1.物理层 1.2.介质访问控制层 1.3.网络/安全层 1.4.应用层 2.最低需求估算 3.硬件资源 3.1.节点芯片选型 3.2.CC2530简介 3.2.1 ...

  9. 基于北斗RDSS短报文卫星的物联网自动气象远程数据采集系统

    一.项目概述   随着时代的进步发展,社会对自然可利用资源的开采,伴随而来的自然灾害对国家的经济.军事.政治.产业等的生产发展活动造成巨大的影响.利用气象监测站监测气象的实时变化,加以物联网云平台实现 ...

最新文章

  1. C#可用的日出日落时间类
  2. Spring Cloud Security:Oauth2使用入门
  3. BAT集体升级云事业部,这背后都藏着哪些“小心思”?
  4. Java黑皮书课后题第1章:1.3(显示图案)编写程序,显示下面的图案 Java
  5. java 基本类型 引用_java中 引用类型 和 基本类型 有何区别?
  6. linux 单例模式改密码,Java 利用枚举实现单例模式
  7. 【计蒜客 - 2019南昌邀请赛网络赛 - M】Subsequence(字典树,dp预处理)
  8. Linux的实际操作:文件目录类的实用指令(cat more less)
  9. HTML5手机重力与方向感应的应用——摇一摇效果
  10. JavaScript操作XML(IE6下)
  11. 常见错误 不能打开注册表关键字
  12. 2020年10月“省时查报告”十大热门报告盘点(附下载链接)
  13. Windows To Go,让Windows 8移动起来!
  14. 全新激光雕刻机切割机打标机写字机三轴步进电机运动控制板 控制板硬件软件全部是自己开发的
  15. Android3dtouch xposed,乐2 MIUI10 8.10.26增强版 主题和谐 黑域 3Dtouch 分屏 Gay设置-刷机之家...
  16. 开源项目halo个人博客源码学习初篇(一)
  17. 手机传感器你知道多少个?
  18. MatlabR2012a 显示使用过期的注册文件破解(.lic)
  19. 微信Mars-xlog日志加密踩坑指南
  20. html div中css设置平均水平分布,CSS - 水平和垂直分布div

热门文章

  1. 链接网络计算机提示请检查名称,绝地求生高端辅助如果win7设置了共享文件提示“请检查名称拼写”怎么办...
  2. node.js基于微信小程序的校园失物招领系统毕业设计源码072343
  3. php是不是越来越过时了,PHP是不是过时了?
  4. Peer pressure in extortion game can resolve social dilemma(博弈论+机制设计) 论文阅读笔记
  5. linux虚拟机联网问题:destination host unreachable
  6. linux虚拟机联网问题(三)--VMnet8
  7. 时间序列学习(1)——【时间序列初认识】
  8. 如何优雅的排出服务器错误
  9. [国产PLC]耐特过硬PLC在恒压供水管网监测改造设备中怎样运用
  10. [教你一招]设置Linux下中文显示