第一篇:无线传感网实验报告
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 网络的节点分布情况。通过点击屏幕上相应节点的图标可以进入相关节点的控制和监控操作。
下图为温度传感器的监控界面:
其它界面读者可以自行实验,并且去了解。
实验心得
四次实验完成了,虽然不能说自己学到了很多吧,至少对这里面的一些操作有了一定的了解,本科生本来就是为了让我们扩充视角,知道更多的东西。无线传感网络真的感觉很神奇,也很有发展前景,这些高尖端的技术,现在存在一些瓶颈,如果能够突破,对物联天下这个目标将前进了一大步,如果能够把传感器节点造的更节能,更低廉,更小巧,将会实现全球各个地方的实时数据采集,就可以得到更多的信息,为以后生产生活带来巨大的改变。在收集的数据肯定是海量的,将需要其他学科的支撑,一起结合起来,实现真的物物相联。
第二篇:无线传感网络学习心得
无线传感器网络学习心得
初次接触这个课程时,我无意地在课本中看到了对于无线传感器网络的基本概述:无线传感器网络是一种全新的信息获取平台,能够实时监测和采集网络分布区域内各种检测对象的信息,并将这些信息发送到网关节点,以实现复杂的指定范围内目标检测与跟踪。这让我联想到物联网体系的感知层与网络层,乍一想,这不就是物联网感知层与网络层的整体解决方案么?美国《商业周刊》与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)测试,交付,维护
以上就是我对无线传感器网络课程的学习心得了,在此课程中,虽然我对其中的知识体系有所了解,但是缺少实际的操作与开发,只是停留在了浅显的认识层面,只有通过实际的操作,才能更深入地去了解它其中的核心,而这一点却恰恰是我们这个课程的学生所缺少的,基于此,我非常地希望在这个专业、这个课程中,有专业的实验室让我们这群学生能够进行实打实的器械操作,这样才能真正地达到“格物致知”,“学为实用”啊。
第三篇:无线传感网外文翻译
无线传感网络
1、简介
无线传感器网络是由一些节点组织成的一个相互协作的网络。每个节点都具有处理能力(有一个或多个微控制器,CPU或DSP芯片),还可包括多种类类型的存储器(程序,数据和闪存),一个射频收发器(能常是用一个全方位的定向天线),电源(如电池和太阳能电池),和各种传感器、执行器。这些节点被部署在一个特定的环境中后,它们通常通过自组织的形式,实现无线通信。可以预见,由数千个甚至上万个这样的节点组成的系统将会出现,并将改变我们的生活和工作方式。
当前,无线传感器网络的部署步伐正在加快。这是很合理的期望:10-15年内,能够通过互联网访问的无线传感器网络将覆盖整个世界。这可以被视为互联网变成了一个物理网络。这一新技术令人兴奋,在许多领域都具有无限潜力,包括医疗,军事,交通,娱乐,危机管理,国土防御和智能空间等。
由于无线传感器网络是一种分布式实时系统,一个自然的问题是,有多少已有的分布式和实时系统解决方案可用于这一些新的系统?不幸的是,很少先前的成果可以应用,因此在系统的所有领域都需要新的解决方案,主要的原因是,以先前的工作为基础的假设发生了巨大变化。过去的分布式系统研究的假设是:系统是有线的,电源是无限的,非实时的,有用户界面(如屏幕和鼠标),有一组固定的资源,将系统中的节点看得很重要,并且是与位置无关的。相比之下,无线传感系统是有线的,电源也比较稀缺,实时的,使用传感器和执行器作为接口,拥有的资源也会动态改变,总体行为很重要,位置信息也很关键。许多无线传感器网络还使用了最低端的设备,这进一步的限制了对过去方案的重用。
本章概述了无线传感器网络的一些关键领域和无线传感网络的研究情况。在介绍过程中,我们使用工作中的具体例子来展示发展的状态并显示这些解决方案与分布式系统的解决方案的不同之处。特别地,我们讨论了MAC层(第2节),路由(第3节),节点定位(第4节),时钟同步(第5节),和电源管理(第6节)。为了展示这一技术的整体状况,我们又简单的讨论了两个当前的系统。在第8节中,我们做了总结。
2、MAC 介质访问控制协议(MAC)通过共用信道协调行动。最常见的解决方案是基于冲突的。一个普通的基于冲突的策略是,让一个节点传输信息来探测信道是否忙,如果不忙则传输该信息,忙则等待并且稍后再次尝试。发生冲突后,节点会等待一段随机的时间,避免再次冲突。许多无线介质访问控制协议也有休眠模式,进入休眠模式后,在一个给定的时间内,节点不再传输和接收数据包,以节省能源。还有许多以些此机制为基础的变化形式。 作者:John A.Stankovic Department of Computer Science University of Vaginal.出处:WDS'08 Proceedings of Contributed Papers, Part III, 19–23, 2008.一般来说,大多数MAC协议都是对一般情况,或者特殊通信模式和工作负荷,而进行的优化。然而,一个无线传输网络具有更多的集中的要求,包括:本地的单播和广播,通信通常是从节点到基站(sink)的(大多数通信因此是朝一个方向的),通信具有周期性和间歇性,并且作为一个主要因素必须考虑能量的消耗。一个有效的无线传感网络的MAC协议必须消耗的能量少,避免冲突,实现所需代码和内存少,能有效的为一应用程序所用,能适应不断变化的无线电频率和网络条件。
基中一个比较好的无线传感网络的MAC的例子是 B-MAC,它是高度可配置的,并且能用很少的代码量和内存量实现。它还有一个接口,允许你选择各种功能,仅当那些功能为某一应用程序特需的时候。B-MAC协议包括四个主要部部分:空闲信道评估(CCA),包重传,链路层的确认,低功耗的监听。当信道空闲时,B-MAC的CCA用一个加权的变化的样本平均值来评估背景噪音,以能更好检测有有效数据包和冲突。包重传时间是可配置的,通常从一个线性范围值中选取,而典型的其他分布式系统使用的是一个指数重传策略。对于典型的在无线传感器网络中发现的通信模式而言,这将减少延迟和工作量。B-MAC也支持一个包一个包的链路层确认机制。这样仅仅重要的包需要消耗额外的代价。低功耗监听机制用于周期性苏醒和休眠的节点中。当苏醒时,它监听一段足够长的时间来评估是否需要继续保持醒的状态,或者转回到休眠模式。该方案节约了大量的能量。许多MAC协议使用请求发送(RTS)和清除发送(CTS)的交互方式。在选定的数据包数量级比较大的网状网络中(1000字节),这个效果很好。然而,当包的大小很小时,为建立一个包的传输所需RTS-CTS开销将变得不可接受,因此,不能用RTS-CTS 策略。
最近,已出现一些支持多信道无线传感网络的的研究工作。在这些系统中,扩展MAC协议为多信道MAC协议是必要的。其中的一个协议就是MMSN[36]。这些协议必须支持像B-MAC协议样的协议的所有特征,但是也必须为每一次传输确定频率。因此,多频MAC协议分为两个阶段:信道分配和访问控制。MMSN的细节是相当复杂的,在此没有做过多的描述。另一方面,我们期望未来有更多的无线传感器网络采用多信道(频率)。MAC协议的优点包括提供了更大的包吞吐量,甚至在由竞争网络和商业设备像移动电话和微波炉引起的频谱拥挤的情况下也能传输。
3、路由
多跳路由是无线传感网络所需的关键服务。下因为如此,出现了大量的这方面原工作。互联网和移动自组网(MANET)路由技术,在无线传感器网络中,不能出色发挥。互联网路由假定具有高可靠的有线连接,因此包错误是很少的;在无线传感器网络中这点不成立。许多MANET路由解决方案依赖于相邻点间的对称的联系(例如,如果节点A可以可靠的到达节点B,则B可以到达A。这些差异使得新的解决方案的发明和部署很必要。
对于以自组形式部署的无线传感器网络,路由策略往往从发现邻居节点开始。节
点巡回发送信息(包)并且建立本立路由表。这些表包括了相邻节点的ID和位置的最少信息。这意味着节点必须先于节点发现之前,知道它们的地理信息。在这些表中的其他典型信息包括节点的剩余能量,能过这个节点的延迟,链路的质量评介。
一旦表在在,在大多数路由算法中,信息从源位置传导到目标地址,都是基于几何坐标,而不是ID。一个典型的像这样工作的路由算法就是GF(Geograpic Forwarding)。
在GF中,一个节点知晓它的位置,并且正在被路由的信息包含了目标地址。此节点然后,通过几何的距离公式,计算哪一个相邻节点与目标节点最靠近。它就将这信息传输到下一跳。在各种GF的变体中,节点也可以考虑延迟,链接的可靠性和剩余的能量。
其他重要的无线传感网络的路由范例是定向扩散[11]。该路由方案集成了路由,查询和数据汇总。此处,散发一个查询来询问对远程节点来的数据的兴趣。拥用适合于被请求的数据的节点就回复以一属性值对。此属性值对,基于梯度,向着请求者的方向延伸,它随着请求的发送和回应而建立和更新。沿着从源到目标的路径,数据可以被聚合,以减少通信量。数据也可以经过多条路径以增加路由的稳健性。
除了刚才展示的的无线传感网络路由的基本的特性外,还有许多关键问题包括: 可靠性
与唤醒/睡眠计划的整合 单播,组播和任播语义 实时 移动性 空洞 安全性和 拥塞
可靠性:由于信息要的传输要经过多跳,各个链接的高可靠性就显得得重要,否则信息传过整个网络的可能性将令人无法接受的低。为了确保链接的可靠性,使用一些指标做了许多重要的工作,像接收信号强度,基于错误的链接质量指标,包投递率等。重要的经验证据表明,包投递率是最好的度量,但是获取这一数据代价是昂贵的。实证数据也表明许多在无线传感器网络中的链接是不对称的,也就是说,节点A可以成功传递一条信息到节点B,反向的从B到A的链接可能不可用。非对称的链接是导致MANET路由算法像DSR和AODV不能很好的用于WSN的原因,因为这些协议从源向目的地发送一条询问信息,然后利用反向的路径获取确认信息。反向路径,由于WSN中的不对称性发生率很高,不太可靠。
与唤醒/睡眠的整合:为了节约能量,许多WSN将点置入睡眠状态。显然,一个醒着的节点里应当选择一个睡眠状态的节点作为它的下一跳(除非它先唤醒该节点)。
单播,组播和任播语义:正如上面提到的,在大多数情况下一个WSN将一条信息路由到一个地理的目的地。当它到达目的的,会发生什么呢?有几种可能性。首先,此信息也包括一个特定单播节点作为目标,或者语义也可能是一个最接近地理终点的节点会成为单播节点。第二,语义可能是,在一个目标地址周围区域中的所有节点都接受到这一信息,这是一区域多播。第三,在目标区域中的任何节点都接受信息,称为任播。SPEED[5]协议就支持这三种语义。也常有洪泛(多播)到整个网络的需要。存在许多高效的洪泛路由策略。
时实性:对于一些应用程序,信息必须在一定期限到达目的地。由于在WSN中存在高度不稳定性,要开发一个总是有保证的路由算法很困难。许多协议如SPEED和RAP用了一个速度的概念来将包传输进行优先次序的化分。速度是一个很好的度量标准,它联合了时间期限和一条信息必须传输的距离。
移动性:路由将会变得复杂,如果信息源和目的都在移动的话。解决方法包括更新本地相邻路由表或者确定代理接点,由它负责跟踪节点所在位置。一给定节点的代理节点也可能改变,当一个节点越来越远离它的初如位置时。
空洞:因为WSN节点传输范围有限,对于一些节点,在路由路径上,在一条信息应该经过的方向上,没有转发节点。像GPSR这样的协议,通过选择一些不在正确方向的节点,以图找到一条绕过空洞的路径,解决了这一问题。
安全性:如果对手存在,他们可以干各种各样的对路由算法的攻击,包括选择性转发,黑洞,重播,虫洞和拒绝服务攻击。不幸的是,几乎所有的路由算法都忽略了安全性并且很容易 受到这些攻击。像SPINS这样的协议开始解决安全路由的问题。
拥塞:今天,许多WSN通信具有周期性或很少通信。拥塞似乎不是一个问题对于这样的网络来说。然而,拥塞对于有更多要求的WSN来说将会成为问题,对于一些处理音频,视频和处理多个基站的大系统来说,这一问题更加突出。甚至在只有一个基站的系统中,在基站附近的拥塞也会是一个严重的问题,因为所以的通信聚集于基站。解决方案使用背压力,减少源节点传输率,扔掉不太重要的信息,并能过调度避免尽可能多的冲突,它们只会加剧拥塞问题。
4、节点定位
节定定位是确定在系统中的每个节点的地理位置的问题。定位问题对于WSN来说是必须解决的,最基本、最困难的问题之一。区域是许多参数和要求的函数,使得它非常的复杂。例如,要考虑的问题包括:额外的定位硬件的成本,信标(自己自己位置的节点)存在吗,如果在在的话,有多少个,它他的通信范围是多大,需要的定位精度是多少,系统是室内的还是室外的,节点之间是否有视线,它是一个二维的、还是三位的定位问题,能量预算是怎样的(信息数量),需要多长时间来定位,时钟是同步的吗,系统处在友好还是敌对区域,有什么错误的假设正在作出,系统对象是否受到安全攻击。
针对某些要求和问题的难题可轻易的解决。如果成本和外形尺寸不是主要的问题并且米级别的精度是可接受的,那么对于户外系统,节点装备上GPS就可以解决问题。如果系统需要一次一个节点的手动方式部署,那么一个由部署者携带的简单GPS节点能够定位每一个节点,依次地,能过一被叫做步行GPS的方案(Walking GPS)。尽管简单,这一方案很精巧,在对每一个节点的定位中避免了手动操作。
许多其他的在WSN中的定位方案要么是基于范围,要么与范围无关。基于范围的机制利用各种技术首先确定节点之间的距离(范围),然后利用几何定理计算位置。为了测定距离,需要采用额外的硬件,比如用来侦测声波和无线电波到达的时间差异。此差异可以被转换为距离的度量。在范围无关的机制中,距离不是直接测定的,但是我们使用跳数。一旦跳数被确定了,节点之间的距离可通过每跳平均距离来估计,然后利用几何定律被来计算位置。范围无关的方案没有基于范围的方案精确,并且常需要更多的信息。然而它们不要求每个节点具备额外的硬件。
几个早期的定位方法包括Centroid[1]和APIT[6]。每一个这类方法解决了基于特定建设的某一定位问题。两个最近有趣的方法是SpotLight和Radio Interferometric Geolocation [20]。聚光灯将许多的定位代码和开销移到中心的一个激光设备上。Spotlight需要光线和时钟同步不。Radio interferometric geolocation 使用一种新奇的网内处理技术,它依靠节点同时发出频率稍微不同的无线电波来完成。这一方案是针对一些部署中的多路问题的,要求许多信息。当前这两种方法都提供了高达厘米级的精度。
5时钟同步
在一个WSN中,每个节点的时钟在一个小的量内应当相同,并且保持下去。由于时钟随着时间漂移,他们必须周期性地重新财步,并且在某些情况下,需要非常高的精确度时,在同步期间对时钟漂移的计数很重要。
时钟同步由于很多原因是很重要的。当一个事件在WSN中发生时,知道它在哪里,什么时间发生是很必要的。时钟也常用于许多系统和应用程序任务。例如,睡眠/苏醒的安排,一些定位算法,传感器融合就是一些需要依靠时钟同步的服务。应用程序像追踪和计算速度也要依靠同步时钟。
用于时钟同步和互联网的的NTP协议对于WSN来说开销太大了。每个节点内置GPS成本又太昂贵了。已经开发的用于WSN的典型时钟同步协议有RBS和FTSP[19]。
在RBS中,一个参考的时间消息被广播到相邻节点。当消息接受到时,接受器记录下这一时间。节点之间交换它们记录的时间并且调整它们的时钟以达到同步。此协议遭受非发射端非确定性,因为时间戳仅在接受端。精确度大约只有30微秒一跳。它不适用于多跳系统,但是可以被扩展。
在TPSN中,为整个网络生成了一棵生成树。该方案假设生成树中的所有链接是对称的。然后从树根开始,沿着树的边进行成对的同步。因为不像在RBS中有广播存
在,TPSN是代价昂贵的。此协议一个关键属性是时间戳被插入到MAC层的传出讯息中,因此减少了非确定性。精确度可达17微秒的范围。
在FTSP中,有无线电层的时间戳,倾斜补偿,线性回归,定期洪泛,来确保这一协议的稳健性,适应拓扑结构的变化。传输和接收信息都在无线电层带上了时间戳,差距用于计算和调整时钟偏移。精确度在1-2微秒范围。
在使用时钟同步协议时,需要注意的是:选择同步的频率,确定在时钟同步期间,时钟漂移是否必须。如何处理多跳/网络问题,并尽量减少能源开销和增加的网络拥塞。
6、电源管理
许多用于WSN的设备像Mica2和MicaZ要两节AA电池带动。根据节点的不同活动级别,如果没有电源管理策略,它的寿命可能只有几天。由于大多数系统需要更长的寿命,许多重大的研究可以保证,在满足基本需求的情况下,使用时间。
在硬件层面上,可以增加太阳能电池或者使用清洁的动能和风能。电池能力也在不断提高。如果外形大小不成为问题,则可以增加更多的电池。低电源电路和微控制器也在逐渐进步。许多硬件平台让设备的各个部分(每个传感器,发送器,微处理器)具有多个省电状态(关闭,闲置,开启)。通过这种方法,仅在某个时间需要的组件才开启。
在软件层面上,电源管理解决方案的目标:(1)由于传输信息和监听信息很耗能量,尽量减少通信(2)对节点或节点的组成部分建立睡眠/唤醒机制
最小化通信信息量是一个综合问题。例如,有一个好的MAC协议,就会减少冲突和重发。有一个好的路由算法,短路径和拥塞的避免或减少就可以实现,并且也可最小化发送信息的量。若能高效的找到相邻节点,则时间同步,定位,广播的查询和洪泛都能减少信息量,从而增加使用寿命。
对于如何安排睡眠/唤醒模式的方法,存在很大的差异。许多解决方案试图让醒着的节点(被称为哨兵)数量最少,为了阻止所有节点睡眠,必须确保所需的感知覆盖范围。为了平衡各节点能量消耗,周期性地执行一个论换机制,选出新的哨兵参加下一个时间段。另一个常用技术是让各节点以一定占空比的形式工作。例如,让一个节点一秒内保持清醒状态200微秒,则它的占空比为20%。占空比的选择取决于应用程序的要求,但最终的结果通常是极大地节省了能源。请注意,占空比法和哨兵法可能联全起来应用,如在军事侦察系统VigilNet[7][9]中,就是这样。
7、应用程序和系统
为了展示WSN的能力,我们举了两个应用程序和与此相关的系统的例子。7.1监视和跟踪
VigiNet系统是一个用于军事侦察的长期实时无线传感器网络。它的主要目标是:在敌对区,当感兴趣的事件发生时,警告军事指挥部和控制单元。感兴趣的事件包括:
人的出现,带武器的人员出现,大型和小型交通工具经过。成功的探测,跟踪和分类要求应用程序以可接受的精度和准确度,获取目标的位置。当信息被成功获取后,在一个可接受的延迟期内,将它报告给无远程的基站。VigilNet是一个自我组织运行的传感器网络(有超过200个XSM微尘节点),它提供了以绊线为基础的监视功能,通过以哨兵为基础的电源管理机制来达到3到6个月的寿命长度。绊线也是仅在需要时才激活外部的传感器(在正常Vigilnet系统之外),如红外摄像机,这也增加了寿命。
图1.1提供了该系统的架构概况,基中有三种组件:1)应用程序组件,2)中间件组件,和3)TinyOS系统组件。应用程序组件为监视目的而设计,包换1)一个基于实体的跟踪组件,2)分类组件,它提供了四种目标的区分,3)速度计算,它人提供目标速度和方向的估计,4)错误警报过滤,它可区分真、假目标。
中间件组件被设计来使独立于应用程序。时间同步,定位和路由组成了低级组件,它们形成了实现更高级中级间服务,像聚合和电源管理的基础。时间同步和定位对于一个监视系统是很重要的,因为协同检测和追踪进程依赖于多个节点发送的追踪报道之间的时空联系。
时间同步模块负责本地节点时钟和基站时钟的同步。定位模块负责确保每个节点能找到它自己的位置。配置模块负责动态配置系统,当系统要求改变时。非对称测试模块设计来协助路由模块来选择高质量的通信链路。无线电唤醒模块用于警告非哨兵节点,当重大事件发生时。电源管理和协作检测是由VigilNet提供的两个关键的高级别服务。哨兵服务和绊线管理负责电源管理,而组管理模块负责事件的联合探测和追踪。哨兵和绊线服务通过选择节点的一部分(它们被定义为哨兵)来监视事件,从而达到省电的目的。其他剩余的节点可以处于低耗电状态,至到一个事件发生。当一个事件发生时,哨兵唤醒事件区域中的其它节点,同时组管理组件动态地将节点组织成组,以实现协同跟踪。这两要组件也一起负责跟踪能量消耗相关的事件。
VigiNet系统的架构建立在TinyOS基础上。TinyOs是一个事件驱动的计算模块。针对特定节点平台,用NesC写成的。TinyOs提供了一个必要的组件集合,像硬件驱动,一个调度机制和基本的通信协议。这些组件为VigiNet模块提供了低层支持,它们也是用NesC语言写的。TinyOS的组件和VigiNet的应用程序先被NESC编译器处理成一个可执行程序,它可以在XSM(和MICA2)节点平台上运行(在VigelNett系统中)。
图1.1 VigilNet系统架构
8、总结
这一章讨论了WSN的相关问题和MAC层、路由、定位、时钟同步、电源管理的实际例子。为什么这些解决方案与过去的网络解决方案如此的不同。还对当前的两个WSN系统进行了简单的描述:一个军事监视、跟踪和分类系统,一个辅助生活设施系统。
尽管这些问题是WSN的关键问题,还有许多重要的话题在本章中无谈到。例如安全和隐私对这些系统来说是很关键的功能。编程抽象和WSN的语言也是一个很活跃的研究领域。一些重大的研究在收集关于WSN性能的实证数据。这些数据对于提高模块和解决方案很关键。调试工具和WSN管理工具也开始出现。
传感器网络研究产生的新技术正在应用到许多实际项目中。未来将会看到这些技术的加速应用。
参考文献
[1] N.Bulusu, J.Heidemann, and D.Estrin, GPS-less Low Cost Outdoor Localization for Very Small Devices, IEEE Personal Communications Magazine, October 2000.[2] A.Cerpa, J.Wong, L.Kuang, M.Potkonjak, and D.Estrin, Statistical Model of Lossy Links in Wireless Sensor Networks, IPSN, April 2005.[3] J.Elson, L.Girod, and D.Estrin, Fine-Grained Network Time Synchronization Using Reference Broad-casts, OSDI, December 2002.[4] S.Ganeriwal, R.Kumar, and M.Srivastava, Timing-sync Protocol for Sensor Networks, ACM SenSys, November 2003.[5] T.He, J.Stankovic, C.Lu and T.Abdelzaher, A Spatiotemporal Communication Protocol for Wireless Sensor Networks, IEEE Transactions on Parallel and Distributed Systems, to appear.[7] T.He, S.Krishnamurthy, J.Stankovic, T.Abdelzaher, L.Luo, T.Yan, R.Stoleru, L.Gu, G.Zhou, J.Hui and B.Krogh, VigilNet: An Integrated Sensor Network System for Energy Ecient Surveillance, ACM Transactions on Sensor Networks, to appear.[8] T.He, P.Vicaire, T.Yan, L.Luo, L.Gu, G.Zhou, R.Stoleru, Q.Cao, J.Stankovic, and T.Abdelzaher,Real-Time Analysis of Tracking Performance inWireless Sensor Networks, IEEE Real-Time Applications Symposium, May 2006.[9] T.He, P.Vicaire, T.Yan, Q.Cao, L.Luo, L.Gu, G.Zhou, J.Stankovic, and T.Abdelzaher, Achieving Long Term Surveillance in VigilNet, Infocom, April 2006.[10] J.Hill, R.Szewczyk, A, Woo, S.Hollar, D.Culler, and K.Pister, System Architecture Directions for Networked Sensors, ASPLOS, November 2000.[11] C.Intanagonwiwat, R.Govindan, and D.Estrin, Directed Diusion: A Scalable Routing and Robust Communication Paradigm for Sensor Networks, Mobicom, August 2000.[12] B.Karp, Geographic Routing for Wireless Networks, PhD Dissertation, Harvard University, October 2000.[14] P.Levis and D.Culler, Mate: A Tiny Virtual Machine for Sensor Networks, Int.Conf.on Architectural Support for Programming Languages and Operating Systems, October 2002.[15] J.Liu, M.Chu, J.J.Liu, J.Reich and F.Zhao, State-centric Programming for Sensor and Actuator Network Systems, IEEE Pervasive Computing, October 2003.[16] C.Lu, B.Blum, T.Abdelzaher, J.Stankovic, and T.He, RAP: A Real-Time Communication Ar-chitecture for Large-Scale Wireless Sensor Networks, IEEE Real-Time Applications Symposium, June 2002.[17] L.Luo, T.Abdelzaher, T.He, and J.Stankovic, EnviroSuite: An Environmentally Immersive Pro-gramming Framework for Sensor Networks, ACM Transactions on Embedded Computing Systems, to appear.[18] L.Luo, T.He, T.Abdelzaher, J.Stankovic, G.Zhou and L.Gu, Achieving Repeatability of Asyn-chronous Events in Wireless Sensor Networks with EnviroLog, Infocom, April 2006.[19] M.Maroti, B.Kusy, G.Simon, and A.Ledeczi, The Flooding Time Synchronization Protocol, ACMSenSys, November 2004.[20] M.Maroti, et.al., Radio Interferometric Geolocation, ACM SenSys, November 2005.[21] D.Mills, Internet Time Synchronization: The Network Time Protocol, In Z.Yang and T.Marsland, editors, Global States and Time in Distributed Systems, IEEE Computer Society Press, 1994.[22] A.Perrig, J.Stankovic, and D.Wagner, Security in Wireless Sensor Networks, invited paper, CACM, Vol.47, No.6, June 2004, pp.53-57, rated Top 5 Most Popular Magazine and Computing Surveys Articles Downloaded in August 2004, translated into Japanese.[23] A.Perrig, R.Szewczyk, J.Tygar, V.Wen, and D.Culler, SPINS: Security Protocols for Sensor Networks,ACM Journal of Wireless Networks, September 2002.[24] J.Polastre, J.Hill and D.Culler, Versatile Low Power Media Access for Wireless Sensor Networks,ACM SenSys, November 2004.[25] N.Ramanathan, K.Chang, R, Kapur, L.Girod, E.Kohler, and D.Estrin, Sympathy for the SensorNetwork Debugger, ACM SenSys, November 2005.[26] R.Stoleru, T.He, J.Stankovic, Spotlight: A High Accuracy, Low-Cost Localization System for WirelessSensor Networks, ACM Sensys, November 2005.[27] R.Stoleru, T.He, and J.Stankovic, Walking GPS: A Practical Localization System for ManuallyDeployed Wireless Sensor Networks, IEEE EmNets, 2004.[28] G.Virone, A.Wood, L.Selavo, Q.Cao, L.Fang, T.Doan, Z.He, R.Stoleru, S.Lin, and J.Stankovic,An Assisted Living Oriented Information System Based on a Residential Wireless Sensor Network,Proceedings D2H2, May 2006.[29] M.Welsh and G.Mainland, Programming Sensor Networks with Abstract Regions, USENIX/ACMNSDI, 2004.[30] K.Whitehouse, C.Karlof, A.Woo, F.Jiang, and D.Culler, The Effects of Ranging Noise on MultihopLocalization: An Empirical Study, IPSN, April 2005.[31] A.Wood and J.Stankovic, Denial of Service in Sensor Networks, IEEE Computer, Vol.35, No.10,October 2002, pp.54-62.[32] A.Wood, G.Virone, T.Doan, Q.Cao, L.Selavo, Y.Wu, L.Fang, Z.He, S.Lin, J.Stankovic, AlarmNet,ACM SenSys, April 2005.[33] T.Yan, T.He and J.Stankovic, Differentiated Surveillance for Sensor Networks, ACM Sensys, November 2003.[34] G.Zhou, T.He, J.Stankovic and T.Abdelzaher, RID: Radio Interference Detection in Wireless SensorNetworks, Infocom, 2005.[35] G.Zhou, T.He, S.Krishnamurthy, J.Stankovic, Impact of Radio Asymmetry on Wireless Sensor Networks, Mobisys, June 2004.[36] G.Zhou, C.Huang, T.Yan, T.He and J.Stankovic, MMSN: Multi-Frequency Media Access Controlfor Wireless Sensor Networks, Infocom, April 2006.
第四篇:水下无线传感网讲解
水下无线传感器网络
摘要: 水下无线传感器网络是一种包括声、磁场、静电场等的物理网络,它在海洋数据采集、污染预测、远洋开采、海洋监测等方面取得了广泛的应用,将在未来的海军作战中发挥重要的优势。描述了水下无线传感器网络的研究现状,给出了几种典型的水下无线传感器网络的体系结构,并针对水下应用的特点,分析了水下无线传感器网络设计中面临的节点定位、传感器网络能量、目标定位等诸多难题,最后根据应用需求提出了水下无线传感器网络研究的重点。
关键词: 水下无线传感器网络;能量;定位 1.引 言
水下无线传感器网络是使用飞行器、潜艇或水面舰将大量的(数量从几百到几千个)廉价微型传感器节点随机布放到感兴趣水域,节点通过水声无线通信方式形成的一个多跳的自组织的网络系统,协作地感知、采集和处理网络覆盖区域中感知对象的信息,并发送给接收者。近年来,水下无线传感器网络技术在国内外受到普遍关注,正在被广泛用于海洋数据采集,污染预测,远洋开采,海难避免,海洋监测等。
水下无线传感器网络具有传统传感器技术无法比拟的优点[1]:传感器网络是由密集型、成本低、随机分布的节点组成的,自组织性和容错能力使其不会因为某些节点在恶意攻击中的损坏而导致整个系统的崩溃;分布节点的多角度和多方位的信息融合可以提高数据收集效率并获得更准确的信息;传感网络使用与目标近距离的传感器节点,从而提高了接收信号的信噪比,因此能提高系统的检测性能;节点中多种传感器的混合应用使搜集到的信息更加全面地反映目标的特征,有利于提高系统定位跟踪的性能;传感器网络扩展了系统的空间和时间的覆盖能力;借助于个别具有移动能力的节点对网络的拓扑结构的调整能力可以有效地消除探测区域内的阴影和盲点。因此,传感器网络能够应用于恶劣的战场环境。在军事领域,通过多传感器系统的密切协调,形成空-舰-陆基传感器构成的多传感器互补监视网络,对目标进行捕获、跟踪和识别。
水下无线传感器网络由于其应用环境的特殊性,要考虑海水盐度、压力、洋流运动、海洋生物、声波衰减等对传感器网络的影响,使水下无线传感器网络的设计比陆地无线传感器网络更难,对硬件的要求更高。水下无线传感器网络的研究现状
由于水下无线传感器网络的巨大应用价值,它已经引起世界许多国家军事部门的极大关注。水下传感器网络技术的发展甚至影响到海军军事战略的变革。由于水下传感器网络技术的发展,未来的海战可充分发挥近海空间优势。
最早开展水下无线传感器网络研究的国家是美国,早在上世纪 50 年代,美国就在大西洋和太平洋中耗巨资建设庞大的水声监视系统(SOSUS)。近几年美国水下无线传感器网络的较大的项目有:1999~2004 年美国海军研究办公室的 SeaWeb 计划;2004 年哈佛大学启动的 CodeBlue平台研究计划;坛上,披露了“近海水下持续监视网” PLUSNet 计划,预计在 2015 年前后具备完全作战能力;洛克希德·马丁公司为美国海军研制能够适应近海海域环境、可以快速布防的先进部署系统(ADS),被用于探测水下敌方潜艇。
随着水下传感器网络技术的成熟,逐渐转向民用。在民用领域主要用于海洋环境和海洋生物监测、海底科学实验等。水下传感器网络主要的民用工程有: MBARI 建立的海洋生化监测系统(LOBO)和海洋监测系统(MOOS)、北太平洋中铺设的有缆绳海洋监测系统 NEPTUNE 工程[8]和设在纽约西长岛南部的前沿分析观测网络和遥测(FRONT)系统。
2006 年国家自然科学基金将水下移动传感器网络的关键技术列为重点研究方向。中国科学技术大学、沈阳自动化研究所、中科院计算所等多家高校和研究单位均已开展了无线传感器网络相关领域的研究。2007 年由中科院上海微系统与信息技术研究所等单位联合承担的“无线传感器网络关键技术及其在道路交通中的应用示范研究”项目通过验收。
随着水下无线传感器网络技术的发展,水下无线传感器网络的节点概念已经由传统的传感器扩大到包括 AUV、蛙人、舰艇、潜艇、鱼雷、水雷和水面浮标等在内的新概念节点形式。新的水下无线传感器网络克服了传统水下无线传感器网络的性能单
一、时效差、造价高和布设困难的缺点,具有布防更灵活、适应环境的能力更强、搜集信息更快捷的特点。
新一代的水下网络不仅仅是水声网络,而是一种包括水声、磁场、静电场等综合性的物理网络。它是集侦察、警戒、指控、通信、导航、定位、目标攻击、综合作战能力的体系。3 水下传感器网络的基本结构和特征
传感器网络系统通常包括传感器节点、汇聚节点(接收器)和管理节点(服务器)。传感器节点监测的数据沿着传感器骨干节点(簇首)多跳地进行传输,在传输过程中监测数据可能被多个节点处理,经过多跳后路由到汇聚节点,最后通过互联网或卫星到达管理节点。用户通过管理节点对传感器网络进行配置和管理,发布监测任务以及收集监测数据。
水下传感器节点主要由一个主控制器或 CPU组成。这个控制器通过接口电路与传感器相连。控制器接收传感器的数据,存储在内存中,然后处理这些数据,并通过声 MODEM 发送给其他网络节点。研究中面临的问题
4.1 水下声传播的特点
陆地上的传感器网络主要靠射频(RF)信号传送信息,而在水下,高频的 RF 信号传播衰减很大,事实上,在水下使用的无线电波的频率仅在低频段(30Hz~300Hz),而且需要较高的发射功率。光信号不像 RF 信号那样有较高的传播衰减,但是有较大的散射。因此,水下无线传感器网络是基于声信号的无线通信。水下声信道的限制带宽和各种延迟要求新的可靠的通信协议。水声无线网络的设计中存在的主要困难是:
(1)水声信号可实现的带宽被严格的限制;(2)水下信道由于多通道导致严重的衰落,而且水下的衰减是多变的;
(3)由于传感器节点的流动性和能量消耗殆尽导致节点“死亡”,可能造成通信连接的不可靠,比特率出错高和暂时的通信中断可能会出现;
(4)节点的通信范围小,导致网络不能实时处理数据;(5)在水下不能使用太阳能,电池的能量有限并且不可被更换;(6)水下无线传感器网络的实时性和能量问题是一对矛盾,信息处理结构的变化使软件必须重新设计;
(7)水下传感器节点会由于密度大而拥塞出现错误。基于水下声信号传播的特点列出水下无线传感器网络中的设计中存在的主要问题。
4.2 水下无线传感器网络设计中的问题 4.2.1 传感器节点定位问题
水下传感器网络节点是随机放置的,因为数目众多,节点体积很小和费用上的考虑,每个节点都有 GPS 定位系统是不可能的,另外,布放后每个节点位置不是固定的,可能随洋流漂流,给节点的自身定位提出了挑战。
定位是军事应用的基础。定位问题包括两部分:节点自身定位和外部目标定位,前者是后者的基础。
基于参考节点的节点自身定位问题,很多学者提出了很多定位的方法,这些算法的目的在于使得传感器节点能够被随机地布置在一个给定的区域,并能根据一些参考节点而自动检测它们的自身位置。
无线传感器网络中需要定位的节点称为未知节点(unknown node),通过人工部署或 GPS 系统已知位置的节点称为锚节点(anchor)。节点的定位包括:绝对定位和相对定位、集中式定位和分布式定位、基于测距的定位和无需测距的定位。绝对定位的结果是一个标准的坐标位置,如经纬度。相对定位通常是以网络中部分节点为参考,建立整个网络的相对坐标系统。集中式定位是把信息传送到某个中心节点进行定位计算的方式,便于从全局角度统筹规划,获得相对精确的位置估计。分布式定位是尽量将计算量分摊到网络中的各个节点上,以减小对中心节点的计算能力的要求。
无线传感器网络中绝大多数现有的定位方法都包含两个基本步骤:距离(或角度)测量和定位计算。目前的定位方法有:于接收信号能量的RSSI 定位算法;基于信号到达时间的 TOA 定位算法;基于信号到达时间差的 TDOA 定位算法;基于邻节点发送信号角度的技术 AOA 算法。计算节点位置的方法有:三角测量法、三边测量法、多边测量法、质心定位算法、多跳定位算法 APS、APIT定位算法、极大似然估计法、Hop-Euclidean 定位算法和多维定位算法 MSD 等。
在水下无线传感器网络中,通常由于传感器放置于水下,网络节点无法获知确定的位置信息,要求可实现分布式无锚节点的 WSN 节点定位机制。
针对水下 WSN 会存在很多移动的传感器节点,如 AUV、移动机器人等,目前出现了许多移动节点的定位方法。
WSN 定位算法的性能直接影响其可用性。评价定位算法的标准主要有:定位精度、规模、锚节点密度、节点密度、覆盖率、容错性和自适应性、功耗和代价。4.2.2 系统能源问题
由于水下无线传感器网络的应用特点,使得更换水下节点电池非常困难,因此无线传感器网络的能耗一直是研究人员关注的焦点。传感器网络节点的能源主要消耗在信息传输和数据处理,而且传输信息比数据处理更消耗电能。软件上采用好的拓扑控制算法、高效的通信协议和路由协议,硬件上节点内部结构的合理设计、采用低功耗的芯片和改进电池性能是节省能源的关键。
目前关于传感器在实时应用的能量有效计算问题形成了很多拓扑算法。例如,最小能量途径的算法(LBMER)、HCAN、CDS(Connected DominatingSet)、JSD、蚁群算法等。所有的这些算法都是基于节约能量的算法。
在无线传感器网络中,介质访问控制(MAC)协议决定无线信道的使用方式,在传感器节点之间分配有限的无线通信资源,用来构建传感器网络系统的底层基础结构。根据传感器节点无线通信模块发送、接收、侦听和睡眠四个状态消耗能量顺序依次减少的特点,传感器网络 MAC 协议为了减少能量的消耗,通常采用“侦听/睡眠”交替的无线信道使用策略。采用简单高效节能的 MAC 协议是无线传感器网络设计应考虑的问题。
与传统网络的路由协议不同,无线传感器网络的路由协议是基于能量优先的。路由协议的设计目标是,应尽可能地降低能耗,提高能量使用的有效性,避免过度使用低能量节点,从而延长网络生命周期。同时路由协议不能占用大量的存储空间,尽量减少计算量。
在硬件上,针对传感器节点传输能力有限和传输距离有限,往往需要布设大量节点,廉价和低功耗的传感器节点正在被不断设计出来。设计新的试验平台减小能耗是研究者研究的方案,出现了Mica2 和 MicaDot2,以及 NASA JPL 实验室的 SensorWeb。Mica2 选配了新的微处理器和射频芯片,修正 Mica 的一些技术缺陷。Mote 系列的第四代节点Telos 设计上出现了很大改进,通过选用新的微处理器减小休眠工作电流和系统唤醒时间,能耗显著降低。国内也有许多研究机构根据各自应用的需要开发出了新的节点。电池技术的进步已逐步在减轻传感器网络的能源瓶颈。加州大学洛杉矶分校、佛罗 里达大学、犹它大学和海军研究实验室用微机电系统(MEMS)技术开发三维形状的微型电池,有望突破这一限制。水下无线传感器网络中使用风能和太阳能也并非不可能,MBARI 已经设计出了通过水面浮标搜集风能和太阳能,并通过水下缆绳传输给每一个网络节点。4.2.3 目标定位跟踪
声信号目标定位方法从物理处理角度大致分为几大类: AOA、TDOA、DOA 和 RSSI(或 SRP)。基于 AOA 技术定位不仅能确定目标的坐标,而且能够确定目标的角度信息,但是 AOA 测距技术容易受外界环境的影响,而且 AOA 需要额外硬件,在硬件尺寸和功耗上不适用于大规模的传感器网络[14]。目前常用的声源定位方法主要是 TDOA、DOA 和 RSSI。
水下目标的跟踪往往涉及数据融合,融合就是将来自多个传感器或多源的信息进行综合处理,从而得出更准确可信的结论。目标的跟踪包括几个阶段:探测、分类、定位、预测和跟踪。目标的探测需要建立合适的门限,超过门限,判有目标,否则无目标;分类是判断目标的有无及目标个数;定位最常用的方法是极大似然估计(ML)定位算法,可以得到很好的定位结果,但对参数变化敏感,且在多目标跟踪环境下实现复杂度较高;预测是根据采集数据,建立目标的运动方程,预测目标的运动轨迹。4.2.4 其它
(1)水下无线传感器网络的安全性问题。在军事应用中,传感器网络的安全问题不可忽视,对数据的采样传输和物理节点的分布都有很高的要求。由于传感器网络的自身特点使得传感器网络安全问题的解决思路和方法与传统网络安全问题不同。主要表现在:有限的存储空间和计算能力;缺乏后期节点布置的先验知识;布置区域的物理安全无法保证;有限的带宽和通信能量;整个网络的安全问题和应用相关性。传感器网络的安全问题是一个开放的、活跃的研究领域。
(2)网络的实时性。由于在军事上被用于目标跟踪,要求传感器网络能实时地反映目标的运动信息。
(3)固定区域内布置传感器节点的最佳数量。要找 出 不 同 类 型 和 位 置 的 传 感 器,使 覆 盖 面(Coverage)最大,代价(Cost)最小,这是一个 NP 问题。一种办法是找到一种覆盖路径,使路径到各节点的距离之和最大,也就是覆盖面最大,同时使这条路径距离最近传感器节点的距离最小。5 结 论
水下无线传感器网络是一个大的系统,其中的硬件、软件的技术问题很多。本文总结了水下传感器网络中已有的研究,重点阐述了传感器网络节点自定位、系统的能源问题和基于声信号的目标定位方法,对影响传感器网络性能的一些重要因素进行了阐释。今后要做的是,考虑所有对传感器网络的性能有较大影响的因素,在运算量和定位精度之间有一个折中时,寻求一种目标定位跟踪方法,达到最好的定位效果。参 考 文 献
[1] 丁晋俊, 李志刚.传感器网络在战场目标定位跟踪中的应用[J].电子对抗, 2006 [2] Arati Manjeshwar and Dharma P.Agrawal, TEEN: A routing protocol for enhanced efficiency in wireless sensor networks[R].International Proceedings of 15th Parallel and Distributed Processing Symposium, 2001: 23-27.[3] 胡荣春.无线传感器网络中的节点定位方法研究[D].中国科学技术大学硕士学位论文, 2007.5.[4] T.O’Reilly, R.A.Herlien, et al.Satellite link management for an ocean observing network[A].MTS 2007[C].[5] Walter Paul, Mark Chaffey, et al.The use of snubbers as strain limiters in ocean moorings[R].Proceedings of MTS/IEEE, September 2005.[6] Andrew Hamilton, Mark Chaffey.Use of an electro-optical-mechanical mooring cable for oceanographic buoys: Modeling and validation[A].[7] Luke J.Coletti, Steve E.Fitzwater.Wireless network allows monitoring of a dynamic coastal resource.monterey bay aquarium research institute[R].OS45D-25.[8] CHAN Ting, LIU Chen-Ching, Bruce M.Howe, et al.Optimization based load management for the NEPTUNE power system[A].IEEE Power Engineering Society General Meeting[C].2007: 1-6.[9] James O'Donnell1, Dan Codiga1, Christopher Edwards, et al.Front resolving observational network with telemetry(FRONT)[P].A National Oceanographic Partnership Program Award,Award Number: N00014-99-1-1020.[10] Erdal Cayirci, Hakan Tezcan, et al.Wireless sensor networks for underwater surveillance systems[J].Ad Hoc Networks, 2004,(4):431-446.[11] Bruce M.HOWE and Timothy MCGINNIS.Sensor networks for cabled ocean observatories[A].IEEE 2003[C].216-221.[12] 王焱欣.无线传感器网络中的自定位研究[D].中国科学技术大学硕士学位论文, 2007.5.[13] 孙利民, 李建中, 陈渝, 等.无线传感器网络[M].清华大学出版
第五篇:无线传感网络课程设计
无线传感网络 课程设计报告
姓名:胡韶辉 胡衎
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显示屏也会显示相应状态,进行信息反馈。