1.CTP协议
CTP协议是一种汇聚树协议,子节点收集的数据通过传感网络(WSN),经过多跳将数据最终传递到根节点(root)。
2.如何获得数据包到达根节点的路径
我使用的方法:
TinyOS中CTP协议中,有一个 Intercept 接口,通过查看Intercept.nc文件我们可以发现,其中有一个event函数
interface Intercept
{
event bool forward(message_t* msg, void* payload, uint8_t len);
}
forward事件函数主要功能:当节点接收到一个要转发的消息包时,汇聚服务应当触发这个事件。返回值为 TRUE 时,可以转发这个包,反之,返回值为 FALSE 则不能转发这个包。
所以实现forward函数的时候,我将要转发的数据包的跳数,以及来自的源节点标号,用一个数组记录。
oscilloscope_t *in = (oscilloscope_t*) payload;
oscilloscope_t *out;
int parentIndex = (int)call CtpPacket.getThl(msg);//获得跳数(就是前面经过了多少跳)
in->parent[parentIndex-1] = TOS_NODE_ID;//将产生数据根源节点的ID存入数组
in->hopRssi[parentIndex-1] = call CC2420Packet.getRssi(msg);//将这一跳的RSSI信息存入数组
return TRUE;
3.如何利用传感器节点感知信道能量
看到有论文中写道,可以使用telosb节点来感知信道能量,从而获得WiFi网络的一些信息,或者利用WiFi AP周期性的beacon发送来使传感器网络,根据这个有规律的beacon,来调整时钟,从而达到传感器网络的时钟同步。前提条件:WiFi网络和ZigBee网络公用ISM 2.4GHz频段,信道存在重合。
如何用telosb节点感知信道能量:
前面的笔记中写道,获得包的RSSI可以通过 CC2420Packet 的getRssi函数,然而那是WSN中,收到了一个包才能获得的数据。而我想做的是,不需要发送包,而是直接感知信道的能量(RSSI)。
通过查阅 cc2420手册 以及 TEP cc2420 radio stack,有寄存器(Register)专门存感知信道的RSSI,只要不断地向这个存放RSSI的register获得数据,就能实时获得信道的能量变化了。
获取该RSSI Register方法:
利用 CC2420ControlC组件 组件提供的 Read接口(在CC2420ControlC中被命名为ReadRssi)即可以访问存放RSSI的Register。
use
{
interface Read[uint16_t] as ReadRssi; //明确使用的接口
}
//要获取Register中的Rssi,首先使用read()函数
call ReadRssi.read();//因为是command函数,所以要call
//关键的一步,实现自己的readDone函数
//data 即为你所读到的值
event void ReadRssi.readDone(error_t error, uint16_t data)
{
local.etx = data;//将data记录下来
//SerialSend.send函数是将数据通过串口发送的终端,以便于显示查看。
call SerialSend.send(0x1818, &local, sizeof(local));
}
最后,我发现TinyOS-2.1.2中竟然提供了一个简单的Demo,跟我上面写的是一样一样的。。。具体在 apps/test/cc2420/RssiToSerial 中。
原始读数转换为dBm:
在不使用 RssiToSerial 中提供的Java类观察的情况下,我从串口直接获得了Register中的RSSI读数,然而数据是类似“4F,56…”这样的 16进制 数,如何转换为dBm呢?
千辛万苦查阅资料以及上网搜索才找到答案,具体是:
//我们设原始获得的数据是val
dBm = (int8_t) (((val - 0x7F) & 0xFF) -45);
//简单的换算
temp = int(val,16) //将val转换为10进制数
dBm = temp -127 -45; //再将10进制数减去127,然后再减去45(cc2420手册中说的偏移量45)
4.使用TinyOS中写好的Java类
在TinyOS的很多Demo中,都已经为我们写好了Java类,这样大大方便了我们对结果观察。
以RssiDemo为例:
具体RssiDemo的位置在apps/tutorials/RssiDemo中。我们编译完并将程序烧写进节点,一个SendingMote,用来发送数据包;一个是RssiBase用来收包并把获得数据包的RSSI,然后将其通过串口发送的PC端。
该例子提供了Java类,让我们能更直接的观察到每个包的RSSI。要运行Java类,首先有一个 重要的步骤:设置MOTECOM这个变量,即告诉Java类,该从哪个串口获取信息,即你的RssiBase插在哪个串口。这样才能正确运行Java程序。
具体设置步骤:
//不同类型的波特率
export MOTECOM=serial@COM1:19200 # mica baud rate
export MOTECOM=serial@COM1:mica # mica baud rate, again
export MOTECOM=serial@COM2:mica2 # the mica2 baud rate, on a different serial port
export MOTECOM=serial@COM3:57600 # explicit mica2 baud rate
//对于我们的telosb节点
export MOTECOM=serial@/dev/ttyUSB0:telos //USB0只是个例子,具体用motelist指令查看传感器插在哪个串口。