第一篇:基于无线传感网络的道路照明系统
基于无线传感网络的道路照明系统
杨兵
(徐州建筑职业技术学院,江苏 徐州 221116)
摘 要 :为了实现道路科学照明、绿色照明的关键问题是能够测量和控制到每一盏路灯,无线传感网络是解决这一问题最好的技术之一。选择Freescale公司MC13213芯片,设计了一种嵌入式无线通信模块,使整条道路的每一盏路灯自主联网,接受控制中心的指令,反馈路灯的各种状态,根据环境光强度和时段自动调节照明亮度,在保证道路照明质量和视觉舒适的情况下,节约电能。
关键词 :无线传感网络 ;道路照明;MC13213;ZigBee技术
中图分类号:TPXXX 文献标识码:A 文章编号:1234-567X(2010)一89—00XX—05
Road Lighting System Based on W ireless Sensor Networks
Yang Bing(Xuzhou Institute of Architectural Technology, Xuzhou, Jiangsu 221116)Abstract:The ability to measure and control each street—lamp is the key issue to realize road scientific lighting and green lighting.W ireless sensor network is one of the best technologies to solve this problem.MC13213 chip is used to design an embedded wireless communication module in this paper.Each street lamp on the whole road could independent network,receive instruction from control center,send various states feedback of street lamps and automatically adjust lighting levels according to the ambient light intensity.This technology could ensure the quality of road lighting.visual comfort and save energy 20%~30% .
Key words:wireless sensor network;road lighting;MC13213;ZigBee technology
0 引言
随着城市经济和规模的发展,各种类型的道路越来越长,机动车数量迅速增加,夜间交通流量也越来越大,道路照明质量直接影响交通安全和城市发展[1-2]。如何提高道路照明质量、降低能耗、实现绿色照明已成为城市照明的关键问题。道路照明的首要任务是在节约公共能源的基础上,提供安全和舒适的照明亮度,达到减少交通事故、提升交通运输效率的目的。由于基础设施的条件有限,目前普遍缺少路灯级的通信链路,路灯控制方式一般只能对整条道路统一控制,无法控制到每一盏灯[3]。本文基于无线传感网络,设计了一种嵌入式无线通信模块,实现了每盏路灯的无线自主组网,使每一盏路灯都能遥测和遥控,并达到路灯的亮度(或照度)在 30%~100%无级可调,可根据环境光强度和时段,在保证道路照明质量、辨认可靠且视觉舒适的情况下,节约电能 20%~30%。系统结构
基于无线传感网络道路照明系统的结构如图 1所示,通过在每盏路灯嵌入一个无线通信模块,使它们自组网络,接受控制中心的命令并将路灯的状态反馈给控制中心;HG-2控制箱采用ZigBee技术与所管辖道路的所有路灯通信,采用GPRS与控制中心通信,根据控制中心的指令或时间和照亮度对每盏路灯发出控制命令[路灯开启、关闭、照明度(功率大小)等],自动调节整条道路的功率平衡;控制中心由服务器、大屏显示、Center View中央控制系统软件平台等组成,Center View中央控制系统软件平台采用3D设计,通过缩放变换以俯视的角度观察和控制整个城市、一个街道、一条道路甚至一盏路灯的照明情况;移动计算工具(笔记本电脑、PDA、手机)和路灯维护车也能通过控制中心进行远程遥测和遥控。无线通信模块
无线通信模块的MCU为Freesclae公司MC13213,MC13213采用SiP技术在9mm×9ram的LGA封装内集成了MC9S08GT主控MCU和MC1320x射频收发器。MC13213拥有4kB的RAM、60kB的FLASH,具有1个串行外设接口SPI(Serial Peripheral Interface)、2个异步串行通信接口SCI(Serial Communications Interface)、1个键盘中断模KBI(Keyboard Interrupt)、2个定时器/脉宽调制模块TPM(Timer/PWM)、1个8通道10位的模数转换器ADC(Analog/Digital Converter)以及多达32个的GPIO口等,如图2所示。
无线通信模块采用ZigBee技术、IEEE 802.15.4协议,通信覆盖半径可达150m,能与在其覆盖范围内的任何路灯节点自组网络及进行通信。除了实现路灯的物物相联以外,还可调节电子镇流器的功率输出(30%~100%),实现节能和绿色照明,检测供电线路的电流、电压、功率因数以及每一盏灯的工作状态,当发生故障(如灯具损坏、灯杆撞击、人为破坏)时实时向监控中心和相关部门报警等。无线通信模块还进行了防雨、防潮、防雷电、防电磁干扰设计,并充分考虑了安装方便、维护简单和可恢复性(接入两根线就实现了路灯级的无线控制,拆除两根线又恢复到原来的状态),可以嵌入在路灯的不同位置(灯杆底部、灯杆内、灯罩内)。控制中心软件设计
控制中心的软件设计平台为Windows 2003,开发工具是微软Visual Studio6.0,数据库使用SQL Server 2005,与地理信息系统相结合,在获取了街道、建筑物以及路灯的位置、形状等特征信息后,设计以路灯为主体的3维虚拟城市,在控制中心大屏幕上动态显示道路的照明效果,并可以通过平移、放大、缩小等几何变换,观察整个城市、街道甚至每一盏路灯的照明情况。该软件主要有5个功能模块:系统设置、智能控制、电量核算、故障处理和紧急预案。系统设置中的区域设置有市、区、街道和电控箱4种;路灯设置有路灯的位置、型号、生产单位、施工单位、维护责任人、安装日期、清洗维护日期等;亮灯方式设置有全开、全关、单号路灯开、单号路灯关、双号路灯开、双号路灯关、1/3路灯开、1/3路灯关、1/4路灯开、1/4路灯关、智能控制等11种控制方式;时段设置可根据不同的城市不同的季节设置不同时段的亮灯方式。智能控制有两方面内容:①针对安装了电 子型路灯的路段,根据季节变化和天气状况,通过实时采样环境光强度,对路灯的照明亮度进行智能调节 ;② 在夜间,特别是深夜当检测到汽车和行人的流量十分稀少时,在不影响辨认可靠的情况下,适当降低道路的照明亮度,节约电耗。电量核算能对市、区、街道、电控箱甚至每盏路灯进行用电量的统计和核算。故障处理是对灯具损坏、断电、断相、过流、过压、三相不平衡以及人为破坏等情况,在第一时间向监控中心报警后迅速生成故障报告;故障处理的另一个功能是按路段和时段(年、季度、月)统计亮灯率、故障率、每次故障处理的效率
(平均修理时间)。紧急预案是对一些突发事件制定紧急预案,在特殊情况下,尽可能提供合适的道路照明,保证人民生命财产的安全。图3是控制中心软件的运行界面之一。实际应用
无线传感网络的道路照明系统自2009年5月以来在某国家级工业园区进行了安装和测试,安装环境为同一条道路两边的各100盏路灯,道路左边的100盏路灯采用无线传感智能控制,共增加成本8250.00元人民币,道路右边的100盏路灯采用常规的控制方式(半夜后单双号间隔开灯),测试结果如附表所示。
从附表中可以看出,采用无线传感网络的智能控制,100盏路灯在9l天中节约电能4506度,在产品投人的半年内就可以收回全部投资。使电耗降低的因素有以下几个方面:① 开启关闭时间的调整,道路右边的路灯控制方式是根据季节设定开闭时问(定时控制)并且是全功率开全功率闭(深夜半功率);道路左边的路灯控制方式是环境光强度和季节自动控制开闭时间,开启时,由于路面上尚有较强的环境光,路灯以补光的方式工作,逐渐增加照明强度,路灯关闭控制类似。② 由于深夜时居民用电负荷减少,低压电网电压升高,常规控制方式
下的路灯(道路右边)异常明亮、眩目,往往造成过度照明,不仅大大增加耗电,同时也导致灯具、电器实际使用寿命迅速下降,大量增加维护量和维护费用;深夜控制模式(道路左边),采用降功率照明,不但降低耗电,还能改善道路照明质量和视觉舒适度,延长灯具、电器的实际使用寿命。③ 道路照明的智能控制,对学校、居民密集的小区、道路转弯处、事故多发地带等特殊路段,适当提高照明亮度,其余路段则适当降低照明亮度。结 论
先进的道路照明不但可以提升城市的形象、提高交通运输效率、减少交通事故,还能节约大量的公共电能消耗。但对于大多数城市来说,由于缺少必需的基础设施(路灯级的通信链路),无法实现先进控制方法。无线传感网络(物联网)的出现和应用,有效地解决了以上问题。本文基于无线传感网络,选择Freescale公司的MC13213芯片,设计了一种嵌入式无线通信模块,使整条道路的每一盏路灯自主联网,实现了路灯的遥测、遥控,对节约公共资源,建设数字化和节约型城市有较高的实际应用价值。
参 考 文 献
[1]杨春宇,胡英奎,陈仲林.用中间视觉理论研究道路照明节能[J].照明工程学报,2008,19(4):44—47. [2]张惠玲,王晓雯.城市道路照明设置与节能探讨[J].重庆交通大学学报(自然科学版),2007,26(10):lO6—109 [3]卢秀和,王 琪,陈 军,等.城市照明智能调光方法的研究[J].电力电子技术,2007,41(10):34—36.
第二篇:无线传感网络课程设计
无线传感网络 课程设计报告
姓名:胡韶辉 胡衎
2017
学号:139074377 139074376 班级:物131班 指导教师:卫琳娜
年1月1日
无线传感网络课程设计
实验
一、无线传感网络点对点通信实验
1.实验内容
此实验为验证实验,根据实验步骤进行实验,观察结果是否与预期相符
2.实验步骤
用IAR8.1打开路径:C:UsersxsDesktop无线传感器网络课程设计无线传感网实验资料201604感知RF2-2530WSNV1.2代码和例子程序Light_SwitchIDELight_Switchsrf05_cc2530IarLight_Switch.eww分别编译并下载至两个节点上,打开节点,左右键选择
/* 功 能:查找字符在索引中的哪一个位置 */ /**************************************************************************************************/ static u16 lookforChar(u8 ch){ uint16 i;for(i = 0;i < FONTLISTCOUNT;i ++){
if(fontList[i] == ch)
return i;} return i;}
//查中文
static u16 lookforChar16(u16 ch){ uint16 i,j;u16 temp16;for(i = 0;i < fontChar16ListCount;i ++){
j = i*2;
temp16 = fontChar16List[j + 1];
temp16 <<= 8;
temp16 |= fontChar16List[j];
if(temp16 == ch)
return i;} return i;}
/**************************************************************************************************/ /* 功 能:在指定位置输出8*8 */ /**************************************************************************************************/ static void LcdPutChar8(u8 x,u8 y,u8 ch){ LcdBuf[y][x] = ch;} /**************************************************************************************************/ /* 功 能:在指定位置输出16*16 */ /**************************************************************************************************/
/*static void LcdPutChar16(u8 x,u8 y,u16 ch){ LcdBuf[y][x] =(u8)ch;
//低前高后
LcdBuf[y+1][x] =(u8)(ch>>8);}
void LcdPutString8(u8 x,u8 y,u8 *ptr u8 len,u8 op){
u8 i,*tptr = ptr,xx = x,yy = y;u16 m;if(x > 95)
return;if(y > 1)
return;for(i = 0;i < len;i ++){
m = lookforChar(*tptr ++);
if(m!= FONTLISTCOUNT)
{
m = m * 8;
}
else
return;
xx += 8;
if(xx > 88)
return;} } */
void LcdClearRam(void){ u8 i;for(i = 0;i < 96;i ++){
LcdBuf[0][i] = 0;} for(i = 0;i < 96;i ++){
LcdBuf[1][i] = 0;} } void LcdClearScrean(void){ LcdClearRam();PutPic((void *)LcdBuf);}
void LcdPutString16_8(u8 x,u8 y,u8 *ptr,u8 len,u8 op){ u8 i,j,*tptr = ptr,xx = x,yy = y;u16 m;if(xx > 95)
return;if(yy)
return;
for(i = 0;i < len;i ++){
m = lookforChar(*tptr ++);
if(m!= FONTLISTCOUNT)
{
m = m * 16;
for(j = 0;j < 8;j ++)
{
if(op)
{
LcdPutChar8((xx + j),yy,font[m+j]);
LcdPutChar8((xx + j),yy+1,font[m+j+8]);
}
else
{
LcdPutChar8((xx + j),yy,~font[m+j]);
LcdPutChar8((xx + j),yy+1,~font[m+j+8]);
}
}
}
else
break;
xx += 8;
if(xx > 96)
return;} PutPic((void *)LcdBuf);} //显示16*16字符
void LcdPutString16_16(u8 x,u8 y,u8 *ptr,u8 len,u8 op){ u8 i,j,*tptr = ptr,xx = x,yy = y;u16 m;if(xx > 95)
return;if(yy)
return;
for(i = 0;i < len;i ++){
m = lookforChar(*tptr ++);
if(m!= FONTLISTCOUNT)
{
m = m * 32;
for(j = 0;j < 16;j ++)
{
if(op)
{
LcdPutChar8((xx + j),yy,font[m+j]);
LcdPutChar8((xx + j),yy+1,font[m+j+16]);
}
else
{
LcdPutChar8((xx + j),yy,~font[m+j]);
LcdPutChar8((xx + j),yy+1,~font[m+j+16]);
}
}
}
else
break;
xx += 16;
if(xx > 80)
return;} PutPic((void *)LcdBuf);}
static void LcdPrint8(u8 x,u8 y,u8 vl,u8 op){ u8 j;u16 m;m = lookforChar(vl);if(m!= FONTLISTCOUNT){
m = m * 16;
for(j = 0;j < 8;j ++)
{
if(op)
{
LcdPutChar8((x + j),y,font[m+j]);
LcdPutChar8((x + j),y+1,font[m+j+8]);
}
else
{
LcdPutChar8((x + j),y,~font[m+j]);
LcdPutChar8((x + j),y+1,~font[m+j+8]);
}
} } } static void LcdPrint16(u8 x, u8 y, u16 val, u8 op){ u8 j;u16 m;m = lookforChar16(val);if(m!= fontChar16ListCount)
{
m = m * 32;
for(j = 0;j < 16;j ++)
{
if(op)
{
LcdPutChar8((x + j),y,fontChar16[m+j]);
LcdPutChar8((x + j),y+1,fontChar16[m+j+16]);
}
else
{
LcdPutChar8((x + j),y,~fontChar16[m+j]);
LcdPutChar8((x + j),y+1,~fontChar16[m+j+16]);
}
}
} }
void LcdPutDispBuf(u8 x,u8 y,OledCodeDataType *ptr,u8 op){ u8 tcount = x;OledCodeDataType *tptr = ptr;u16 temp16;if(x > 88)
return;if(y > 1)
return;while((*tptr!= ' ')&&(tcount <= 88)){
if(*tptr < 127)
//显示ASIC码
{
}
else //显示汉字
{
LcdPrint8(tcount,y,*tptr,op);tptr ++;tcount += 8;
temp16 = tptr[1];temp16 <<= 8;temp16 |= tptr[0];LcdPrint16(tcount,y,temp16,op);tptr += 2;
tcount += 16;
} } PutPic((void *)LcdBuf);}
//实现中英文混合显示
void LcdPutDisp(u8 x,u8 y,OledCodeDataType *ptr,u8 op){ u8 tcount = x;OledCodeDataType *tptr = ptr;u16 temp16;if(x > 88)
return;if(y > 1)
return;while((*tptr!= ' ')&&(tcount <= 88)){
if(*tptr < 127)
码
{
LcdPrint8(tcount,y,*tptr,op);
tptr ++;
tcount += 8;
}
else
//显示汉字
{
temp16 = tptr[1];
temp16 <<= 8;
temp16 |= tptr[0];
LcdPrint16(tcount,y,temp16,op);
tptr += 2;
tcount += 16;
} } PutPic((void *)LcdBuf);} //从右往左输出一组字符并移运显示
void LcdPutScDispRtoL(OledCodeDataType *ptr,u8 op,u16 dl){ OledCodeDataType *tptr = ptr;u16 temp16;// LcdClearRam();
//显示ASIC
while(*tptr!= ' '){
if(*tptr < 127)码
//显示ASIC
{
memcpy(LcdBuf[0],&LcdBuf[0][8],88);
memcpy(LcdBuf[1],&LcdBuf[1][8],88);
LcdPrint8(88,0,*tptr,op);
tptr ++;
}
else
//显示汉字
{
memcpy(LcdBuf[0],&LcdBuf[0][16],80);
memcpy(LcdBuf[1],&LcdBuf[1][16],80);
temp16 = tptr[1];
temp16 <<= 8;
temp16 |= tptr[0];
LcdPrint16(80,0,temp16,op);
tptr += 2;
}
PutPic((void *)LcdBuf);
LcdDelay(dl);} }
void LcdPutScDispRtoL12(OledCodeDataType *ptr,u8 op,u16 dl){ OledCodeDataType *tptr = ptr;u16 i,temp16;for(i = 0;i < 12;){
if(*tptr < 127)
//显示ASIC码
{
memcpy(LcdBuf[0],&LcdBuf[0][8],88);
memcpy(LcdBuf[1],&LcdBuf[1][8],88);
LcdPrint8(88,0,*tptr,op);
tptr ++;
i ++;
}
else
//显示汉字
{
memcpy(LcdBuf[0],&LcdBuf[0][16],80);
memcpy(LcdBuf[1],&LcdBuf[1][16],80);
temp16 = tptr[1];
temp16 <<= 8;
temp16 |= tptr[0];
LcdPrint16(80,0,temp16,op);
tptr += 2;
i +=2;
}
PutPic((void *)LcdBuf);
LcdDelay(dl);} }
//从左往右
void LcdPutScDispLtoR12(OledCodeDataType *ptr,u8 op,u16 dl){ OledCodeDataType *ttptr,*tptr = ptr;u16 temp16;u8 i,len,tempbuf[2][96];
len = 12;
tptr = ptr+11;for(i = 0;i < len;){
if(*(tptr)< 127)
ASIC码
{
memcpy(&tempbuf[0][0],&LcdBuf[0][0],96);
memcpy(&tempbuf[1][0],&LcdBuf[1][0],96);
memcpy(&LcdBuf[0][8],&tempbuf[0][0],88);
memcpy(&LcdBuf[1][8],&tempbuf[1][0],88);
LcdPrint8(0,0,*tptr,op);
tptr--;
i ++;
}
else
//显示汉字
{
memcpy(&tempbuf[0][0],&LcdBuf[0][0],96);
memcpy(&tempbuf[1][0],&LcdBuf[1][0],96);
memcpy(&LcdBuf[0][16],&tempbuf[0][0],80);
memcpy(&LcdBuf[1][16],&tempbuf[1][0],80);
ttptr = tptr;
//显示
temp16 = *ttptr;
temp16 <<= 8;
ttptr = tptr-1;
temp16 |= *ttptr;
LcdPrint16(0,0,temp16,op);
tptr-= 2;
i += 2;
}
PutPic((void *)LcdBuf);
LcdDelay(dl);} } void LcdPutScString(OledCodeDataType *ptr,u8 op,u8 rl,u16 dl){
switch(rl){
case LIFT_SC:
LcdPutScDispLtoR12(ptr,op,dl);
break;
case RIGHT_SC:
LcdPutScDispRtoL12(ptr,op,dl);
break;
default:break;
} }
void LcdPutPic(u8 x, u8 y,u8 w,u8 h,OledCodeDataType *ptr,u8 op){ u8 i;OledCodeDataType *tptr = ptr;if((x > 95)||((x + w)> 96))
return;if((y > 1)||((y + h)> 2))
return;
for(i = 0;i < w;i ++)
{
if(op)
{
LcdBuf[y][x + i] = *tptr;
if(h == 2)
LcdBuf[y+1][x + i] = *(tptr+w);
tptr ++;
}
else
{
LcdBuf[y][x + i] = ~*tptr;
if(h == 2)
LcdBuf[y+1][x + i] = ~*(tptr+w);
tptr ++;
} } PutPic((void *)LcdBuf);}
//整屏滑动显示
void LcdPutScPic(OledCodeDataType *ptr, u8 op,u8 qp,u16 dl){ u8 i,j;u8 tempbuf[2][96];if(qp){
for(i = 0;i < 96;i ++)
{
tempbuf[0][i] = *ptr++;
}
for(i = 0;i < 96;i ++)
{
tempbuf[1][i] = *ptr++;
}
} else {
for(i = 0;i < 96;i ++)
{
tempbuf[0][i] = ~*ptr++;
}
for(i = 0;i < 96;i ++)
{
tempbuf[1][i] = ~*ptr++;
}
}
switch(op){
case RIGHT_SC:
//右边
for(i = 0;i < 8;i ++){
for(j = 0;j < 84;j ++)
{
LcdBuf[0][95-j] = LcdBuf[0][83j];
}
for(j = 0;j < 12;j ++)
{
LcdBuf[0][11-j] = tempbuf[0][95j];
}
for(j = 0;j < 84;j ++)
{
tempbuf[0][95-j] = tempbuf[0][83j];
}
PutPic((void *)LcdBuf);
} LcdDelay(dl);break;case LIFT_SC:
//左边
for(i = 0;i < 8;i ++){
for(j = 0;j < 84;j ++)
{
LcdBuf[0][j] = LcdBuf[0][j + 12];
LcdBuf[1][j] = LcdBuf[1][j + 12];
}
for(j = 0;j < 12;j ++)
{
LcdBuf[0][95-j] = tempbuf[0][11-j];
LcdBuf[1][95-j] = tempbuf[1][11-j];
}
for(j = 0;j < 84;j ++)
{
tempbuf[0][j] = tempbuf[0][j+12];
tempbuf[1][j] = tempbuf[1][j+12];
}
PutPic((void *)LcdBuf);
} LcdDelay(dl);break;default:
break;} }
void LcdPutString16_8_R(u8 *ptr,u8 op){ u8 i,x=0;
for(i=0;i<12;i++){ x=88-i*8;LcdPutString16_8(x,0,ptr,i+1,op);LcdDelay(100);} } 4.实验总结
此实验室实现两个节点间的通信,可以输出中文或英文,或中英文混合输出。其主要原理是通过ASIC将中英文转换,通过字符串的拼凑输出。
实验
二、光照传感器实验
1.实验内容
1.了解光照采集的原理
2.学习CDS 光照传感器从而掌握光照传感器的原理 3.掌握“传感器节点板”模块的原理和使用方法。2.实验步骤
第一步:把“代码和例子程序Zigbee2007 多传感器”内文件夹 “ZStack-CC2530-2.2.0-1.3.0MS”“”复制至 IAR 安装盘根目录(如 C: Texas Instruments)下。使用 IAR7.51 打开“ProjectszstackSamplesSampleAppCC2530 DB”中工程文件“SampleApp.eww”。
第二步:打开工程后选择对应的设备类型 打开工程后如下右图所示选择当前要烧写设备的类型。
打开后的工程文件 工程名称 ZigBee 网络功能 CC2530-WSN 节点功能 CoordinatorEB-Pro 协调器 网关 RouterEB-Pro 路由器 路由器节点、传感器节点 EndDeviceEB-Pro 终端节点 传感器节点
第三步:编译工程并下载到目标板。点击菜单 Project,选择“Rebuild All”,等待一会儿工程文件编译完成。等 待一会儿工程文件编译完成把仿真器与网关通过仿真器下载线连接起来。确保仿 真器与计算机、仿真器与网关底板连接正确,ZigBee 无线模块正确地插在网关 底板后。点击菜单 Project,选择“Debug”,或点击如下图标,等待一会儿即完成程 序下载 重复进行第二步和第三步,将“RouterEB-Pro”设备对应的程序下载到带传 感器模块的传感器节点底板中(SMBD-V11-1)第四步:修改 IEEE 地址。在物理地址烧写软件中首先通过“Read IEEE”把物 理地址(IEEE 地址)读出来,如果节点物理地址为“0XFF FF FF FF FF FF FF FF” 或在网络中有相同地址,则需要通过“Write IEEE”修改 ZigBee 网络节点的物 理地址,在此例中,我们把网关的物理地址修改“0x31,0x30,0x30,0x30,0x30,0x30, 0x30,0x30”。按照第二步至第四步的方法下载传感器节点模块的程序,选择 “RouterEB”或“EndDevice”,如有多组在同一实验室进行实验,请修改为各 不相同的 IEEE 地址。第五步:获取和查看光照传感器数据 用 USB 线连接上 PC 机跟网关,打开“代码和例子程序Zigbee2007 多传感 器无线龙 ZigBee 演示软件 V1.21(串口用)”目录下“无线龙 ZigBee 演示软件 V1.21(串口用).exe”软件。通过设备管理器查看对应设备的串口号是多少,如图所示为 COM3。在监控 软件中选择“COM 端口”COM3,波特率:38400,点击“打开串口”。正确打开串口后,选择网络拓扑图,确保网关与计算机的正确连接。3.实验代码与分析
case 4://普通温度、光敏、蜂鸣器 if(DispState == 0){ LcdPutString16_8(0, 0,(void*)“ Temp/Light ”, 12 , 1);} else if(DispState == 1){ temp = ReadTc77();//读取温度 sprintf(msg,“TEMP:%2d ”,temp);LcdPutString16_8(0, 0,(void*)msg, 12 , 1);} else if(DispState == 2)//读取光照 { temp = ReadSensorAdc(1);sprintf(msg,“Light:%03d ”,temp);LcdPutString16_8(0, 0,(void*)msg, 12 , 1);}
break;通过 ADC 读取光敏传感器值:
temp = ReadSensorAdc(1);//读取光敏传感器值
ReadSensorAdc 子函数位于“ ComponentshaltargetCC2530EB”目录下的 Sensor.c 文件中
temp = HalAdcRead(channel,HAL_ADC_RESOLUTION_8);channel 光敏传感器对应的 AD 通道 P01
HAL_ADC_RESOLUTION_8 采集分辨率 8Bit
ADC 采 集 子 函 数 在 在 “ComponentshaltargetCC2530EB ” 目 录 下 的
“ hal_adc.c”文件
/****************************************************************************** ******************** * @fn HalAdcRead * * @brief Read the ADC based on given channel and resolution * * @param channelthe resolution of the value * * @return 16 bit value of the ADC in offset binary format.* Note that the ADC is “bipolar”, which means the GND(0V)level is mid-scale.******************************************************************************* *******************/ uint16 HalAdcRead(uint8 channel, uint8 resolution){ int16 reading = 0;#if(HAL_ADC == TRUE)uint8 i, resbits;uint8 adctemp;volatile uint8 tmp;uint8 adcChannel = 1;/* * If Analog input channel is AIN0..AIN7, make sure corresponing P0 I/O pin is enabled.The code * does NOT disable the pin at the end of this function.I think it is better to leave the pin * enabled because the results will be more accurate.Because of the inherent capacitance on
* pin, it takes time for the voltage on the pin to charge up to its steady-state level.If * HalAdcRead()has to turn on the pin for every conversion, the results may show a lower voltage * than actuality because the pin did not have time to fully charge.*/ if(channel < 8){ for(i=0;i < channel;i++){ adcChannel <<= 1;} } /* Enable channel */ ADCCFG |= adcChannel;/* Convert resolution to decimation rate */ switch(resolution){ case HAL_ADC_RESOLUTION_8: resbits = HAL_ADC_DEC_064;break;case HAL_ADC_RESOLUTION_10: resbits = HAL_ADC_DEC_128;break;case HAL_ADC_RESOLUTION_12: resbits = HAL_ADC_DEC_256;break;case HAL_ADC_RESOLUTION_14: default: resbits = HAL_ADC_DEC_512;break;} /* read ADCL,ADCH to clear EOC */ tmp = ADCL;tmp = ADCH;/* Setup Sample */ adctemp = ADCCON3;adctemp &= ~(HAL_ADC_CHN_BITS | HAL_ADC_REF_BITS);adctemp |= channel | resbits | HAL_ADC_REF_VOLT;/* writing to this register starts the extra conversion */ ADCCON3 = adctemp;/* Wait for the conversion to be done */ while(!(ADCCON1 & HAL_ADC_EOC));/* Disable channel after done conversion */ ADCCFG &=(adcChannel ^ 0xFF);/* Read the result */ reading =(int16)(ADCL);reading |=(int16)(ADCH << 8);/* Treat small negative as 0 */ if(reading < 0)reading = 0;switch(resolution){ case HAL_ADC_RESOLUTION_8: reading >>= 8;break;case HAL_ADC_RESOLUTION_10: reading >>= 6;break;case HAL_ADC_RESOLUTION_12: reading >>= 4;break;case HAL_ADC_RESOLUTION_14: default:
HAL_ADC_DEC_BITS |
break;} #else // unused arguments(void)channel;(void)resolution;#endif return((uint16)reading);}
4.实验总结
通过串口助手,配置正确的串口号和波特率,填入测试的数据指令,点击发送就可以获取网关返回的读取到节点的数据。
实验
三、气压传感器实验
1.实验内容
1.了解气压采集的原理
2.学习MPX5010 气压传感器从而掌握气压传感器的原理 3.掌握“ 传感器节点板” 模块的原理和使用方法。2.实验步骤
同“实验二十四 光照传感器实验 实验步骤第一步至第四步”
第五步:获取和查看大气气压传感器数据用 USB 线连接上 PC 机跟网关,打开“ 软件工具及驱动无线龙 ZigBee 演示软件 V1.11”目录下“无线龙 ZigBee 演示软件 V1.11.exe”软件。通过设备管理器查看对应设备的串口号是多少,如图所示为 COM3。在监控软件中选择“ COM 端口” COM3,波特率: 38400,点击“打开串口”。在 RSS 曲线部分中的下拉选择框中选择节点压力(如下图),鼠标左键单击选中要查看的节点模块。点击“开始”按钮,就可开始显示节点空气压力的曲线了(注:这时“开始”
按钮将变为“关闭”按钮)。为了使显示曲线效果明显,可以通过电扇吹气方式来达到明显效果。点击“关闭”按钮,则曲线停止,但曲线不会消失,这时“关闭”按钮将变为“开始”按钮,这时在点击“开始”按钮会弹出一格对话框,选择“是”则不清空曲线,继续在图上画曲线。选择“否”则清空曲线,再 在图上画曲线。点击“保存”按钮,可将曲线图以 RSS 格式的数据保存在电脑上,点击“载入”按钮,可以载入保存了曲线数据的 RSS 文件,将曲线显示在曲线图上。3.实验代码与分析
传感器采集的函数在 void SampleApp_MessageMSGCB(afIncomingMSGPacket_t *pkt)中
if((RfRx.RXDATA.HeadCom[1] == 'P')&&(RfRx.RXDATA.HeadCom[2] == 'R'))//压力传感器 { if(SensorNum == 5)//压力传感器板 { memcpy(RfTx.TxBuf, RfRx.RxBuf, 14);temp = ReadSensorAdc(0);RfTx.TXDATA.DataBuf[0] = temp/100 + 0x30;temp = temp%100;RfTx.TXDATA.DataBuf[1] = temp/10 + 0x30;RfTx.TXDATA.DataBuf[2] = temp%10 + 0x30;RfHaveTxDara = 1;} } //调用子函数 ReadSensorAdc 完成读取
//---------------------------//Read Sensor ADC value //读取 AD 值 //输入:通道名
//返回: 8 位 AD 值
//---------------------------INT8U ReadSensorAdc(INT8U channel){ INT8U temp;temp = HalAdcReadSen(channel,HAL_ADC_RESOLUTION_8);return temp;} 通过 ADC 读取大气压力传感器值:
temp = HalAdcReadSen(channel,HAL_ADC_RESOLUTION_8);/读取空气压力传感器值 channel 气体压力传感器对应的 AD 通道
HAL_ADC_RESOLUTION_8 采集分辨率 8Bit
ADC 采 集 子 函 数 在 在 “ComponentshaltargetCC2530EB ” 目 录 下 的 “ hal_adc.c”文件
/****************************************************************************** ******************** * @fn HalAdcRead * * @brief Read the ADC based on given channel and resolution * * @param channelthe resolution of the value * * @return 16 bit value of the ADC in offset binary format.* Note that the ADC is “bipolar”, which means the GND(0V)level is mid-scale.******************************************************************************* *******************/ uint16 HalAdcRead(uint8 channel, uint8 resolution)int16 reading = 0;#if(HAL_ADC == TRUE)uint8 i, resbits;uint8 adctemp;volatile uint8 tmp;uint8 adcChannel = 1;/* * If Analog input channel is AIN0..AIN7, make sure corresponing P0 I/O pin is enabled.The code * does NOT disable the pin at the end of this function.I think it is better to leave the pin * enabled because the results will be more accurate.Because of the inherent capacitance on the * pin, it takes time for the voltage on the pin to charge up to its steady-state level.If * HalAdcRead()has to turn on the pin for every conversion, the results may show a lower voltage * than actuality because the pin did not have time to fully charge.*/ if(channel < 8){ for(i=0;i < channel;i++){ adcChannel <<= 1;} } /* Enable channel */ ADCCFG |= adcChannel;/* Convert resolution to decimation rate */ switch(resolution){ case HAL_ADC_RESOLUTION_8: resbits = HAL_ADC_DEC_064;break;case HAL_ADC_RESOLUTION_10: resbits = HAL_ADC_DEC_128;break;case HAL_ADC_RESOLUTION_12: resbits = HAL_ADC_DEC_256;break;case HAL_ADC_RESOLUTION_14: default: resbits = HAL_ADC_DEC_512;break;} /* read ADCL,ADCH to clear EOC */ tmp = ADCL;tmp = ADCH;/* Setup Sample */ adctemp = ADCCON3;adctemp &= ~(HAL_ADC_CHN_BITS | HAL_ADC_DEC_BITS | HAL_ADC_REF_BITS);adctemp |= channel | resbits | HAL_ADC_REF_VOLT;/* writing to this register starts the extra conversion */ ADCCON3 = adctemp;/* Wait for the conversion to be done */ while(!(ADCCON1 & HAL_ADC_EOC));/* Disable channel after done conversion */ ADCCFG &=(adcChannel ^ 0xFF);/* Read the result */ reading =(int16)(ADCL);reading |=(int16)(ADCH << 8);/* Treat small negative as 0 */ if(reading < 0)reading = 0;switch(resolution){ case HAL_ADC_RESOLUTION_8: reading >>= 8;break;case HAL_ADC_RESOLUTION_10: reading >>= 6;break;case HAL_ADC_RESOLUTION_12: reading >>= 4;break;case HAL_ADC_RESOLUTION_14: default: break;} #else // unused arguments(void)channel;(void)resolution;#endif return((uint16)reading);} 4.实验总结
打开“ EXPLORERF-CC2530 增配传感器光盘 V1.1软件工具及驱动” 中工具 “ 串口调试助手.exe”配置正确的串口号和通讯波特率,填入测试的数据指令,点击发送就可以获取网关返回的读取到节点的数据。
实验
四、综合实验
1.实验原理
以一LED灯,LED显示屏作为工具。当LED灯显示时,LED显示屏上也显示信息灯亮。将LED灯作为协调器,LED显示屏作为终端,当LED灯亮时,会通过组网将信息传给终端,即此时LED显示屏显示灯亮,即LED显示屏给予LED灯亮的一个信息反馈。2.实验步骤
选择烧取设备的类型为CoordinatorEB-pro, 点击菜单 Project,选择“ Rebuild All”,等待一会儿工程文件编译完成。等待一会儿工程文件编译完成把仿真器与网关通过仿真器下载线连接起来。确保仿真器与计算机、仿真器与网关底板连接正确,ZigBee 无线模块正确地插在网关底板后。点击菜单 Project,选择“ Debug”,或点击如下图标,等待一会儿即完成程序下载.将烧取设备类型改为EndDeviceEB-pro,重复上述步骤。当LED亮时,此时显示屏也将有相应反应。4.实验代码
#include “OSAL.h” #include “ZGlobals.h” #include “AF.h” #include “aps_groups.h” #include “ZDApp.h”
#include “SampleApp.h” #include “SampleAppHw.h”
#include “OnBoard.h”
/* HAL */ #include “hal_lcd.h” #include “hal_led.h” #include “hal_key.h” #include “string.h” #include
#include “sensor.h” #include “SHT10.h” #include “ugOled9616.h” #include “LcdDisp.h” #include “TMP006.h” #include “hal_timer34.h” /********************************************************************* * MACROS */
/********************************************************************* * CONSTANTS */ /********************************************************************* * TYPEDEFS */
/********************************************************************* * GLOBAL VARIABLES */
// This list should be filled with Application specific Cluster IDs.const cId_t SampleApp_ClusterList[SAMPLEAPP_MAX_CLUSTERS] = { SAMPLEAPP_PERIODIC_CLUSTERID, SAMPLEAPP_FLASH_CLUSTERID };
const SimpleDescriptionFormat_t SampleApp_SimpleDesc = { SAMPLEAPP_ENDPOINT, // int Endpoint;SAMPLEAPP_PROFID, // uint16 AppProfId[2];SAMPLEAPP_DEVICEID, // uint16 AppDeviceId[2];SAMPLEAPP_DEVICE_VERSION, // int AppDevVer:4;SAMPLEAPP_FLAGS, // int AppFlags:4;SAMPLEAPP_MAX_CLUSTERS, // uint8 AppNumInClusters;(cId_t *)SampleApp_ClusterList, // uint8 *pAppInClusterList;SAMPLEAPP_MAX_CLUSTERS, // uint8 AppNumInClusters;(cId_t *)SampleApp_ClusterList // uint8 *pAppInClusterList;};
// This is the Endpoint/Interface description.It is defined here, but // filled-in in SampleApp_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 SampleApp_epDesc;
/********************************************************************* * EXTERNAL VARIABLES */ extern unsigned char SensorNum;extern INT8U DispNum;unsigned char DispState = 0;unsigned char Relay1State = 0;unsigned char Relay2State = 0;extern INT16U LEDDispNum;/********************************************************************* * EXTERNAL FUNCTIONS */
/********************************************************************* * LOCAL VARIABLES */ uint8 SampleApp_TaskID;// Task ID for internal task/event processing // This variable will be received when // SampleApp_Init()is called.devStates_t SampleApp_NwkState;
uint8 SampleApp_TransID;// This is the unique message ID(counter)uint8 *ieeeAddr;//物理地址
unsigned char LCDUPDATA = 0;//LCD刷新标致位 unsigned char Shakeflag = 0;unsigned char InfraredState = 0;unsigned char InfraredCount = 0;unsigned char InfraredInitFlag = 0;unsigned char HallState = 0;union f1{ uint8 RxBuf[32];struct UARTCOMBUF { uint8 Head;//头 uint8 HeadCom[3];//命令头 uint8 Laddr[8];//物理地址 uint8 Saddr[2];//网络地址 uint8 DataBuf[16];//数据缓冲区 uint8 CRC;//校验位
uint8 LastByte;//帧尾 }RXDATA;}UartRxBuf;//从串口接收到的数据帧
union e{ uint8 TxBuf[32];struct UARTBUF { uint8 Head;//头 uint8 HeadCom[3];//命令头 uint8 Laddr[8];//物理地址 uint8 Saddr[2];//网络地址 uint8 DataBuf[16];//数据缓冲区 uint8 CRC;//校验位
uint8 LastByte;//帧尾 }TXDATA;}UartTxBuf;//从串口发送数据帧
union h{ uint8 RxBuf[32];struct RFRXBUF { uint8 Head;//头
uint8 HeadCom[3];//命令头 uint8 Laddr[8];uint8 Saddr[2];uint8 DataBuf[16];//数据缓冲区
uint8 CRC;//校验位
uint8 LastByte;//帧尾 }RXDATA;}RfRx;//无线接收缓冲区
union j{ uint8 TxBuf[32];struct RFTXBUF { uint8 Head;//头
uint8 HeadCom[3];//命令头
uint8 Laddr[8];uint8 Saddr[2];uint8 DataBuf[16];//数据缓冲区
uint8 CRC;//校验位
uint8 LastByte;//帧尾 }TXDATA;}RfTx;//无线发送缓冲区
uint16 Ultrasonic_Count;//超声波计数
/***************************************************************************** void WaitUs(uint16 microSecs)
延时uS函数.*****************************************************************************/ void WaitUs(uint16 microSecs){ while(microSecs--){ /* 32 NOPs == 1 usecs */ asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);asm(“nop”);} }
/***************************************************************************** uint8 SendData(uint16 addr, uint8 *buf, uint8 Leng)
发送一组数据.*****************************************************************************/ uint8 SendData(uint16 addr, uint8 *buf, uint8 Leng){ afAddrType_t SendDataAddr;
SendDataAddr.addrMode =(afAddrMode_t)Addr16Bit;SendDataAddr.endPoint = SAMPLEAPP_ENDPOINT;SendDataAddr.addr.shortAddr = addr;if(AF_DataRequest(&SendDataAddr, &SampleApp_epDesc, 2,//SAMPLEAPP_PERIODIC_CLUSTERID, Leng, buf, &SampleApp_TransID, AF_DISCV_ROUTE, // AF_ACK_REQUEST, AF_DEFAULT_RADIUS)== afStatus_SUCCESS){
return 1;} else {
return 0;// Error occurred in request to send.} } case 1://DAC 输出
if(DispState == 0)
{
DAC_OUT_CON(0x07ff, 0x07ff);
LcdPutString16_8(0, 0,(void*)“ DAC-OUT ”, 12 , 1);
}
else if(DispState == 1)
{
DAC_OUT_CON(0x03ff, 0x03ff);
sprintf(msg,“OUT:0.5MA/V ”,temp);
LcdPutString16_8(0, 0,(void*)msg, 12 , 1);
}
else if(DispState == 2)
{
DAC_OUT_CON(0x0Bff, 0x0Bff);
sprintf(msg,“OUT:1.5MA/V ”,temp);
LcdPutString16_8(0, 0,(void*)msg, 12 , 1);
}
break;case 2://高亮LED控制
if(DispState == 0)
{
ChangT3Cmp0Val(0xff);
P1_6 = 0;
LcdPutString16_8(0, 0,(void*)“ LED-LIGHT ”, 12 , 1);
}
else if(DispState == 1)
{
ChangT3Cmp0Val(230);
LcdPutString16_8(0, 0,(void*)“LEVEL:10% ”, 12 , 1);
}
else if(DispState == 2)
{
ChangT3Cmp0Val(25);
LcdPutString16_8(0, 0,(void*)“LEVEL:90% ”, 12 , 1);
}
break;
} void SampleApp_Init(uint8 task_id){ SampleApp_TaskID = task_id;SampleApp_NwkState = DEV_INIT;SampleApp_TransID = 0;
// Device hardware initialization can be added here or in main()(Zmain.c).// If the hardware is application specificThis app will handle all key events RegisterForKeys(SampleApp_TaskID);
#ifdef WXL_COORD
MT_UartRegisterTaskID(SampleApp_TaskID);
#endif } void SampleApp_Init(uint8 task_id){ SampleApp_TaskID = task_id;SampleApp_NwkState = DEV_INIT;SampleApp_TransID = 0;
// Device hardware initialization can be added here or in main()(Zmain.c).// If the hardware is application specificThis app will handle all key events RegisterForKeys(SampleApp_TaskID);
#ifdef WXL_COORD
MT_UartRegisterTaskID(SampleApp_TaskID);
#endif }
/********************************************************************* * @fn SampleApp_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_idevents to process.This is a bit map and can * contain more than one event.* * @return none */ uint16 SampleApp_ProcessEvent(uint8 task_id, uint16 events){ afIncomingMSGPacket_t *MSGpkt;uint16 temp1;
#if(defined(WXL_ROUTER)|| defined(WXL_RFD))//ROUTER OR RFD uint16 SrcSaddr;#endif
(void)task_id;// Intentionally unreferenced parameter
if(events & SYS_EVENT_MSG){
MSGpkt =(afIncomingMSGPacket_t *)osal_msg_receive(SampleApp_TaskID);
while(MSGpkt)
{
switch(MSGpkt->hdr.event)
{
// Received when a key is pressed
case KEY_CHANGE:
SampleApp_HandleKeys(((keyChange_t *)MSGpkt)->state,((keyChange_t *)MSGpkt)->keys);
break;
// Received when a messages is received(OTA)for this endpoint
case AF_INCOMING_MSG_CMD:
SampleApp_MessageMSGCB(MSGpkt);
break;
// Received whenever the device changes state in the network
case ZDO_STATE_CHANGE:
SampleApp_NwkState =(devStates_t)(MSGpkt->hdr.status);
if((SampleApp_NwkState == DEV_ZB_COORD)
||(SampleApp_NwkState == DEV_ROUTER)
||(SampleApp_NwkState == DEV_END_DEVICE))
{
HalLedSet(HAL_LED_1,HAL_LED_MODE_ON);#ifdef WXL_COORD
ugOled9616int();LcdPutString16_8(0, 0,(void*)“ COORD ”, 12 , 1);
//osal_start_timerEx(SampleApp_TaskID,//SAMPLEAPP_RUN__EVT,//SAMPLEAPP_RUN_TIMEOUT);//启动超时定时器
#endif
#ifdef WXL_RFD
memset(RfTx.TxBuf,'x',32);
RfTx.TXDATA.Head = '&';
RfTx.TXDATA.HeadCom[0] = 'J';
RfTx.TXDATA.HeadCom[1] = 'O';
RfTx.TXDATA.HeadCom[2] = 'N';
ieeeAddr = NLME_GetExtAddr();
memcpy(RfTx.TXDATA.Laddr,ieeeAddr,8);
SrcSaddr = NLME_GetShortAddr();
RfTx.TXDATA.Saddr[0] = SrcSaddr;RfTx.TXDATA.Saddr[1] = SrcSaddr>>8;
RfTx.TXDATA.DataBuf[0] = 'R';
RfTx.TXDATA.DataBuf[1] = 'F';
RfTx.TXDATA.DataBuf[2] = 'D';
NLME_GetCoordExtAddr(&RfTx.TXDATA.DataBuf[3]);temp1 = NLME_GetCoordShortAddr();RfTx.TXDATA.DataBuf[11] =(unsigned char)(temp1>>8);RfTx.TXDATA.DataBuf[12] =(unsigned char)(temp1);
RfTx.TXDATA.DataBuf[13] = SensorNum;
RfTx.TXDATA.LastByte = '*';
SendData(0x0000, RfTx.TxBuf, 32);//发送自己的节点信息到主机
if((SensorNum == 1)||(SensorNum == 2))//点阵屏或数码管屏
{
init_T3();//打开定时器3开始扫描
}
else if(SensorNum == 9)//振动传感器
{
IEN1 |= 0x20;//Port 0 interrupt enable
}
osal_start_timerEx(SampleApp_TaskID,SAMPLEAPP_SEND_PERIODIC_MSG_EVT,SAMPLEAPP_1000MS_TIMEOUT);//每秒检测一次红外传感器 #endif
#ifdef WXL_ROUTER
memset(RfTx.TxBuf,'x',32);
RfTx.TXDATA.Head = '&';
RfTx.TXDATA.HeadCom[0] = 'J';
RfTx.TXDATA.HeadCom[1] = 'O';
RfTx.TXDATA.HeadCom[2] = 'N';
RfTx.TXDATA.Saddr[1] SrcSaddr>>8;
temp1 NLME_GetCoordShortAddr();RfTx.TXDATA.DataBuf[11](unsigned char)(temp1>>8);RfTx.TXDATA.DataBuf[12](unsigned char)(temp1);
RfTx.TXDATA.DataBuf[13] SensorNum;
RfTx.TXDATA.LastByte = '*';
息到主机
if((SensorNum == 2))//点阵屏或数码管屏
ieeeAddr = NLME_GetExtAddr();memcpy(RfTx.TXDATA.Laddr,ieeeAddr,8);SrcSaddr = NLME_GetShortAddr();RfTx.TXDATA.Saddr[0] = SrcSaddr;= RfTx.TXDATA.DataBuf[0] = 'R';RfTx.TXDATA.DataBuf[1] = 'O';RfTx.TXDATA.DataBuf[2] = 'U';NLME_GetCoordExtAddr(&RfTx.TXDATA.DataBuf[3]);= = = = SendData(0x0000, RfTx.TxBuf, 32);//发送自己的节点信== 1)||(SensorNum { init_T3();//打开定时器3开始扫描 } else if(SensorNum == 9)//振动传感器 { IEN1 |= 0x20;//Port 0 interrupt enable }
osal_start_timerEx(SampleApp_TaskID,SAMPLEAPP_SEND_PERIODIC_MSG_EVT,SAMPLEAPP_1000MS_TIMEOUT);//每秒检测一次红外传感器
#endif
}
break;
case SPI_INCOMING_ZTOOL_PORT:
UartRxComCallBack();//串口收到一帖数据的处理
break;
default:
break;
}
// Release the memory
osal_msg_deallocate((uint8 *)MSGpkt);
// NextThis event is generated by a timer //(setup in SampleApp_Init()).if(events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT)//发送数据超时
{
if(SensorNum == 8)
{
if(InfraredInitFlag == 0)//人体红外传感器需要初始化20秒
{
if(++InfraredCount > 20)
{
InfraredInitFlag = 1;
}
}
else
{
if(P0_0 == 1)
{
if(InfraredState == 0)
{
InfraredState = 1;
RfTx.TXDATA.Head = '&';
RfTx.TXDATA.HeadCom[0] = 'A';
RfTx.TXDATA.HeadCom[1] = 'I';
RfTx.TXDATA.HeadCom[2] = 'N';
ieeeAddr = NLME_GetExtAddr();
memcpy(RfTx.TXDATA.Laddr,ieeeAddr,8);
temp1 = NLME_GetShortAddr();
RfTx.TXDATA.Saddr[0] = temp1;
RfTx.TXDATA.Saddr[1] = temp1>>8;
RfTx.TXDATA.LastByte = '*';
SendData(0x0000, RfTx.TxBuf, 32);//发送报警数据
}
}
else
{
InfraredState = 0;
} if(DispState!= 0)//每一秒自动采集一次传感器
{
LCDUPDATA = 1;
}
}
}
else if(SensorNum == 9)//振动传感器
{
if(Shakeflag)
{
Shakeflag = 0;
P0IEN |= 0x01;//Port 0, inputs 0 interrupt enable.P0IFG &= 0xfe;//Clear any pending interrupts
RfTx.TXDATA.Head = '&';
RfTx.TXDATA.HeadCom[0] = 'A';
RfTx.TXDATA.HeadCom[1] = 'S';
RfTx.TXDATA.HeadCom[2] = 'H';
ieeeAddr = NLME_GetExtAddr();
memcpy(RfTx.TXDATA.Laddr,ieeeAddr,8);
temp1 = NLME_GetShortAddr();
RfTx.TXDATA.Saddr[0] = temp1;
RfTx.TXDATA.Saddr[1] = temp1>>8;
RfTx.TXDATA.LastByte = '*';
SendData(0x0000, RfTx.TxBuf, 32);//发送报警数据
BEEPState2 = 2;} if(BEEPState2 == 1){
BEEPState2 = 2;
P1_4 = 1;} else if(BEEPState2 == 2){
BEEPState2 = 1;
P1_4 = 0;} } else if(SensorNum == 16)//霍尔传感器板 { if(P0_0 == 0){
if(HallState == 0)
{
HallState = 1;
RfTx.TXDATA.Head = '&';
RfTx.TXDATA.HeadCom[0] = 'A';
RfTx.TXDATA.HeadCom[1] = 'H';
RfTx.TXDATA.HeadCom[2] = 'A';
ieeeAddr = NLME_GetExtAddr();
memcpy(RfTx.TXDATA.Laddr,ieeeAddr,8);
temp1 = NLME_GetShortAddr();
RfTx.TXDATA.Saddr[0] = temp1;
RfTx.TXDATA.Saddr[1] = temp1>>8;
RfTx.TXDATA.LastByte = '*';
SendData(0x0000, RfTx.TxBuf, 32);//发送报警数据
}
}
else
{
HallState = 0;
}
}
else if(SensorNum == 4)
{
if(DispState!= 0)//每一秒自动采集一次传感器
{
LCDUPDATA = 1;
}
if(BEEPState1 == 1)
{
BEEPState1 = 2;
P1_6 = 1;
}
else if(BEEPState1 == 2)
{
BEEPState1 = 1;
P1_6 = 0;
}
}
else if((SensorNum == 3)||(SensorNum == 5)||(SensorNum == 7)||(SensorNum == 10)||(SensorNum == 11)||(SensorNum == 13))
{
if(DispState!= 0)//每一秒自动采集一次传感器
{
LCDUPDATA = 1;
}
}
LCDDispFun();
// Setup to send message again in normal period(+ a little jitter)
osal_start_timerEx(SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, SAMPLEAPP_1000MS_TIMEOUT);
return(events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);} // Discard unknown events return 0;} void SampleApp_HandleKeys(uint8 shift, uint8 keys){(void)shift;// Intentionally unreferenced parameter
if(keys & HAL_KEY_UP){
P1_1 =!P1_1;
if(++DispState >= 3)DispState = 0;
LCDUPDATA = 1;} if(keys & HAL_KEY_DOWN){
P1_1 =!P1_1;
if(--DispState >= 200)DispState = 2;
LCDUPDATA = 1;} }
/********************************************************************* * LOCAL FUNCTIONS */
/********************************************************************* * @fn SampleApp_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 SampleApp_MessageMSGCB(afIncomingMSGPacket_t *pkt){ #ifdef WXL_COORD uint8 i;
memcpy(RfRx.RxBuf,pkt->cmd.Data,32);//读出无线按收到的数据
osal_stop_timerEx(SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT);//停止超时计数器
if((RfRx.RXDATA.Head == '&')&&(RfRx.RXDATA.LastByte == '*')){
memcpy(UartTxBuf.TxBuf,RfRx.RxBuf,32);
for(i=0;i<8;i++)
{
UartTxBuf.TXDATA.Laddr[i] = RfRx.RXDATA.Laddr[i];//长地址
}
for(i=0;i<2;i++)
{
UartTxBuf.TXDATA.Saddr[i] = RfRx.RXDATA.Saddr[1-i];//短地址
}
UartTxBuf.TXDATA.CRC = CheckUartData(&UartTxBuf.TxBuf[1],29);
HalUARTWrite(HAL_UART_PORT_0, UartTxBuf.TxBuf, 32);//从串口输出
} #endif
#if(defined(WXL_ROUTER)|| defined(WXL_RFD))//ROUTER OR RFD uint8 temp;uint16 temp1,temp2;uint8 RfHaveTxDara = 0;//无线有数据需要发送
ieeeAddr = NLME_GetExtAddr();memcpy(RfRx.RxBuf,pkt->cmd.Data,32);memset(RfTx.TxBuf,'x',32);switch(RfRx.RXDATA.HeadCom[0]){
case 'R'://读
if((RfRx.RXDATA.HeadCom[1] == 'A')&&(RfRx.RXDATA.HeadCom[2] 'S'))//读传感器
{
if(SensorNum == 4)//高精温湿度传感器
{
==
memcpy(RfTx.TxBuf, RfRx.RxBuf, 16);
if((RfRx.RXDATA.DataBuf[0] == 'G')&&(RfRx.RXDATA.DataBuf[1] == 'M'))//读光敏
{
temp = ReadSensorAdc(1);//显示值转换
RfTx.TXDATA.DataBuf[2] = temp/100 + 0x30;
temp = temp%100;
RfTx.TXDATA.DataBuf[3] = temp/10 + 0x30;
RfTx.TXDATA.DataBuf[4] = temp%10 + 0x30;
RfHaveTxDara = 1;;
}
else if((RfRx.RXDATA.DataBuf[0] == 'W')&&(RfRx.RXDATA.DataBuf[1] == 'D'))//读温度
{ //WriteTc77(1);//唤醒温度传感器
//Sensor_Delay(10000);//必须延时后才能读
temp = ReadTc77();//读取温度
//WriteTc77(0);//温度传感器休眠
//显示值转换
RfTx.TXDATA.DataBuf[2] = temp/10 + 0x30;
RfTx.TXDATA.DataBuf[3] = temp%10 + 0x30;
RfHaveTxDara = 1;
}
}
}
else if((RfRx.RXDATA.HeadCom[1] == 'S')&&(RfRx.RXDATA.HeadCom[2] == 'H'))//读取高精温湿度传感器
{ // 读取的温湿度为16位浮点数,在上位机上转换。if(SensorNum == 3)//高精温湿度传感器 { memcpy(RfTx.TxBuf, RfRx.RxBuf, 16);SHT1X_INT();if((RfRx.RXDATA.DataBuf[0] == 'W')&&(RfRx.RXDATA.DataBuf[1] == 'D'))
{
temp1 = Read_SHT1X(3);
RfTx.TXDATA.DataBuf[2] =(uint8)(temp1>>8);
RfTx.TXDATA.DataBuf[3] =(uint8)(temp1&0xff);
RfHaveTxDara = 1;
}
else if((RfRx.RXDATA.DataBuf[0] == 'S')&&(RfRx.RXDATA.DataBuf[1] == 'D'))
{
temp1 = Read_SHT1X(5);
RfTx.TXDATA.DataBuf[2] =(uint8)(temp1>>8);
RfTx.TXDATA.DataBuf[3] =(uint8)(temp1&0xff);
RfHaveTxDara = 1;
}
}
}
else if((RfRx.RXDATA.HeadCom[1] == 'P')&&(RfRx.RXDATA.HeadCom[2] == 'R'))//压力传感器
{ if(SensorNum == 5)//压力传感器板 {
memcpy(RfTx.TxBuf, RfRx.RxBuf, 14);
temp = ReadSensorAdc(0);
RfTx.TXDATA.DataBuf[0] = temp/100 + 0x30;
temp = temp%100;
RfTx.TXDATA.DataBuf[1] = temp/10 + 0x30;
RfTx.TXDATA.DataBuf[2] = temp%10 + 0x30;
RfHaveTxDara = 1;} }
else if((RfRx.RXDATA.HeadCom[1] == 'R')&&(RfRx.RXDATA.HeadCom[2] == 'A'))//雨滴传感器
{ if(SensorNum == 7)//雨滴传感器板 {
memcpy(RfTx.TxBuf, RfRx.RxBuf, 14);
temp = ReadSensorAdc(0);
RfTx.TXDATA.DataBuf[0] = temp/100 + 0x30;
temp = temp%100;
RfTx.TXDATA.DataBuf[1] = temp/10 + 0x30;
RfTx.TXDATA.DataBuf[2] = temp%10 + 0x30;
RfHaveTxDara = 1;} } else if((RfRx.RXDATA.HeadCom[1] == 'A')&&(RfRx.RXDATA.HeadCom[2] == 'D'))//控制加速度传感器
{
if(SensorNum == 10)//加速度传感器板 { //P1_4 = 1;if(RfRx.RXDATA.DataBuf[0] == 'X')
{
temp = ReadSensorAdc(XOUT);
}
else if(RfRx.RXDATA.DataBuf[0] == 'Y')
{
temp = ReadSensorAdc(YOUT);
} else if(RfRx.RXDATA.DataBuf[0] == 'Z')
{
temp = ReadSensorAdc(ZOUT);
}
//P1_4 = 0;
memcpy(RfTx.TxBuf, RfRx.RxBuf, 15);RfTx.TXDATA.DataBuf[1] = temp/100 + 0x30;
temp = temp%100;
RfTx.TXDATA.DataBuf[2] = temp/10 + 0x30;
RfTx.TXDATA.DataBuf[3] = temp%10 + 0x30;
RfHaveTxDara = 1;
}
}//end
else if((RfRx.RXDATA.HeadCom[1] == 'G')&&(RfRx.RXDATA.HeadCom[2] == 'A'))//可燃气体传感器 { if(SensorNum == 11)//可燃气体传感器板 {
memcpy(RfTx.TxBuf, RfRx.RxBuf, 14);
temp = ReadSensorAdc(0);
RfTx.TXDATA.DataBuf[0] = temp/100 + 0x30;
temp = temp%100;
RfTx.TXDATA.DataBuf[1] = temp/10 + 0x30;
RfTx.TXDATA.DataBuf[2] = temp%10 + 0x30;
RfHaveTxDara = 1;} } else if((RfRx.RXDATA.HeadCom[1] == 'U')&&(RfRx.RXDATA.HeadCom[2] == 'L'))//超声波传感器 { if(SensorNum == 14)//超声波传感器板 {
memcpy(RfTx.TxBuf, RfRx.RxBuf, 14);
P1_4 = 1;
WaitUs(20);
P1_4 = 0;
Ultrasonic_Count = 0;
while(!P0_0)//等待返回高电平 {
WaitUs(20);
if((++Ultrasonic_Count)>= 1000)//超时自动退出
{
break;
} }
Ultrasonic_Count = 0;while(P0_0)
{
WaitUs(20);
Ultrasonic_Count++;
if(Ultrasonic_Count >= 600)//超时退出
{
Ultrasonic_Count = 0;
break;
}
}
temp1 = Ultrasonic_Count;
if((temp1 > 1)&&(temp1 <550)){
RfTx.TXDATA.DataBuf[0] = temp1/100 + 0x30;
temp = temp1%100;
RfTx.TXDATA.DataBuf[1] = temp/10 + 0x30;
RfTx.TXDATA.DataBuf[2] = temp%10 + 0x30;
}
else
{
RfTx.TXDATA.DataBuf[0] = 'E';
RfTx.TXDATA.DataBuf[1] = '0';
}
RfHaveTxDara = 1;} }
else if((RfRx.RXDATA.HeadCom[1] == 'N')&&(RfRx.RXDATA.HeadCom[2] == 'S'))//读模块连接状态
{
memcpy(RfTx.TxBuf, RfRx.RxBuf, 14);
temp = pkt->LinkQuality;
RfTx.TXDATA.DataBuf[0] = temp/100 + 0x30;temp %= 100;RfTx.TXDATA.DataBuf[1] = temp/10 + 0x30;RfTx.TXDATA.DataBuf[2] = temp%10 + 0x30;NLME_GetCoordExtAddr(&RfTx.TXDATA.DataBuf[3]);temp1 = NLME_GetCoordShortAddr();RfTx.TXDATA.DataBuf[11] =(INT8U)(temp1>>8);RfTx.TXDATA.DataBuf[12] =(INT8U)(temp1);
RfHaveTxDara = 1;
}//end 读模块连接状态 break;
case 'T'://测试
if((RfRx.RXDATA.HeadCom[1] == 'L')&&(RfRx.RXDATA.HeadCom[2] == 'D'))//LED测试
{
if(RfRx.RXDATA.DataBuf[0] == 'C')
{
if((RfRx.RXDATA.DataBuf[1] == 'D')&&(RfRx.RXDATA.DataBuf[2] == '1'))
{
if(RfRx.RXDATA.DataBuf[3] == '1')
{
HalLedSet(HAL_LED_1, HAL_LED_MODE_ON);//开
}
else if(RfRx.RXDATA.DataBuf[3] == '0')
{
HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF);//关
}
}
else if((RfRx.RXDATA.DataBuf[1] == 'D')&&(RfRx.RXDATA.DataBuf[2] == '2'))
{
if(RfRx.RXDATA.DataBuf[3] == '1')
{
HalLedSet(HAL_LED_2, HAL_LED_MODE_ON);//开
}
else if(RfRx.RXDATA.DataBuf[3] == '0')
{
HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF);//关
}
}
} else if(RfRx.RXDATA.DataBuf[0] == 'T'){ if((RfRx.RXDATA.DataBuf[1] == 'D')&&(RfRx.RXDATA.DataBuf[2] == '1'))//控制LED1
{
if(RfRx.RXDATA.DataBuf[3] == '1')
{ HalLedSet(HAL_LED_1, HAL_LED_MODE_FLASH);
}
else if(RfRx.RXDATA.DataBuf[3] == '0')
{ HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF);
}
}
else if((RfRx.RXDATA.DataBuf[1] == 'D')&&(RfRx.RXDATA.DataBuf[2] == '2'))//控制LED2
{ if(RfRx.RXDATA.DataBuf[3] == '1')
{ HalLedSet(HAL_LED_2, HAL_LED_MODE_FLASH);
}
else if(RfRx.RXDATA.DataBuf[3] == '0')
{ HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF);
}
}
}
memcpy(RfTx.TxBuf, RfRx.RxBuf, 14);
RfTx.TXDATA.DataBuf[0] = 'O';
RfTx.TXDATA.DataBuf[1] = 'K';
RfHaveTxDara = 1;
}//end LED测试
else if((RfRx.RXDATA.HeadCom[1] == 'D')&&(RfRx.RXDATA.HeadCom[2] == 'A'))//
{
if(SensorNum == 12)//DAC输出 { temp1 = RfRx.RXDATA.DataBuf[0];temp1 <<= 8;temp1 += RfRx.RXDATA.DataBuf[1];
temp2 = RfRx.RXDATA.DataBuf[2];temp2 <<= 8;temp2 += RfRx.RXDATA.DataBuf[3];
DAC_OUT_CON(temp1, temp2);
memcpy(RfTx.TxBuf, RfRx.RxBuf, 14);
RfTx.TXDATA.DataBuf[0] = 'O';
RfTx.TXDATA.DataBuf[1] = 'K';
RfHaveTxDara = 1;}
}//end DAC_OUT测试
else if((RfRx.RXDATA.HeadCom[1] == 'M')&&(RfRx.RXDATA.HeadCom[2] == 'O'))//
{
if(SensorNum == 15)//电机测试 {
if((RfRx.RXDATA.DataBuf[0] == 'M')&&(RfRx.RXDATA.DataBuf[1] == '1'))
{
if(RfRx.RXDATA.DataBuf[2] == '0')//停止
{
MOTOR_Con(1, 0x8F);
}
else if(RfRx.RXDATA.DataBuf[2] == '1')//正转
{
MOTOR_Con(1, 0x80);
}
else if(RfRx.RXDATA.DataBuf[2] == '2')//反转
{
MOTOR_Con(1, 0x88);
}
}
else if((RfRx.RXDATA.DataBuf[0] == 'M')&&(RfRx.RXDATA.DataBuf[1] == '2'))
{
if(RfRx.RXDATA.DataBuf[2] == '0')//停止
{
MOTOR_Con(2, 0x8F);
}
else if(RfRx.RXDATA.DataBuf[2] == '1')//正转
{
MOTOR_Con(2, 0x80);
}
else if(RfRx.RXDATA.DataBuf[2] == '2')//反转
{
MOTOR_Con(2, 0x88);
}
}
memcpy(RfTx.TxBuf, RfRx.RxBuf, 14);
RfTx.TXDATA.DataBuf[0] = 'O';
RfTx.TXDATA.DataBuf[1] = 'K';
RfHaveTxDara = 1;
}
}//end MOTOR电机测试
else if((RfRx.RXDATA.HeadCom[1] == 'E')&&(RfRx.RXDATA.HeadCom[2] == 'D'))//点阵屏测试
{
if(SensorNum == 1)//点阵屏板 {
memcpy(RfTx.TxBuf, RfRx.RxBuf, 14);
if((RfRx.RXDATA.DataBuf[0] >= '0')&&(RfRx.RXDATA.DataBuf[0] <= '9')){
LCDUPDATA = 1;
DispNum = RfRx.RXDATA.DataBuf[0]-0x30;
RfTx.TXDATA.DataBuf[0] = 'O';
RfTx.TXDATA.DataBuf[1] = 'K';} else {
RfTx.TXDATA.DataBuf[0] = 'E';
RfTx.TXDATA.DataBuf[1] = '0';
} RfHaveTxDara = 1;} } else if((RfRx.RXDATA.HeadCom[1](RfRx.RXDATA.HeadCom[2] == 'U'))//数码管屏测试
{
if(SensorNum == 2)//数码管屏板 {
memcpy(RfTx.TxBuf, RfRx.RxBuf, 14);
temp1 = RfRx.RXDATA.DataBuf[0];
temp1 <<= 8;
temp1 += RfRx.RXDATA.DataBuf[1];
if(temp1 <= 9999)
{
LEDDispNum = temp1;
LEDDISPFUN();//显示数据
LCDUPDATA = 1;
RfTx.TXDATA.DataBuf[0] = 'O';
RfTx.TXDATA.DataBuf[1] = 'K';
}
else
{
RfTx.TXDATA.DataBuf[0] = 'E';
RfTx.TXDATA.DataBuf[1] = '0';
} RfHaveTxDara = 1;}
== 'N')&& }
else if((RfRx.RXDATA.HeadCom[1] == 'B')&&(RfRx.RXDATA.HeadCom[2] == 'L'))//测试电池电压
{
memcpy(RfTx.TxBuf, RfRx.RxBuf, 14);
temp = ReadSensorAdc(4);
RfTx.TXDATA.DataBuf[0] = temp;
RfHaveTxDara = 1;
} else if((RfRx.RXDATA.HeadCom[1] == 'B')(RfRx.RXDATA.HeadCom[2] == 'E'))//测试蜂鸣器
{
if((SensorNum == 4)||(SensorNum == 9))
{
memcpy(RfTx.TxBuf, RfRx.RxBuf, 14);
if(RfRx.RXDATA.DataBuf[0] == '1'){
if(SensorNum == 4)
{
BEEPState1 = 2;
}
else
{
BEEPState2 = 2;
} }
else if(RfRx.RXDATA.DataBuf[0] == '0'){
if(SensorNum == 4)
{
BEEPState1 = 0;
P1_6 = 1;
}
else
{
BEEPState2 = 0;
P1_4 = 1;
} }
&&
RfTx.TXDATA.DataBuf[0] = 'O';
RfTx.TXDATA.DataBuf[1] = 'K';
RfHaveTxDara = 1;
}
} else if((RfRx.RXDATA.HeadCom[1] == 'R')&&(RfRx.RXDATA.HeadCom[2] == 'E'))//控制继电器
{
if(SensorNum == 6)//继电器板
{
if((RfRx.RXDATA.DataBuf[0] == 'K')&&(RfRx.RXDATA.DataBuf[1] == '1'))
{
if(RfRx.RXDATA.DataBuf[2] == '1')
{
Relay1State = 1;
P1_4 = 1;
}
else if(RfRx.RXDATA.DataBuf[2] == '0')
{
Relay1State = 0;
P1_4 = 0;
}
}
else if((RfRx.RXDATA.DataBuf[0] == 'K')&&(RfRx.RXDATA.DataBuf[1] == '2'))
{
if(RfRx.RXDATA.DataBuf[2] == '1')
{
Relay2State = 1;
P1_5 = 1;
}
else if(RfRx.RXDATA.DataBuf[2] == '0')
{
Relay2State = 0;
P1_5 = 0;
}
}
memcpy(RfTx.TxBuf, RfRx.RxBuf, 14);
RfTx.TXDATA.DataBuf[0] = 'O';
RfTx.TXDATA.DataBuf[1] = 'K';
RfHaveTxDara = 1;
}
}//end 控制继电器
else if((RfRx.RXDATA.HeadCom[1] == 'L')&&(RfRx.RXDATA.HeadCom[2] == 'L'))//控制高亮LED
{
if(SensorNum == 17)//高亮LED板
{
memcpy(RfTx.TxBuf, RfRx.RxBuf, 14);
ChangT3Cmp0Val(RfRx.RXDATA.DataBuf[0]);
RfTx.TXDATA.DataBuf[0] = 'O';
RfTx.TXDATA.DataBuf[1] = 'K';
RfHaveTxDara = 1;
}
}//end 控制高亮LED
break;
}//end if(RfHaveTxDara)//如果有数据要发送
{
RfTx.TXDATA.Head = '&';
RfTx.TXDATA.LastByte = '*';
SendData(0x0000, RfTx.TxBuf, 32);//发送数据
RfHaveTxDara = 0;} #endif } 4.实验总结
主要是通过组网来使协调器与终端器进行数据的交流与反馈,当LED灯显示时,LED显示屏也会显示相应状态,进行信息反馈。
第三篇:无线传感网络学习心得
无线传感器网络学习心得
初次接触这个课程时,我无意地在课本中看到了对于无线传感器网络的基本概述:无线传感器网络是一种全新的信息获取平台,能够实时监测和采集网络分布区域内各种检测对象的信息,并将这些信息发送到网关节点,以实现复杂的指定范围内目标检测与跟踪。这让我联想到物联网体系的感知层与网络层,乍一想,这不就是物联网感知层与网络层的整体解决方案么?美国《商业周刊》与MIT技术评论分别将无线传感器网络列为改变世界的10大技术之一。作为一名物联网工程专业的大学生,了解于此,内心燃起了一团火焰,因为觉得这个将成为我们将以时代推动者的身份参与到人类21世纪的建设中。
学习无线传感器网络这个课程,分3个阶段,第一个阶段是分别讲解无线传感器网络里面的各个组成部分,包括物理层,信道接入技术,路由协议,拓扑技术,网络定位与时间同步技术等等。第二个阶段是整合零碎的知识,总结出无线传感器网络的工作原理。第三阶段是利用现有知识理解无线传感器网络在物联网环境下的应用并且能够根据现实需求设计出符合要求的一个整体的无线传感器网络。
第一阶段知识总结,(1)无线传感器网络物理层是数据传输的最底层,它需要考虑编码调制技术,通信速率,通信频段等问题。信道接入技术中有IEEE 802.11MAC协议,S-MAC协议,Sift协议,TDMA技术,DMAC技术,CDMA技术。在物理层和信道接入技术主要有2个标准,一个是IEEE 802.15.4标准,一个是ZigBee标准,它们各有优劣,可根据现实情况采用不同标准。(2)无线传感器网络路由协议的作用是寻找一条或或多条满足一定条件的,从源节点到目的节点的路径,将数据分组沿着所寻找的路径进行转发。路由协议中有Flooding协议,Gossiping协议,SPIN协议,DD协议,Rumor协议,SAR协议,LEACH协议,PEGASIS协议等协议。(3)动态变化的拓扑结构是无线传感器网络最大特点之一,拓扑控制策略为路由协议、MAC协议、数据融合、时间同步和目标定位等多方面都奠定了基础。在无线传感器网络中,拓扑控制将影响整个网络的生存时间,减小节点间通信干扰,提高网络通信效率,为路由协议与时间同步提供基础,影响数据融合与弥补节点失效的影响。(4)无线传感器网络主要有两种基本感知模型,而这又跟覆盖问题直接相关。根据无线传感器网络不同的应用,覆盖需求通常不同。根据覆盖目标不同,目前覆盖算法可以分为面覆盖,点覆盖及栅栏覆盖。(5)无线传感器网络的定位是指自组织的网络通过特定方法提供节点位置信息。这种自组织网络定位分为节点自身定位和目标定位。节点自身定位是确定网络中节点的坐标位置的过程。目标定位是确定网络覆盖范围内目标的坐标位置。定位过程中把定位算法分为基于测距和无需测距的定位算法。基于测距的定位算法需要测量相邻节点之间的绝对距离或者访方位,并利用节点间的实际距离或者方位来计算位置节点的位置,常用的测距技术用RSS(到达信号强度)测量法,TOA(到达时间)测量法,TDOA(到达时间差)测量法,RSSI(到达信号强度)测量法等。(6)无线传感器网络上的目标跟踪与其定位不同,主要目的不是追求定位的精度,而是需要对移动的目标或者时间进行动态的监测。基于无线传感器网络的目标跟踪过程大致包括3个阶段:检测、定位和通告。检测阶段:无线传感器网络中的节点周期性地通过传感器模块检测是否有目标出现。定位阶段:为了节省能量,只有距离跟踪目标比较近的节点才会对目标进行定位,如果节点接受到另外两个或者两个以上的节点到跟踪目标的距离,则可选用三边定位法或者多边极大似然估计法计算跟踪目标的位置。通告阶段:计算出跟踪跟踪目标的运动轨迹后,传感器网络要通知跟踪目标周围的节点启动进入跟踪状态。(7)无线传感器网络中的时间同步技术有两大时间同步模型,时钟模型与通信模型。时间同步协议中有经典的LTS协议,RBS协议,TPSN协议,DMTS协议和FTSP协议等协议。(8)在无线传感器网络中间件应用中,无线传感器网络中间件体系结构是无线传感器网络中间件的核心,它决定着无线传感器网络的运行及组织方式。(9)传感器网络以数据中心的特点使得其设计方法不不同于其他计算机网络,传感器网络应用系统的设计以感知数据管理和处理为中心,把数据库技术和网络技术紧密结合,从逻辑概念和软、硬件技术两个方面实现一个高性能的以数据为中心的网络系统。(10)无线传感器网络数据不能局限于网络内部传输,这样不利于无线传感器网络的普及应用,必须让终端用户能够通过外部网络(如Internet)便捷地访问无线传感器网络采集的环境数据。这就需要物联网环境下的无线传感器网络接入技术了。多网融合的无线传感器网络是在传统的无线传感器网络的基础上,利用网关接入技术,实现无线传感器网络与以太网、无线局域网、移动通信网等多种网络的融合。处于特定应用场景中的、高效组织组织的节点,在一定的网络调度与控制策略驱动下,对其所部属的区域开展监控与传感;网关节点设备将实现对其所在的无线传感器网络的区域管理、任务调度、数据聚合、状态监控与维护等一系列功能。经网关节点融合、处理并经过相应的标准化协议处理和数据转换之后的无线传感器网络信息数据,将有网关节点设备聚合,根据其不同的业务需求及所接入的不同网络环境,经由TD-SCDMA和GSM系统下的地面无线接入网、Internet环境下的网络通路及无线局域网网络下的无线链路接入点等,分别接入TD-SCDMA与GSM核心网、Internet主干网及无线局域网等多类型异构网络,并通过各网络下的基站或主控设备,将传感信息分发至各终端,以实现针对无线传感器网络的多网远程监控与调度。(11)无线传感器网络具有很强的应用相关性,起硬件需要满足轻量化、扩展性、灵活性、稳定性、安全性与低成本等要求。
学习的第二个阶段,对零碎的知识点进行整合,总结出对无线传感的工作原理的自我理解。
上图就是一个典型的无线传感器网络应用系统的简易示意图,它拥有着无线传感器网络所应该拥有的最基本的三种类型的节点,即传感器节点(sensor node),汇聚节点(sink),用户的管理节点(User)以及互联网或通信卫星。传感器节点(sensor node)分布于监测区域的各个部分(sensor field),用于收集数据,并且将数据路由至信息收集节点(sink),信息收集节点(sink)与信息处理中心(User)通过广域网络进行通信,从而对收集到的数据进行处理。
学习的第三阶段:利用现有的知识体系,理解无线传感器网络在现实中的应用,并且可以根据现实的需求设计出合理的应用体系。结合无线传感器网络在农业中的应用进行探究:(1)在体系结构选择方面,其体系结构选择通性化的网络体系结构,跟上图体系相符。(2)节点选择方面,由于农业监测的复杂性及监测环境对于外来设备的敏感性,要求传感器节点体积尽可能小,为了获取到确切的监测信息,要求传感器节点装备多种高精度传感器。为了延长传感网的使用寿命,需要传感器节点具有尽可能长的生命周期。(3)能量管理:实际情况下的传感器网络应用可能需要长达多个月的环境监控,而单个节点的能量非常有限。为了节省能量,在发生传感任务时,只有相邻区域的节点处于传感通信状态,其余节点不需要传感和转发数据包,应当关闭无线通信系统,使其休眠节省能量。(4)数据采集方面,在无线传感器网络中,靠近基站的节点要为其他节点转发数据,能量消耗较大,边缘节点只要进行数据收集,能耗较少,所以边缘节点应当采取一定的算法对数据进行融合,降低通信量,校正采样数据之后再进行发送。(5)通信机制方面,包括路由协议、MAC协议及通信部件的控制访问机制等,路由协议负责将数据分组从源节点通过网络发送到目的节点,寻找源节点和优化节点间的路径,将数据分组沿优化的路径正确转发。MAC协议决定无线信道的使用方式,在节点间分配有限的通信资源,无线通信模块在发送状态消耗能量最多,睡眠状态消耗最少,接受和侦听状态下消耗稍小于发送状态(6)远程任务控制主要是在对环境监控一段时间后,调整网络的任务,这需要向基站发出命令,基站通过发送广播消息发出指令,还要对节点的能量、通信等状态进行监控,不断进行任务调整,延长传感器网络的使用寿命。
根据现实的需求设计出合理的应用体系分这几步:(1)根据客户的要求,分析现实的需求,书写需求文档。(2)设计出无线传感器网络的整体框架体系,选择与设计各项通信协议与通信机制。(3)分别对框架中的软硬件进行分析与设计(4)进入开发状态(5)测试,交付,维护
以上就是我对无线传感器网络课程的学习心得了,在此课程中,虽然我对其中的知识体系有所了解,但是缺少实际的操作与开发,只是停留在了浅显的认识层面,只有通过实际的操作,才能更深入地去了解它其中的核心,而这一点却恰恰是我们这个课程的学生所缺少的,基于此,我非常地希望在这个专业、这个课程中,有专业的实验室让我们这群学生能够进行实打实的器械操作,这样才能真正地达到“格物致知”,“学为实用”啊。
第四篇:无线传感网络研究应用
无线传感网络研究应用
应用前景
无线传感网络是面向应用的,贴近客观物理世界的网络系统,其产生和发展一直都与应用相联系。多年来经过不同领域研究人员的演绎,无线传感网络技术在军事领域、精细农业、安全监控、环保监测、建筑领域、医疗监护、工业监控、智能交通、物流管理、自由空间探索、智能家居等领域的应用得到了充分的肯定和展示。
在环境监控和精细农业方面,WSN系统最为广泛。2002年,英特尔公司率先在俄勒冈建立了世界上第一个无线葡萄园,这是一个典型的精准农业、智能耕种的实例。杭州齐格科技有限公司与浙江农科院合作研发了远程农作管理决策服务平台,该平台利用了无线传感器技术实现对农田温室大棚温度、湿度、露点、光照等环境信息的监测。
在民用安全监控方面,英国的一家博物馆利用无线传感器网络设计了一个报警系统,他们将节点放在珍贵文物或艺术品的底部或背面,通过侦测灯光的亮度改变和振动情况,来判断展览品的安全状态。中科院计算所在故宫博物院实施的文物安全监控系统也是WSN技术在民用安防领域中的典型应用。
现代建筑的发展不仅要求为人们提供更加舒适、安全的房屋和桥梁,而且希望建筑本身能够对自身的健康状况进行评估。WSN技术在建筑结构健康监控方面将发挥重要作用。2004年,哈工大在深圳地王大厦实施部署了监测环境噪声和震动加速度响应测试的WSN网络系统。
在医疗监控方面,美国英特尔公司目前正在研制家庭护理的无线传感器网络系统,作为美国“应对老龄化社会技术项目”的一项重要内容。另外,在对特殊医院(精神类或残障类)中病人的位置监控方面,WSN也有巨大应用潜力。
在工业监控方面,美国英特尔公司为俄勒冈的一家芯片制造厂安装了200台无线传感器,用来监控部分工厂设备的振动情况,并在测量结果超出规定时提供监测报告。西安成峰公司与陕西天和集团合作开发了矿井环境监测系统和矿工井下区段定位系统。
在智能交通方面,美国交通部提出了“国家智能交通系统项目规划”,预计到2025年全面投入使用。该系统综合运用大量传感器网络,配合GPS系统、区域网络系统等资源,实现对交通车辆的优化调度,并为个体交通推荐实时的、最佳的行车路线服务。目前在美国的宾夕法尼亚州的匹兹堡市已经建有这样的智能交通信息系统。
无线传感网络应用前景广阔,特别是我国西部地区的一些山区,需要对山地滑坡、泥石流、大桥位移、景区环境监测,但是无线传感器网络的生存时间却要求长达数月甚至数年,因此,如何在不影响功能的前提下,尽可能节约无线传感器网络的电池能量成为无线传感器网络软硬件设计中的核心问题,也是当前国内外研究机构关注的焦点。本文研究基于分布式压缩感知算法的无线传感网络节能模型研究,用以降低无线传感网络的耗电量,具有极高的应用价值。
第五篇:无线传感网实验报告
Central South University
无线传感器网络 实验报告
学院:
班级: 学号: 姓名:
时间: 指导老师:
第一章 基础实验
了解环境
1.1 实验目的
安装 IAR 开发环境。CC2530 工程文件创建及配置。源代码创建,编译及下载。1.2 实验设备及工具
硬件:ZX2530A 型底板及 CC2530 节点板一块,USB 接口仿真器,PC 机
软件:PC 机操作系统 WinXP,IAR 集成开发环境,TI 公司的烧写软件。
1.3 实验内容
1、安装 IAR 集成开发环境
IAR 集成开发环境安装文件所在光盘目录:物联网光盘工具CD-EW8051-7601
2、ZIBGEE 硬件连接
安装完 IAR 和 Smartrf Flash Programmer 之后,按照图所示方式连接各种硬件,将仿真器的 20 芯 JTAG 口连接到 ZX2530A 型 CC2530 节点板上,USB 连接到 PC 机上,RS-232 串口线一端连接 ZX2530A 型 CC2530 节点板,另一端连接 PC 机串口。
3、创建并配置 CC2530 的工程文件 IAR 是一个强大的嵌入式开发平台,支持非常多种类的芯片。IAR 中的每一个 Project,都可以拥有自己的配置,具体包括 Device 类型、堆/栈、Linker、Debugger 等。(1)新建 Workspace 和 Project 首先新建文件夹 ledtest。打开 IAR,选择主菜单 File-> New-> Workspace 建立新的工作区域。
选择 Project-> Create New Project-> Empty Project,点击 OK,把此工程文件保存到文件夹 ledtest 中,命名为:ledtest.ewp(如下图)。
(2)配置 Ledtest 工程
选择菜单 Project->Options...打开如下工程配置对话框
选择项 General Options,配置 Target 如下 Device:CC2530;
(3)Stack/Heap 设置:XDATA stack size:0x1FF
(4)Debugger 设置:
Driver:Texas Instruments(本实验为真机调试,所以选择 TI;若其他程序要使用 IAR仿真器,可选 Simulator)
至此,针对本实验的 IAR 配置基本结束.4、编写程序代码并添加至工程
选择菜单 File->New->File 创建一个文件,选择 File->Save 保存为 main.c 将 main.c 加入到 ledtest 工程,将实验代码输入
然后选择 Project->Rebuild All 编译工程
编译好后,选择 Project->Download and debug 下载并调试程序 下载完后,如果不想调试程序,可点工具栏上的按钮终止调试。
到此,程序已经下载到了 cc2530 芯片的 flash 内,按下 ZX2530A 上的复位按钮可看到程序的运行效果。
LED 实验 2.1 实验目的
通过 I/O 控制小灯闪烁的过程。
在 ZX2530A 型 CC2530 节点板上运行自己的程序。2.2 实验设备及工具
硬件:ZX2530A 型底板及 CC2530 节点板一块,USB 接口仿真器,PC 机
软件:PC 机操作系统 WinXP,IAR 集成开发环境。2.3 实验结果
1.正确连接下载线和 ZX2530A 型 CC2530 节点板,打开 ZX2530A 型 CC2530 节点板电源。
2.在文件夹“基础实验2 LED”下打开工程 led,编译工程,并下载到 CC2530 节点板。3.观察 LED 的闪烁情况。
4.修改延时函数,可以改变 LED 小灯的闪烁间隔时间。
5.重新编译,并下载程序到 CC2530 节点板,观察 LED 的闪烁情况。
答:增加延时就会发现小灯闪烁的频率降低了。
串口实验 3.1 实验目的
本次实验将会学习如果使用串口实现与 PC 机的通讯。(实验中需要 PC 机与开发板之间使用RS232 交叉串口连接线)。
能正确配置 CC2530 的串口。3.2 实验设备及工具
硬件:ZX2530A 型底板及 CC2530 节点板一块,USB 接口仿真器,PC 机,交叉串口线一根。
软件:PC 机操作系统 WinXP,IAR 集成开发环境、串口调试助手。3.3 实验结果
CC2530 能与上位机通过串口正常通信
1.正确连接下载线和 ZX2530A 型 CC2530 节点板,用串口线正确连接上位机和 ZX2530A 型板,使能通过串口交换数据。
2.在文件夹“基础实验5 uart”下打开工程 uart,编译工程,并下载到 CC2530 节点板。
3.通过上位机上的串口调试助手,发送数据到 cc2530,然后检查 cc2530 回送给上位机的数据。
3.4 实验总结
通过这次实验,让我对无线传感器网络有了进一步的了解。在无线的世界,感觉一切都是那么神奇,二一切又是那么理所当然,记得小时候常常想,那些无线好神秘,画面,声音等怎么可以从一方到达另一方而可以完全不接触。虽然今天做的实验都是很小很简单的,比起显示中那些绚丽的感觉没什么值得赞扬的,但对于我来说,这个更有魅力,那些绚丽的我是以仰望的视角来对待,而这次我能深入它的原理去真正接触它,以平视来看待它。
第二章 射频实验
点对点射频通信实验 1 实验目的
在 ZX2530A 型 CC2530 节点板上运行相应实验程序。熟悉通过射频通信的基本方法。练习使用状态机实现收发功能。2 实验内容
接收节点上电后进行初始化,然后通过指令 ISRXON 开启射频接收器,等待接收数据,直到正确接收到数据为止,通过串口打印输出。发送节点上电后和接收节点进行相同的初始化,然后将要发送的数据输出到 TXFIFO 中,再调用指令 ISTXONCCA 通过射频前端发送数据。3 实验设备及工具
硬件:ZX2530A 型 CC2530 节点板 2 块、USB 接口的仿真器,PC 机 Pentium100 以上。
软件:PC 机操作系统 WinXP、IAR 集成开发环境、串口监控程序。4 实验原理
发送节点通过串口接收用户的输入数据然后通过射频模块发送到指定的接收节点,接收节点通过射频模块收到数据后,通过串口发送到 pc 在串口调试助手中显示出来。如果发送节点发送的数据目的地址与接收节点的地址不匹配,接收节点将接收不到数据。以下为发送节点程序流程图:
以下为接收节点流程图: 实验步骤
1.打开光盘“无线射频实验2.点对点通信”双击 p2p.eww 打开本实验工程文件。2.打开 main.c 文件下面对一些定义进行介绍 RF_CHANNEL 此宏定义了无线射频通信时使用的信道,在多个小组同时进行实验是建议每组选择不同时信道。但同一组实验中两个节点需要保证在同一信道,才能正确通信。
PAN_ID 个域网 ID 标示,用来表示不同在网络,在同一实验中,接收和发送节点需要配置为相同的值,否则两个节点将不能正常通信。SEND_ADDR 发送节点的地址 RECV_ADDR 接收节点的地址
NODE_TYPE 节点类型:0 接收节点,1:发送节点,在进行实验时一个节点定义为发送节点用来发送数据,一个定义为接收节点用来接收数据。
3.修改 NODE_TYPE 的值为 0,并编译下载到节点板。此节以下称为接收节点。
4.修改 NODE_TYPE 的值为 1,并编译下载到另外一个节点板。此节点板以下称为发送节点。
5.将接收节点的串口与 pc 的串口相连,并在 pc 端打开串口调试助手,配置波特率为 115200。
6.先将接收节点上电,然后将发送节点上电。7.从串口调试助手观察接收节点收到的数据。
8.修改发送数据的内容,然后编译并下载程序到发送节点,然后从串口调试助手观察收到的数据。9.修改接收节点的地址,然后重新编译并下载程序到接收节点,然后从发送节点发送数据观察接收节点能否正确接收数据。6 实验数据分析及结论
发送节点将数据发送出去后,接收节点接收到数据,并通过串口调试助手打印输出。发送数据的最大长度为 125(加上发送的据长度和校验,实际发送的数据长度为 128 字节)。7 实验心得
这次实验在原来的短距离无线通信中有所涉猎,所以应该这个对于我们来说还是很简单的,所以很快就做完实验了,就和几个同学好好研究了一下它的原理和一些它的展望,感觉这个学科以后有很大的发展前途,作为一个物联网的学生,对无线射频技术应该得很了解,指望它吃饭呢。这次实验也很简单,但是还是可以解除它的最底层的东西可以更加激发我们的兴趣。第三章 ZStack组网实验
多点自组织组网实验 1 实验目的
理解 zigbee 协议及相关知识。
在 ZX2530A 型 CC2530 节点板上实现自组织的组网。在 ZStack 协议栈中实现单播通信。2 实验内容
先启动协调器节点,协调器节点上电后进行组网操作,再启动路由节点和终端节点,路由节点和终端节点上电后进行入网操作,成功入网后周期的将自己的短地址,父节点的短地址,自己的节点 ID 封装成数据包发送给协调器节点,协调器节点接收到数据包后通过串口传给 PC,从 PC 上的串口监控程序查看组网情况。发送数据格式为(16 进制): FF 源节点(16bit)父节点(16bit)节点编号 ID(8bit)例如 FF 4B 00 00 00 01,表示 01 号节点的网络地址为 004B,发送数据到父节点,其网络地址为 00 00(协调器)。3 实验设备及工具
硬件:DZ2530 型 CC2530 节点板、USB 接口的仿真器,PC 机 Pentium100 以上。
软件:PC 机操作系统 WinXP、IAR 集成开发环境、ZTOOL 程序。4 实验原理
程序执行的流程图如图 5-4 所示,在进行一系列的初始化操作后程序就进入事件轮询状态。
对于终端节点,若没有事件发生且定义了编译选项 POWER_SAVING,则节点进入休眠状态。
协调器是 Zigbee 三种设备中最重要的一种。它负责网络的建立,包括信道选择,确定唯一的PAN 地址并把信息向网络中广播,为加入网络的路由器和终端设备分配地址,维护路由表等。Z-Stack 中打开编译选项 ZDO_COORDINATOR,也就是在 IAR 开发环境中选择协调器,然后编译出的文件就能启动协调器。具体工作流程是:操作系统初始化函数 osal_start_system 调用ZDAppInit 初 始 化 函 数,ZDAppInit 调 用 ZDOInitDevice 函 数,ZDOInitDevice 调 用
ZDApp_NetworkInit 函数,在此函数中设置 ZDO_NETWORK_INIT 事件,在 ZDApp_event_loop 任务中对其进行处理。由 第 一 步 先 调 用 ZDO_StartDevice 启动网络中的设备,再调用NLME_NetworkFormationRequest 函数进行组网,这一部分涉及网络层细节,无法看到源代 码,在库中处理。ZDO_NetworkFormationConfirmCB 和 nwk_Status 函数有申请结果的处理。如果成功则 ZDO_NetworkFormationConfirmCB 先执行,不成功则 nwk_Status 先执行。接着,在ZDO_NetworkFormationConfirmCB 函数中会设置 ZDO_NETWORK_START 事件。由于第三步,ZDApp_event_loop 任务中会处理 ZDO_NETWORK_START 事件,调用 ZDApp_NetworkStartEvt 函数,此函数会返回申请的结果。如果不成功能量阈值会按ENERGY_SCAN_INCREMENT 增加,并将App_event_loop 任务中的事件 ID 置为 ZDO_NETWORK_INIT 然后跳回第二步执行;如果成功则设置 ZDO_STATE_CHANGE_EVT 事件让 ZDApp_event_loop 任务处理。对 于 终 端 或 路 由 节 点,调 用 ZDO_StartDevice 后 将 调 用 函 数 NLME_NetworkDiscoveryRequest 进行信道扫描启动发现网络的过程,这一部分涉及网络层 细节,无法看到源代码,在库中处理,NLME_NetworkDiscoveryRequest函数执行的结果将会返回到函数ZDO_NetworkDiscoveryConfirmCB 中,该 函 数 将 会 返 回 选 择 的 网 络,并 设 置 事 件ZDO_NWK_DISC_CNF,在 ZDApp_ProcessOSALMsg 中对该事件进行处理,调用 NLME_JoinRequest加入指定的网络,若加入失败,则重新初始化网络,若加入成功则调用 ZDApp_ProcessNetworkJoin函数设置 ZDO_STATE_CHANGE_EVT,在对该事件的处理过程 中将调用ZDO_UpdateNwkStatus函数,此函数会向用户自定义任务发送事件 ZDO_STATE_CHANGE。本实验在 Zstack 的事例代码 simpleApp 修改而来。首先介绍任务初始化的概念,由于自定义任务需要确定对应的端点和簇等信息,并且将这些信息在 AF 层中注册,所以每个任务都要初始化然后才会进入 OSAL 系统循环。在 Z-Stack 流程图中,上层的初始 化集中在 OSAL 初始化(osal_init_system)函数中。包括了存储空间、定时器、电源管理和 各任务初始化。其中用户任务初始化的流程如下:
用户任务初始化流程图
任务 ID(taskID)的分配是 OSAL 要求的,为后续调用事件函数、定时器函数提供了参数。网络状态在启动的时候需要指定,之后才能触发 ZDO_STATE_CHANGE 事件,确定设备的类型。目的地址分配包括寻址方式,端点号和地址的指定,本实验中数据的发送使用单播方式。之后设置应 用 对 象 的 属 性,这 是 非 常 关 键 的。由 于 涉 及 很 多 参 数,Z-Stack 专 门 设 计 SimpleDescriptionFormat_t 这一结构来方便设置,其中的成员如下: EndPoint,该节点应用的端点,值在 1-240 之间,用来接收数据。AppProfId,该域是确定这个端点支持的应用 profile 标识符,从 Zigbee 联盟获取具体的 标识符。AppNumInClusters,指示这个端点所支持的输入簇的数目。pAppInClusterList,指向输入簇标识符列表的指针。AppNumOutClusters,指示这个端点所支持的输出簇的数目。pAppOutClusterList,指向输出簇标识符列表的指针。
本实验 profile 标识符采用默认设置,输入输出簇设置为相同 MY_PROFILE_ID,设 置完成后,调用 afRegister 函数将应用信息在 AF 层中注册,使设备知晓该应用的存在,初 始化完毕。一旦初始化完成,在进入 OSAL 轮询后 zb_HandleOsalEvent 一有事件被触发,就会得到及时的处理。事件号是一个以宏定义描述的数字。系统事件(SYS_EVENT_MSG)是强制的,其中包括了几个子事件的处理。ZDO_CB_MSG 事件是处理 ZDO 的响应,KEY_CHANGE 事件 处理按键(针对 TI 官方的开发板),AF_DATA_CONFIRM_CMD 则是作为发送一个数据包 后的确认,AF_INCOMING_MSG_CMD是接收到一个数据包会产生的事件,协调器在收到 该事件后调用函数 p2p_test_MessageMSGCB,将接收到的数据通过 HalUARTWrite 向串口 打印输出。ZDO_STATE_CHANGE 和网络状态的改变相关在此事件中若为终端或路由节点 则发送用户自定义的数据帧:FF 源节点短地址(16bit,调用 NLME_GetShortAddr()获得)、父节点短地址(16bit,调用 NLME_GetCoordShortAddr())、节点编号 ID(8bit,为长地址的最低字节,调用 NLME_GetExtAddr()获得,在启动节点前应先用 RFProgrammer 将非 0XFFFFFFFFFFFFFFFF 的长地址写到 CC2530 芯片存放长地址的寄存器中),协调器不做任何处理,只是等待数据的到来。终端和路由节点在用户自定义的事件 MY_REPORT_EVT中 发 送 数 据 并 启 动 定 时 器 来 触 发 下 一 次 的 MY_REPORT_EVT 事件,实现周期性的发送数据(发送数据的周期由宏定义 REPORT_DELAY 确定)。5 实验步骤
1.打开工程文件夹协议栈实验2.多点自组网ProjectszstackSamplesSimpleAppCC2530DB下的工程文件 SimpleApp.eww。2.选择工程
编译,生成协调器代码,并下载到 ZX2530A 开发板。此节点为协调器节点。3.选择工程
编译,生成终端节点代码,并下载到 ZX2530 开发板。此节点为终端节点。4.选择工程
编译,生成路由器节点代码,并下载到 ZX2530 开发板,此节点为路由器节点。5.用串口线将协调器节点与 pc 连接起来,在 pc 端打开 ZTOOL 程序。(ZTOOL 程序在 zstack 安装后自动安装)6.开启 ZX2530A 型 CC2530 节点板电源。7.在 ZTOOL 程序中观察组网结果。6 实验数据分析及结论
由接收数据的 DebugString 可以看出图中有两个节点加入了网了,其中一个节点的 DEVID 是21,网络地址:4f07,父节点地址是 0 即协调器。另外一个节点的 DEVID 是 11,网络地址:A6F7,父节点地址是 4f07 即上一节点。实验中可以试着改变不同节点的位置,然后通过 ZTOOL 看看组网结果有什么不同。7 实验心得
这次实验感觉比原来的更有趣,可以在手机上看到无线连接的组网,所以和同学们很有兴趣,虽然只有几个分支,但是几个的通信还是可以清晰可见的。同时也让我们看到了大型android手机的模样,以前都是看成品,这次看的是半成品,感觉很有意思。在组网的过程中,遇到了一些问题,刚开始不知道如何解决,就问同学和老师,有的是线的问题,由于实验器材本身的问题,导致一些松动之类的,但最后实验总算是顺利的完成了。在这感谢帮助我的同学和老师。第四章 传感器网络综合实验
Zigbee 节点控制程序设计 1.1 协调器节点工程
SimpleCoordinator 即协调器工程,如下图
协调器的应用功能代码实现文件是 SimpleCoordinator.c 在工程文件夹 App 目录下具体实现可参考源码。按下键盘上的 F7 即个编译协调器工程,编译好之后可将代码下载到协调器节点板。1.2 人体红外传感器节点工程
SimpleInfrared 即人体红外传感器工程,如下图
人体红外传感器节点应用控制代码可参考工程目录 App 下 SimpleInfrared.c 1.3 超声波距离传感器节点工程 SimpleDistanceSensor 即超声波距离传感器工程,如下图
超声波距离传感器节点实现代码可参考工程目录 App 下
SimpleDistanceSensor.c。超声波测距驱动代码请参考 ys-srf05.c 文件。
1.4 湿度传感器节点工程
SimpleHumiditySensor 即湿度传感器节点工程,如下图
湿度传感器应用控制代码可参考工程目录 App 下SimpleHumiditySensor.c 文件,其湿度的测量驱动可参考温湿度传感器驱动 dht11.c 文件
平台控制操作 2.1 启动程序
1)安装好程序后,打开 android 应用程序面板,找到图标 点击进入程序。
2)直接点击登录按钮,进入到系统主界面。第一次进入是系统会自动连接到 zigbee 网关然后去搜索 zigbee 网络,默认的 zigbee 网关地址为本机 IP 地址,即 127.0.0.1。
3)如果你的 zigbee 网关地址不是本机,则需要修改默认网关地址。通过按下系统‘菜单’按键,会出现如下菜单,选择‘设置’菜单,可以设置默认的 zigbee 网关。如下图:
4)设置好网关后,下次启动程序就不用再次设置了。2.2 搜索网络
如果 zigbee 网关设置好,通过菜单选择‘搜索网络’就可以搜索 zigbee 网络了,正常情况下至少会有一个协调器节点,如果程序提示搜索不到网络,请检查你的网络连接和协调器是否正确连接。如果 zigbee 网络上还有其它节点,可以在网络 TOP 图上一起显示出来。如下,是一个zigbee 网络 TOP 图:
图中共有 7 个节点,其中最上面那个是协调器节点,其它为传感器节点,其中地址为 58229的灯光设备带有路由功能,属路由器节点,它下面有两个子节点,分别为人体传感器和温度传感器。2.3 传感器节点操作
通过搜索到的 zigbee 网络 TOP 图,可以了解整个 zigbee 网络的节点分布情况。通过点击屏幕上相应节点的图标可以进入相关节点的控制和监控操作。
下图为温度传感器的监控界面:
其它界面读者可以自行实验,并且去了解。
实验心得
四次实验完成了,虽然不能说自己学到了很多吧,至少对这里面的一些操作有了一定的了解,本科生本来就是为了让我们扩充视角,知道更多的东西。无线传感网络真的感觉很神奇,也很有发展前景,这些高尖端的技术,现在存在一些瓶颈,如果能够突破,对物联天下这个目标将前进了一大步,如果能够把传感器节点造的更节能,更低廉,更小巧,将会实现全球各个地方的实时数据采集,就可以得到更多的信息,为以后生产生活带来巨大的改变。在收集的数据肯定是海量的,将需要其他学科的支撑,一起结合起来,实现真的物物相联。