实验4 节点-PC串口通信实验

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验四节点-PC串口通信实验
实验目的
本实验的目的是实现节点和PC间的串口双向通讯,通过串口连接,PC可以从网络收集其他节点的数据,也可以发送数据或者命令到节点,因此,串口通信编程是无线传感器网络中的重要内容。

实验要求
根据例子提供的例子程序,详细了解程序结构,并尝试进行程序的修改运行。

具体实验要求如下:
1.了解掌握串口双向通信的方法,学会使用mig工具以及SerialForwarder;
2.修改BlinkToRadio程序,使用mig创建BlinkToRadioMsg的java 对象发送至BaseStation,然后使用MsgReader读取该对象内容。

实验内容
1、TestSerial例子程序
节点与PC之间的通信在TinyOS中被抽象为数据包源(packet source)。

一个数据包源就是一种与节点双向通信的介质,可以是串口,也可以是TCP socket,或是SerialForwarder工具(该工具后面介绍)。

先看以下示例程序,将一个节点连接到PC,进入TestSerial例子程序目录,
这时节点的LED灯会闪烁。

此时表明节点与串口双向通信正常。

2、基站程序示例
基站节点是无线传感器网络的重要组成部分,它负责与后台服务器进行串口通信以及与网络中的其他节点进行无线通信,是一个桥梁的作用。

取两个节点,一个节点烧录BlinkToRadio程序,一个烧录BaseStation程序,将两个节点都通电。

可以看到BaseStation的LED1等闪烁,按住BlinkToRadio节点的RESET,LED1不闪烁。

BaseStation节点的LED0闪烁表示它收到了网络包,LED1闪烁表示将网络包发送到串口,LED2闪烁表示网络包被丢弃,丢弃的原因可能是串口的带宽小于节点的无线带宽。

Listen命令的功能是创建数据包源,然后打印出每一个监听到的包。

BlinkToRadioC应用的消息格式如下(忽略开始的00字节):
•目标地址Destination address(2 bytes)
•连接源地址Link source address(2 bytes)
•消息长度Message length(1 bytes)
•组号 Group ID(1 byte)
•Active Message handler类型Active Message handler type(1 byte)•Payload(最大28 bytes)
源节点ID Source mote ID(2 bytes)
示例计数值Sample counter(2 bytes)
3、MIG及数据包对象
Listen程序是与节点通讯最基础的方式。

但是它只打印了二进制的包。

显然这种方式不是十分易读。

在实际中,往往需要读取这些二进制数据后,再根据二进制的内容分析其字段。

TinyOS提供了一种方便解析二进制数据包内容的工具-MIG(Message InterFace Generator)。

MIG可以为用户指定的消息结构建立一个Java,Python或C的接口,免除了解析二进制的麻烦。

进入到TestSerial目录下,输入make clean清除上次的编译结果。

然后输
这个输出表示在编译TinyOS应用程序之前,Makefile中要求先生成TestSerialMsg.java文件,然后将TestSerialMsg.java和TestSerial.java进行编译,最后再编译TinyOS应用程序。

打开TestSerial目录下的Makefile文
BUILD_EXTRA_DEPS这行说明TinyOS应用生成以前要先编译
说明TestSerialMsg.java是TestSerial.class的依赖文件,在编译生成TestSerial.class之前需要生成TestSerialMsg.java。

4、SerialForwarder和其他数据包源
直接监听串口的问题就是只能与一个程序进行读取,因为这是一个硬件资源。

并且需要监听程序物理连接到串口才可以进行读取。

为解决以上限制,TinyOS 中的SerialForwarder工具提供了一个解决方案。

一般来说,SerialForwarder工具连接一个真实的物理串口,然后在此之上创建一个虚拟数据包源,然后允许同时多个程序通过TCO/IP连接来访问这个数据包源。

可以看出,SerialForwarder相当于物理串口的读写包的代理。

HOST和PORT是可选的。

默认状态是localhost和9002端口的。

会弹出一个窗口。

这表示已经成功创建了一个数据包源sf,它的地址是本地的9001端口。

