1.实验目的
本实验介绍了使用IOT-NODE433的MAC库实现一个基于简单的泛洪协议的多跳路由网络的程序。通过实验操作,使读者了解无线自组织网络的特点及它与传统网络的区别,并对无线自组网有一个直观的印象,激发对于无线自组织网络的兴趣和爱好。同时,使读者初步掌握利用MAC库编程的方法和步骤,并能够通过MAC库开发高级通信协议。
2.实验设备
(1)硬件
● 433MHz节点(IOT-NODE433)3个。
● JTAG编程器1个。
● PC(含串口)1台。
(2)软件
● WINAVR4.07。
● AVRStudio。
● 多跳库文件libmac433.a。
● 可视化软件Snamp。
3.实验原理
该协议的实现基于泛洪协议的思想,也就是产生数据的节点向全网广播该数据包,收到该数据包的节点也采用广播的方式向全网广播接收到的数据包,直到数据包到达发送节点,发送节点接收到该数据包后将其发送给后台PC。
图4-5 无线自组织网络示意图
协议的开发加入了一些避免循环路由和广播风暴的机制。广播风暴是由广播引起的,以图4-5所示的网络为例,假设A为数据源,A通过广播给B传输了一个数据包,那么B要转发该数据包,在广播方式下A,C,D都会收到B点转发的数据包,那么A,C,D又要转发该数据包,结果造成数据包在网络中无限的被广播,并最终导致网络瘫痪。可以采用数据包登记的机制来避免这种广播效应:每个节点接收到一个数据包后,先要检查自己的登记表,看是否收到过相同的数据包,如果有相同的就不转发,如果没有相同的就转发并且将该数据包登记。数据包的标示由数据包的源节点号以及数据包的包号组成,由于数据包中的mac头部分和网络层部分的参数在数据包传输的过程中是可变的,因此只能提取应用层部分的数据,选择SensorMsg中的src和sensorseq作为判断一个数据包的标识。
(1)IOT-NODE433的433MAC库介绍
IOT-NODE433试验开发板最主要的功能是实现半双工的无线通信。为了方便读者的开发学习,提供了MAC层协议库,相关的函数以功能库的形式提供。MAC层协议库能够提供的功能包括ACK机制、射频睡眠机制以及透明的传输数据包的能力,采用了CSMA/CA技术,使用二进制退避算法实现冲突避免,利用CRC-16算法进行检校。
(2)MAC数据包格式说明
下面是message.h中的部分代码,相关数据包的格式在该文件中定义。
length,type,toAddr,fromAddr,group这5字节是数据包的MAC头。其中length是比较重要的部分,它表示包的长度。由#defineMAC_HEADER_LEN7这段代码可以看出,在设计的时候crc的2字节是计算在MAC头中的,对于length的计算需要先说明一下data数组。data[MAX_PKT_LEN-MAC_HEADER_LEN]才是用户可以自由发挥的地方,在这里用户可以定义自己的数据包格式,MAC库对数据包是透明的,数据包的解析和填充过程是在外部完成的,不过数据包要放在data数组中。比如下面定义的一个数据包格式:
下面是填充data数组的代码:
对于这个数据包来说,length的计算应该是sizeof(SensorMsg)+MAC_HEADER_LEN。这里有一点要强调的就是,length不是一次就算出来的,只有在MAC层中才会加入MAC_HEADER_LEN,这会在后面介绍MAC库的时候介绍。
type字节表示数据包的类型,这都是在MAC库中定义的,分为下面几种,在库中用枚举类型进行了定义:enum{RTS_PKT,CTS_PKT,DATA_PKT,ACK_PKT};toAddr和fromAddr字段表示源地址和目的地址;group字段表示组号,MAC中设定为0x01,一般来说group字段是用不到的,可以不管;crc字段是用来做检校用的。
(3)MAC库接口函数介绍
IOT-NODE433的MAC库给用户提供了丰富的接口,便于用户自己开发。MAC库包含了3个模块,分别是mac,physical和radiocontrol,对外接口主要由mac模块提供。radiocontrol模块在初始化的时候会调用CC1000模块完成射频芯片的一些配置工作,在TX和RX切换的时候也会调用CC1000模块(为了方便,CC1000模块也被封装在库中)。还有一点需要说明的是,radiocontrol模块在进行载波监听的时候需要使用ADC转换部件。ADC转换结束的时候会回调radiocontrol模块中的RadiocontrolRSSIADCDataReady函数,该函数会根据ADC转换获得的数据来判断信道是否空闲。实现这个功能需要占用硬件上的ADC0通道。下面分两部分对相关的接口函数进行简单的介绍。
1)入口函数。入口函数也就是可以供用户调用的功能接口,主要包含两个函数,分别是支持单播的函数MACUnicastMsg和支持广播的函数MACBroadcastMsg。另外,还有MAC层的初始化函数MACInit。本实验中主要使用广播函数MACBroadcastMsg,其原型和实现如下:
MACBroadcastMsg(void*data,uint8_tlength)
2)回调函数。回调函数是MAC库对外的信息接口,通过回调函数外部模块可以被动地获得MAC层的一些运行状态。需要注意的是,回调函数需要用户来实现,回调函数中最主要的几个函数是ReceiveDone,TransmitDone,SendFail,GetFreeQueueLength。由于这几个函数需要用户来实现,这里对其功能进行简单介绍。
result_tReceiveDone(OSMACMsgPtrpacket);
函数的参数是接收到的数据包指针。该函数是MAC层正确接收到一个完整的数据包后向上层提交数据包的一个响应,能通过MAC层的数据包要么是广播数据包,要么是指定发往本节点的数据包,其他非发往本节点的单播数据包会被MAC层过滤掉,上层看不见到这些数据包。
result_tTransmitDone(OSMACMsgPtrmsg);
函数的参数是发送的数据包指针。该函数是MAC层完成一个数据包的传输后通知上层的函数。对于广播和单播,它们的意义有所不同:在广播方式下,MAC层只要将数据包发送出去了,就表示数据发送完成了,可以调用TransmitDone函数来通知上层数据发送完成;在单播方式下,如果采取不需要ACK的方式,那么其工作的机理和广播一样,但在有ACK方式下,MAC层只有在收到ACK信息以后,才会调用TransmitDone函数来通知上层数据发送完成。
voidSendFail(OSMACMsgPtrreceivemsg);
该函数的参数是发送失败的数据包指针,用于通知上层发送失败,它只有在采用单播并且同时使用ACK机制的时候才有效,在ACK等待超时的情况下MAC层会回调该函数,通知上层数据包发送失败。
(4)泛洪协议实现过程
协议的实现在代码app.c中。主要过程是,实验中3号节点为数据源,每2s,3号节点产生一个数据包。该数据包通过广播的方式发送出去,其他节点(非发送节点)接收到该数据包后,也是通过广播的方式进行转发。下面分发送和接收两部分分别进行介绍和说明。
数据的发送过程主要负责采集光传感器数据,并将此数据发送出去,其主要过程为:主程序在启动之后,启动一个计数器。每次计数器溢出时,调用采集光传感器数据的函数SensorExternalPhotoADCGetData。采集到数据之后系统触发SensordataReady事件,在其处理函数中,调用SendSensorData函数。该函数又使用MACBroadcastMsg函数进行发送,最后系统触发TransmitDone事件。各函数的调用关系如图4-6所示。
下面分别对图中的主要函数进行说明。
光传感器数据采集完毕事件响应函数SensordataReady:该函数判断节点号,如果是数据源节点就把采集到的数据发送出去。(www.xing528.com)
图4-6 各函数调用关系
数据采集和广播函数SendSensorData:在数据源节点中,函数由ADC中断响应函数调用,其功能是将由ADC采样得到的数据组合成数据包,通过MACBroadcastMsg函数,将数据包广播出去。
上述函数中调用了数据包登记函数InRecord。该函数的功能是登记一个数据包到本地的数据包登记表,采用数据包登记机制的目的是避免广播风暴。其代码如下:
数据发送完毕,TransmitDone事件被触发,在其处理函数中将网络层数据包序列号递加,并改变LED灯的状态。
接收到数据包,系统触发ReceiveDone函数。该函数调用routehandlepkt对数据包类型进行处理。如果是传感器数据包,再调用routeReceiveSENSOR根据节点的类型进行转发或者发送到串口。主要函数调用关系如图4-7所示。
图4-7 主要函数调用关系
下面对图中主要函数进行说明。
ReceiveDone函数判断:如果是发送给本节点的数据包,则调用routehandlepkt进行处理。
routehandlepkt函数根据数据包网络层类型判断:如果是传感器数据包,再调用routeReceiveSENSOR根据节点的类型进行转发或者发送到串口。
routeReceiveSENSOR函数首先登记接收到的数据包,然后判断自己的节点类型对数据包进行处理。如果是非发送节点先要检查自己的登记表,看是否收到过相同的数据包,如果有相同的就不转发,如果没有相同的就转发并且将该数据包登记;如果是发送节点则把数据打印至串口显示,完成整个传输过程。下面是相关的代码:
接收数据转发函数sendreceivesensor调用MAC库提供的广播函数把收到的数据发送出去。用于数据的转发,使节点具有路由功能。
4.实验内容
阅读MAC库的介绍,学习MAC库的功能,了解主要接口函数。
掌握使用MAC库设计通信程序的方法,了解MAC库的功能架构,通过使用该库文件可以实现简单的路由协议。对IOT-NODE433节点进行实际操作,包括程序烧入,在线仿真等,了解IOT-NODE433节点的硬件结构。
在PC上通过WinAVR编译提供的实验代码,使用AVRStudio和仿真器把编译好的或者我们提供的现成的.hex文件烧入开发板,并在PC上通过可视化软件观察实验结果
5.实验步骤
1)启动WinAVR,编写实验代码,并建立Makefile文件。建立Makefile文件时,在文件中添加对MAC库文件的引用,即添加如下代码:
其中“E:/433mac”为存放MAC库文件的位置,这里假设库放在E盘的433mac目录下,库的名字为libmac433.a。
2)在app.c中的Init函数中修改OS_LOCAL_ADDRESS的值,给其赋值1(即发送节点),2,3,分别编译后获得3个.hex文件,切记每次编译后生成的文件名均为main.hex,所以编译后需要把生成的main.hex文件改名,以防下次编译把它覆盖,比如把OS_LOCAL_ADDRESS的值设为1,编译后生成的main.hex文件,需要改成1.hex,以此类推。
3)将.hex文件下载到节点中。
4)通过串口线连接1号节点(即烧入1.hex的节点)到PC,打开所有节点。
5)启动SNAMP可视化后台软件,通过SNAMP可以观察到3号节点的通信状况,如果节点之间位置摆放正确,就会看到3号节点每次都通过2号节点转发数据包到发送节点。
6)注意节点之间的摆放位置,3个节点摆放的很近,不容易出现多跳效果,为了最快出现自组织网络多跳效果,可以把3个节点摆放成一条直线,最好使1号和2号节点可以互相通信,2号和3号可以互相通信,而1号和3号之间不能直接通信。
6.思考题
1)为什么需要自组织网络?
2)为什么实验中节点的摆放位置会影响多跳效果?
3)如何将实验中演示的3个节点组网,改成4个或者更多个节点?
7.补充阅读
[1]李晓维,徐勇军,等.无线传感器网络技术[M].北京:北京理工大学出版社,2007.
[2]徐勇军,安竹林,等.无线传感器网络实验教程[M].北京:北京理工大学出版社,2007.
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。