RSSI定位
基于RSSI的定位设计
1、实验目的
理解并掌握射频信号强度的测量原理和方法,学习电磁波空间传播模型
理解RSSI与距离的关系
掌握基于RSSI的WSN测距/定位原理及方法
2、实验内容
一个节点通过射频向另一个节点发送信息,接收节点向串口打印输出接收的信息内容和RSSI值。
测量并记录两个通信节点不同间距对应的RSSI值,利用matlab拟合Shadowing模型参数。
布设盲节点与3个参考节点,节点组网后,盲节点周期性的广播消息给周围的参考节点以获取它们的坐标及信号强度,然后上传获取到的RSSI信息及参考点位置信息给Sink节点。记录实验结果并选用多边定位算法计算盲节点位置。
3、预备知识
IAR集成开发环境中编写和调试程序的基本过程
定位、参考/盲节点、RSSI概念。
4、实验设备及工具
硬件:物联网网关及基础实验平台、无线智能传感节点、传感器模块、物联网与智能控制平台、频谱仪、计算机
软件:软件:PC 机操作系统WinXP/Win7 、IAR集成开发环境、
串口调试助手、SmartRF Flash Programmer 烧写软件
5、实验原理
CC2431有一个内置的接收信号强度指示器,其数值为8位有符号的二进制补码,可以从寄存器RSSIL.RSSI_VAL读出,RSSI值总是通过8个符号周期内,取平均值得到的,此为获得RSSI的一种方法,但是当数据接收以后这个寄存器没有被锁定,因此不宜把寄存器RSSIL.RSSI_VAL的值作为RSSI值。
当MDMCTRL0L.AUTOCRC已经设置为1时两个FCS字节被RSSI值、平均相关值(用于链路质量指示LQI)和CRC OK/not OK所取代,第一个帧校验序列(FCS)字节被8位的RSSI值取代。可以在接收数据时读出。最后将接收的数据和RSSI值打印输出。
6、设计思路
按照实验的要求,因为只有一个信道,就通过不同的时隙发不同定节点的信息,使用盲节点进行接收RSSI信息,然后通过Matlab运算计算出距离,根据距离来估计盲节点的位置。
7、实现方式
首先是盲节点广播一个信息用作同步,然后定节点收到广播信息之后,开始进行计时,并在自己的时隙内发送RSSI信息。
8、硬件代码
#include "hal.h"
#include"ioCC2430.h"
#include"console.h"
/********************************************************** ********************
* CONSTANTS
*/
#define ADDRESS_0 0x02
#define ADDRESS_1 0x08
#define ADDRESS_2 0x09
#define ADDRESS_3 0x0a
#define ADDRESS_4 0x0b
#define ADDRESS_5 0x0c
#define BROADCAST_ADDRESS 0xFF
#define SEND_NODE 0
#define RECEIVE_NODE 1
/********************************************************** ********************
* LOCAL VARIABLES
*/
UINT8 node_type,sendcount=2;
UINT8 myAddr;
UINT8 remoteAddr;
BOOL remoteAddressSet;
BOOL myAddressSet;
UINT8 channel;
UINT8 payload[13]="node 1";
BYTE *received_packet;
BYTE received_length;
WORD timeout=5000;
BYTE rssi_reg,rssi_crc;
extern void radioInit(UINT8 channel, BYTE localAddress); void rf_test_main(void);
void halInitUart(void) {
// Setup for UART0
// IEN2 &= 0x0d;
IO_PER_LOC_USART0_AT_PORT0_PIN2345();
UTX0IF = 1;
}
void main(void)
{
SET_MAIN_CLOCK_SOURCE(CRYSTAL);
halInitUart();
UART_SETUP(0, 57600, HIGH_STOP);
INT_GLOBAL_ENABLE(INT_ON);
rf_test_main();
DISABLE_ALL_INTERRUPTS();
}
void initRfTest(void)
{
channel = 22;
//node_type = SEND_NODE;
node_type = RECEIVE_NODE;
if(node_type == SEND_NODE)
{
myAddr = ADDRESS_1;
remoteAddr = ADDRESS_0;
}
else
{
myAddr = ADDRESS_0;
remoteAddr = BROADCAST_ADDRESS;
}
radioInit(channel, myAddr);
}
void rf_test_main(void){
initRfTest();
BOOL send_status, receive_status;
if(node_type == SEND_NODE)
{
receive_status=halRfReceivePacket();
if(receive_status)
{
while(1)
{
halWait(250);halWait(250);halWait(250);halWait(250);
send_status=halRfSendPacket(payload,13);
halWait(250);halWait(250);halWait(250);halWait(250);
halWait(250);halWait(250);halWait(250);halWait(250);
halWait(250);halWait(250);halWait(250);halWait(250);
}
}
if(send_status)
{
conPrintROMString("packet sent successfull!"); }
else
{
send_status=halRfSendPacket(payload,13); conPrintROMString("\npacket sent failed!"); }
}
else
{
send_status=halRfSendPacket(payload,13); conPrintROMString("packet sent successfull!"); while(1)
{
receive_status=halRfReceivePacket();
if(receive_status)
{
conPrintString (received_packet);
conPrintROMString("\nrssi value in register FCS position:\n");
conPrintData(&rssi_crc, 1);
receive_status=0;
}
}
}
return;
}
Matlab定位代码
syms a b
n=5.33;% 计算和测量得到的公式中的参数
d02=-5;
d03=-2;
pd1=5;
pd2=-15;
pd3=-3.3;
d1=10^((d01-pd1)/(10*n));%计算盲节点到各个定节点的距离
d2=10^((d02-pd2)/(10*n));
d3=10^((d03-pd3)/(10*n));
x1=0;y1=0;%设定的三个定节点坐标
x2=0;y2=1;
x3=1;y3=1;
f1=(a-x1)^2+(b-y1)^2-d1^2;%通过距离确定交点的方程
f2=(a-x2)^2+(b-y2)^2-d2^2;
f3=(a-x3)^2+(b-y3)^2-d3^2;
s1=solve(f1,f2);a1=double(s1.a);b1=double(s1.b);%计算交点位置(6个解)
s2=solve(f2,f3);a2=double(s2.a);b2=double(s2.b);
s3=solve(f1,f3);a3=double(s3.a);b3=double(s3.b);
e1(1)=sqrt(((x1-a1(1))^2+(y1-b1(1))^2));%选取靠内的三个交点
e1(2)=sqrt(((x1-a1(2))^2+(y1-b1(2))^2));
if e1(1)<=e1(2)
m1(1)=a1(1);m1(2)=b1(1);
else
m1(1)=a1(2);m1(2)=b1(2);
end
e2(1)=sqrt(((x2-a2(1))^2+(y2-b2(1))^2));
e2(2)=sqrt(((x2-a2(2))^2+(y2-b2(2))^2));
if e2(1)<=e2(2)
m2(1)=a2(1);m2(2)=b2(1);
else
m2(1)=a2(2);m2(2)=b2(2);
end
e3(1)=sqrt(((x3-a3(1))^2+(y3-b3(1))^2));
e3(2)=sqrt(((x3-a3(2))^2+(y3-b3(2))^2));
if e3(1)<=e3(2)
m3(1)=a3(1);m3(2)=b3(1);
else
m3(1)=a3(2);m3(2)=b3(2);
end
l1=(m1(1)+m2(1)+m3(1))/3;%取靠内的三个交点的x,y平均值
l2=(m1(2)+m2(2)+m3(2))/3;
plot(l1,l2,'o'); hold on
plot(x1,y1,'ro',x2,y2,'ro',x3,y3,'ro')
9、设计时遇到的问题
(1)节点信号发送接收问题
在初次代码时候,是定节点定时发送RSSI信息,盲节点每个时隙接收一次,然后就出现了盲节点一直通过串口发送的是只有一个定节点的信息,而且信息更新速度缓慢。
后来通过对CC2431实验平台的不断使用,发现初次代码中盲节点的串口通讯是通过接收寄存器来触发的,所以后面将盲节点的接收改为信道信息触发的方式而不是定时的方式,每次接收通过串口发送之后就将寄存器信息清空,然后等待下次信息来临的触发。从而解决了硬件方面的问题。
(2)matlab定位问题
在理想情况下,以三个定节点为圆心,各自与盲节点的距离为半径的圆会交于一点;但是实际测量中,因为有误差因素,导致三组方程出现6个解(即三圆两两相交,产生6个交点,如图)。在初始设计中,未能很好解决这个问题,不知道选取哪个交点作为定位出的盲节点位置。
经过进一步研究,选取靠内的三
个交点(即图中的1、2、3号交点),
去它们的坐标的平均值作为最终定位
的盲节点坐标。
10、设计结果
说明:红色为定节点的坐标,蓝色为定位出的盲节点坐标。