第一篇:无线传感网络研究应用
无线传感网络研究应用
应用前景
无线传感网络是面向应用的,贴近客观物理世界的网络系统,其产生和发展一直都与应用相联系。多年来经过不同领域研究人员的演绎,无线传感网络技术在军事领域、精细农业、安全监控、环保监测、建筑领域、医疗监护、工业监控、智能交通、物流管理、自由空间探索、智能家居等领域的应用得到了充分的肯定和展示。
在环境监控和精细农业方面,WSN系统最为广泛。2002年,英特尔公司率先在俄勒冈建立了世界上第一个无线葡萄园,这是一个典型的精准农业、智能耕种的实例。杭州齐格科技有限公司与浙江农科院合作研发了远程农作管理决策服务平台,该平台利用了无线传感器技术实现对农田温室大棚温度、湿度、露点、光照等环境信息的监测。
在民用安全监控方面,英国的一家博物馆利用无线传感器网络设计了一个报警系统,他们将节点放在珍贵文物或艺术品的底部或背面,通过侦测灯光的亮度改变和振动情况,来判断展览品的安全状态。中科院计算所在故宫博物院实施的文物安全监控系统也是WSN技术在民用安防领域中的典型应用。
现代建筑的发展不仅要求为人们提供更加舒适、安全的房屋和桥梁,而且希望建筑本身能够对自身的健康状况进行评估。WSN技术在建筑结构健康监控方面将发挥重要作用。2004年,哈工大在深圳地王大厦实施部署了监测环境噪声和震动加速度响应测试的WSN网络系统。
在医疗监控方面,美国英特尔公司目前正在研制家庭护理的无线传感器网络系统,作为美国“应对老龄化社会技术项目”的一项重要内容。另外,在对特殊医院(精神类或残障类)中病人的位置监控方面,WSN也有巨大应用潜力。
在工业监控方面,美国英特尔公司为俄勒冈的一家芯片制造厂安装了200台无线传感器,用来监控部分工厂设备的振动情况,并在测量结果超出规定时提供监测报告。西安成峰公司与陕西天和集团合作开发了矿井环境监测系统和矿工井下区段定位系统。
在智能交通方面,美国交通部提出了“国家智能交通系统项目规划”,预计到2025年全面投入使用。该系统综合运用大量传感器网络,配合GPS系统、区域网络系统等资源,实现对交通车辆的优化调度,并为个体交通推荐实时的、最佳的行车路线服务。目前在美国的宾夕法尼亚州的匹兹堡市已经建有这样的智能交通信息系统。
无线传感网络应用前景广阔,特别是我国西部地区的一些山区,需要对山地滑坡、泥石流、大桥位移、景区环境监测,但是无线传感器网络的生存时间却要求长达数月甚至数年,因此,如何在不影响功能的前提下,尽可能节约无线传感器网络的电池能量成为无线传感器网络软硬件设计中的核心问题,也是当前国内外研究机构关注的焦点。本文研究基于分布式压缩感知算法的无线传感网络节能模型研究,用以降低无线传感网络的耗电量,具有极高的应用价值。
第二篇:无线传感网络课程设计
无线传感网络 课程设计报告
姓名:胡韶辉 胡衎
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)测试,交付,维护
以上就是我对无线传感器网络课程的学习心得了,在此课程中,虽然我对其中的知识体系有所了解,但是缺少实际的操作与开发,只是停留在了浅显的认识层面,只有通过实际的操作,才能更深入地去了解它其中的核心,而这一点却恰恰是我们这个课程的学生所缺少的,基于此,我非常地希望在这个专业、这个课程中,有专业的实验室让我们这群学生能够进行实打实的器械操作,这样才能真正地达到“格物致知”,“学为实用”啊。
第四篇:无线传感网实验报告
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 网络的节点分布情况。通过点击屏幕上相应节点的图标可以进入相关节点的控制和监控操作。
下图为温度传感器的监控界面:
其它界面读者可以自行实验,并且去了解。
实验心得
四次实验完成了,虽然不能说自己学到了很多吧,至少对这里面的一些操作有了一定的了解,本科生本来就是为了让我们扩充视角,知道更多的东西。无线传感网络真的感觉很神奇,也很有发展前景,这些高尖端的技术,现在存在一些瓶颈,如果能够突破,对物联天下这个目标将前进了一大步,如果能够把传感器节点造的更节能,更低廉,更小巧,将会实现全球各个地方的实时数据采集,就可以得到更多的信息,为以后生产生活带来巨大的改变。在收集的数据肯定是海量的,将需要其他学科的支撑,一起结合起来,实现真的物物相联。
第五篇:无线传感网络课程作业
物联网之未来的智能家居系统
——House Stage
不知不觉中时光在悄悄的流逝,转眼之间,我选择这个专业已经两年了。从一开始的不知物联网为何物的懵懂少年,成长为了一名热爱物联网技术并坚定的以它为未来目标职业的物联网发烧友。这其中经历了太多太多。今天就接着这个机会,来谈一谈我内心中对智能家居系统的一种设计理念。
目前在全球范围内,都有一股对物联网技术的推崇,其中以智能可穿戴设备,智能家居,车联网为主导方向。而在其中,谷歌与苹果相继发布了关于Self-Driving Car与IWatch的相关信息后,关于物联网技术的应用更是达到了一个白热化的阶段,各种各样的智能设备也随之活跃起来。但是智能家居系统却始终处在一个较为尴尬的局面,市场上主要以智能家居单品为代表。究其根源,一方面有用户体验方面的原因,另一方面也有在安全方面的原因。而我的House Stage主要设计是出于用户体验方面的考量。
首先,用户在使用智能家居系统时,首要的考量便是完全性的问题,因此我设计的House Stage使用的协议为ZigBee协议。之所以选择这样的协议主要是对比WiFi协议,ZigBee协议具有低功耗,成本低,短时延,组网能力强,安全性能高等优势,而它的缺点也比较明显,那就是对于数据传输的速率比较低。但是对于实现家庭自动化的智能家居系统来说,这并不是问题。目前市场上的智能家居系统主要是采用WiFi协议,一方面WiFi协议开发成本高,导致后期智能系统价格不够亲民,群众接受度不高,而且安全性差,达不到群众内心中对智能系统的最基本要求;另一方面,WiFi组网能力不强,能够接受的有效节点数只有32个,这对于普通用户家庭中所拥有的家电数目显然是不太够的。同时,用户在使用智能家居系统时也会考虑到平时的功耗问题,而ZigBee不仅工作时耗电少,而且支持休眠模式。平时不用工作时可以处于休眠状态,用户需要使用时直接唤醒即可,另外ZigBee从休眠状态转换到工作状态所花费的时间非常的短,具有较好的用户体验。考虑到用户家中可能设置有无线路由器并使用WiFi接入网络,所以在House Stage中会引入抗干扰机制,采用非协作方式,通过动态信道分配,来减少ZigBee与家庭WiFi的冲突。同时使用ZigBus总线协议,添加多级无线信号的有线中继,解决了多楼层多单元之间的信号覆盖问题。对于家庭中平时采集的数据则存放在后台数据库中,采用一套轻量级数据库加密技术,并且通过物理网络地址绑定,允许绑定多个物理地址。只有通过事先设置好的终端才能进行查看,并且用户可自行设置数据的最大存活周期。这都大大提高了系统的安全性,满足了用户对系统安全性的需求。其次在功能方面,整个系统可分为安防监控系统和智能操控系统。在安防监控系统中,使用了系统集成的无线网络摄像头以及各种安防传感器如红外线探测器,烟感/煤气传感器,智能门锁控制等。同时安防系统支持3G网络,当用户不在家时,可以通过手机等移动终端查看家中的情况。当有小偷或是发生火灾等重大紧急情况,在向用户发送紧急信息的同时,也会接入到当地公安机关和消防部门等。如果家中有老人或者小孩发生意外,系统还会发送警告信息给用户,帮助用户妥善处理这类问题。不仅如此,当有访客来访时,系统也会对访客进行拍照,并且发送到用户手机上,用户可以考虑是否接待客人。如果用户选择接待,则系
统开门迎接,并打开部分娱乐性的家电供访客打发时间。如果用户此时不方便接待,则可以选择不接待,此时系统会自动播放录音,可以是用户自行设定的录音,也可以是系统默认的录音。同时支持黑名单功能,用户一旦将来访者列入黑名单后,系统今后将自动拒绝来访者的来访请求。而智能操控系统则包括了智能灯光控制,智能家电控制,智能家居情景模式切换,智能环境监控等。在智能灯光控制方面,支持手机电脑远程控制,兼容多种情景模式,如会客,家庭影院,派对等,同时也支持智能感应。在晚上的时候,当有人起夜时,系统通过传感器检测到有人夜间活动,便会亮起电灯,当人离开时又会自动关闭。当然此时的安全监控系统是开启的,门磁也处于工作状态,所以能够识别盗贼。另外在智能家电控制功能中,用户不仅可以通过移动网络对家里的家电进行操控,在没有网络的情况下,也可以通过将手机短信发送到家里的系统控制终端来达到操控目的。打个比方,在夏天酷热难耐时,你正好在赶回家的路上。此时的你想必是希望快点回到家中躲避这样的酷暑吧。但是,即便回到家中,打开空调到室内温度达到一个舒适温度也需要数分钟的时间。如果拥有这样的一个系统,你只需要设定好温度和时间并将信息发送回家,系统终端接收到信息后便会通过相应的智能开关打开空调进行制冷。这样一方面即可实现用户远程控制家电的想法,另一方面,使用智能开关更加具有灵活性,即便不是智能家电设备也可以进行轻松调控。可如果你在家想看一场电影而又苦于没有在电影院看的那种感觉,亦或是你想开一场派对却又懒得布置环境,那么拥有这套系统就可以轻松帮你搞定。用户只需要在系统终端中选择到智能家居情景模式切换,并选择相应的模式即可。比如用户选择了影院模式,灯光便会自动调整为影院模式,同时窗帘自动拉上,各种音频视频设备自动打开,DVD机智能选择播放用户喜欢的电影。又或者用户选择派对模式,系统会将普通灯光换成彩色闪灯,在打开各类音频视频设备的同时,还能智能调控音量大小,让用户既能玩的尽兴又不用担心噪声扰民。另外用户只需准备好相应的食材,并在网上下载相应的烹饪算法,然后将这一切交给智能家居便可。而对于智能环境监控这个功能来说,它通过调用分布在家中各处的温度湿度传感器对家居环境进行检测,并自动控制中央空调调节温度和湿度,还可通过光传感器,在白天的时候检测家中的采光情况,并控制窗帘和窗户进行光线调节,给用户营造一个舒适的家居环境。
以上便是我对智能家居系统的一个设想,其中部分功能已经现世,但仍然不完善,有一些功能则尚未开发出来。另一方面在系统组成架构上是按照课本上及其相应的一些专业知识进行合理的构想组合,并认为有一定可能可以实现的,并且我认为这样的一套系统在未来10~20年内有可能被开发出来。因为其中的大部分技术与协议是现今所有的,只是通过重新的组合,以一种新的方式呈现出来。但是由于某些协议中的技术标准尚不完善,并且大部分市场尚未打开,所以需要一定的时间来完善。同时这也是我对无线传感器网路技术及其应用这门课程学习后的心得体会的缩影,绝大部分资料来源于课本和之前的物联网导论及其自己平时经常关注的一些国外较成熟产品的功能,整片文章纯手打,来源于互联网的资料少之又少,无任何抄袭复制的成分。
学习心得
经过了一个学期的无线传感网络技术及其应用的课程学习,我对物联网的了解更加深入了一点,从以前只知道事物之间可以互联互通,到现在对相应技术及
其相应的协议算法等都有了一个比较初级的了解,从物理层,数据链路层,网络层,传输层,应用层具有涉猎。单从课程角度来讲,课程内容比较偏理论化,个人感觉缺乏相应的实验教学导致所学的内容与实操偏离较远。但老师的教学相当不错,能够尽可能的以生动形象的比喻来说明,这点是非常好的。