这条命令创建了第2个sf,它的源是工作在9001端口上的第1个sf,第一个sf的引用数会增加1。

这里仅仅是演示需要,将第2个sf(9003)关闭。

可以观察到第一个sf的引用数加1,并且使用MsgReader开始打印内容,与上一节结果类似。

除了串口和SerialForwarder以外,TinyOS还支持Crossbow MIB 600
5、向串口发送数据包
在TinyOS中向串口发送一个AM类型的数据包与通过radio发送是非常相似的。

可以使用AMSend接口,调用AMSend.send发送数据包,然后处理
其中SerialActiveMessageC用来打开和关闭栈,其余两个分别为收发组件。

组件接口上的相似,也带来了实现上的相似。

如下所示:
实验要求说明
实验具体要求,修改BlinkToRadio程序,使用mig创建BlinkToRadioMsg 的java对象,BaseStation(该程序不改动)将BlinkToRadio发送的消息转发到串口,然后使用MsgReader读取BlinkToRadioMsg对象。

提示步骤:
1.按照TestSerial例子修改makefile。

注意,javac后面应该接一个tab字符而不是空格。

2.然后输入make telosb命令生成BlinkToRadioMsg的java类。

就需要将AM类型从AM_BLINKTORADIO改为AM_BLINKTORADIOMSG,这是mig 命名规则的需要。

然后再次编译烧录。

3.BaseStation节点与修改后的BlinkToRadio节点都通电。

然后在
实验过程说明
首先需要修改节点通信的相关信道,选择26信道,在Makefile文件中进行修改,PFLAGS+=-DCC2420_DEF_CHANNEL=26。

对BlinkToRadio程序中的Makefile 文件进行修改,使用mig创建BlinkToRadioMsg的java对象:BlinkToRadioMsg.java:
mig java -target=null $(CFLAGS) -java-classname=BlinkToRadioMsg BlinkToRadio.h BlinkToRadioMsg -o $@
申请节点,自动分配为3号和4号节点,将3号节点作为普通节点,烧录BlinkToRadio程序,4号节点作为基站节点,烧录BaseStation程序,可以看到4号节点的LED1灯在不停的闪烁,说明基站节点不停的收到网络包并将其发送至串口。

由于缺少MsgReader 命令,实验中使用Listen命令进行代替,对4号节点即基站节点进行读数,结果如下图所示:
图中每一行代表基站节点收到的一个网络包,最后二个字节代表的是计数值,可以看到为递增数。

修改后的核心程序清单
BlinkToRadioC.nc
implementation {
uint16_t counter;
message_t pkt;
bool busy = FALSE;
void setLeds(uint16_t val) {
if (val & 0x01)
call Leds.led0On();
else
call Leds.led0Off();
if (val & 0x02)
call Leds.led1On();
else
call Leds.led1Off();
if (val & 0x04)
call Leds.led2On();
else
call Leds.led2Off();
}
event void Boot.booted() {
call AMControl.start();
}
event void AMControl.startDone(error_t err) {
if (err == SUCCESS) {
call Timer0.startPeriodic(TIMER_PERIOD_MILLI);
}
else {
call AMControl.start();
}
}
event void AMControl.stopDone(error_t err) {
}
event void Timer0.fired() {
counter++;
if (!busy) {
BlinkToRadioMsg* btrpkt =
(BlinkToRadioMsg*)(call Packet.getPayload(&pkt, sizeof(BlinkToRadioMsg))); if (btrpkt == NULL) {
return;
}
btrpkt->nodeid = TOS_NODE_ID;
btrpkt->counter = counter;
if (call AMSend.send(AM_BROADCAST_ADDR,
&pkt, sizeof(BlinkToRadioMsg)) == SUCCESS) {
busy = TRUE;
}
}
}
实验感想
节点与PC之间的通信是无线传感网里获取数据的最后一步,Sink节点即使获取到很多数据,如果不能传送给后方数据库,那么一切都没有意义。

通过阅读代码,明白了节点与PC串口之间收发数据大致是怎么一个流程。

相关文档
最新文档