基于ESP866和ESP8266通过RSSI的测距问题
本人目前打算在做一款用多个ESP8266进行室内定位手机位置的设备,(通俗的讲就是手机打开热点,ESP8266连接上这个热点就可以收集到当前手机的RSSI的值,通过数学公式即可计算出手机与ESP8266的大致距离)目前还属于测试阶段,现在已经可以做到用ESP8266检测与手机信号的RSSI值,但也出现了一些问题,现在我将我的思路分享给大家,希望能够给予大家帮助。
Arduino与ESP8266的串口通信
想要通过Arduino收集ESP8266的RSSI值首先要做到ESP8266与Arduino的串口通信
1.接线
接线如下
Arduino | ESP8266 |
---|---|
TX(1) | RX |
RX(1) | TX |
3.3V | VCC |
3.3V | CH_PD |
GND | GND |
2.程序
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial)
{
; // wait for serial port to connect. Needed for native USB port only
}
while(Serial.read()>=0){} //清空串口缓存
Serial.println("Goodnight moon!"); // set the data rate for the SoftwareSerial port
Serial1.begin(115200);
Serial1.println("AT");
}
void loop() { // run over and over
if (Serial1.available()) //判断串口1是否接收到数据(这里串口1指的是TX1和RX1)
{
Serial.write(Serial1.read()); //将串口1读到的数据发送给串口0(串口0指的是RX0)
}
if (Serial.available()) //判断串口0是否接收到数据
{
Serial1.write(Serial.read()); //将串口0读到的数据发送给串口1
}
}
将串口监视器打开, 格式和波特率按下图设置
输入AT后,看到OK即可进行下一步
ESP8266连接手机热点
1.重启ESP8266模块
看到返回OK即可
2.将ESP8266转换为AT+SAT模式
发送AT+CWMODE=3
看到返回OK即可
3.发送 AT+CWJAP=“热点名称”,“热点密码”
出现下图数据后即证明连接成功,现在打开手机后也可以看到ESP8266连接到手机热点
4.发送AT+CWJAP?查询当前热点信息,返回的数据分别为SSID,MAC地址,信道,RSSI
这里我们只要RSSI的值
提取并处理RSSI值
在这里我选择了最简单粗暴的方法来提取RSSI值
数据提取我用了两个Serial.readBytes()函数将RSSI的值提取出来,你可以研究下Serial.readBytes()函数的作用
程序如下
Serial.write(Serial1.readBytes(buffer1,49));
Serial.write(Serial1.readBytes(buffer2,5));
float i1= buffer2[0];
float i2= buffer2[1];
i1=i1-48;
i2=i2-48 ;
float rssi=i1*10+i2;
通过计算公式将RSSI值转换成距离
distance=(10^((abs(-rssi)-A)/(n*10)))
其中A为发射端和接收端相隔1米时的信号强度,n为环境衰减因子,这两个值是经验值,一般参考网上给出的数值是(A为59,n为2)这两个值可以根据实际情况来改
完整程序
char buffer1[50];
char buffer2[50];
float n=4.00;
float A=48.00;
float distance;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
while(Serial.read()>=0){}
Serial.println("Goodnight moon!");
// set the data rate for the SoftwareSerial port
Serial1.begin(115200);
Serial1.println("AT");
}
void loop() {
if (Serial1.available())
{
Serial.write(Serial1.readBytes(buffer1,49));
Serial.write(Serial1.readBytes(buffer2,5));
float i1= buffer2[0];
float i2= buffer2[1];
i1=i1-48;
i2=i2-48 ;
float rssi=i1*10+i2;
distance=pow(10,((abs(-rssi)-A)/(n*10)));//将RSSI的值转换成距离
Serial.println(":");
Serial.print("RSSI值:");
Serial.print(rssi);
Serial.print("距离:");
Serial.print(distance);
Serial.print("米");
}
if (Serial.available())
{
Serial1.write(Serial.read());
}
}
输入AT+CWJAP?
得到距离值为1.26米
本人经过几天的尝试后发现这个距离的数值有很大的误差和不缺定性,因为RSSI值与距离并不是线性关系,所以只能做粗略的距离计算,如果说你要做的高精度的距离测量,建议不要通过RSSI的值来计算。
以上即是本人通过RSSI来获得热点与ESP8266距离的经验,把我的经验分享给大家,希望能给予大家帮助
如有其它疑惑可以加本人QQ:1149484183
其它关于ESP8266的文章
关于Arduino使用软串口读取ESP8266模块数据不稳定的解决办法
用Arduino和esp8266检测WIFI信号强度