基于蓝牙的室内定位硬件部分设计

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36278071/article/details/79174349

定位原理

  1. 蓝牙和WiFi信号都有信号衰减快的特性,在通信方面是一大弊端,但凡事都是有弊必有利。同样我们以可以利用他的这个特性,比如用作根据RSSI(信号强度)的定位。
  2. 之前苹果公司 就有一个可以粗略的计算距离的Ibeacon模块。但是他的局限性就是只能
    手机端通过对ibeacon的检测,算出ibeacon的大概距离。这样以来,如果我们做一个基于ibeacon的定位,那么每个标签就是一个ibeacon,按照市场价格一个ibeacon大约要33美元。很明显,它的优势不足以为高昂的价格买单。
  3. 蓝牙模块HC-05提供了丰富的AT指令,其中就有我们需要的用于查询RSSI的指令,可谓是:天助我也。/笑哭

所需材料

分类 所需材料
硬件部分 STC89C51单片机(带基本外围电路),ESP8266WiFi模块,HC-05蓝牙模块,USB-TTL模块,面包板,公对公 公对母 母对母杜邦线,(最好再有一个22.1184MHZ的晶振,如果你会改变ESP8266模块的波特率的话你也可以没有)。
软件部分 串口助手,网络串口助手,Keil编译器,单片机烧录软件。

前期准备

相关准备 参考意见
单片机串口通信 这个是必须的,大部分速度较快的模块都是通过串口方式通信的。所以学会了单片机的串口通信,可以做很多东西。不过话说回来其实每次写程序没必要每次都去写那些例如串口初始化啊这些函数,可以做一次,然后建立一个自己的代码库每次使用岂不方便。

实物图

单片机接线
这里需要注意的是面包板上我用的全部都是3.3V的电源,因为ESP8266要
求的是3.3V电源。而HC-05要求的是3.3V-5.0V的电源为了保证通信的正常
全部使用的是3.3V电源。
!!!!单片机仍用5V电源,因为我试了一下单片机在3.3V的时候有时候
会出现异常。
模块
这两个模块没什么好说的,唯一需要注意的是蓝牙模块按键的顺序,因为是提
前配置好的,所以每次长按KEY的时候,都会返回数据。
面包板
面包板上的线看似很乱,我也是为了方便检查错误,为了调试错误花了我两天
的时间。真的很烦!!将每个传送数据的端口都接在面包板上面,这样我们就
可以用USB-TTL很方便的检查每条线上的数据。这样有利于调试。

关键代码

基础代码:

//********************send message***********************
void UsartInit()
{
    SCON=0X50;      
    TMOD=0X20;          
    PCON=0X80;          
    TH1=0XFF;           
    TL1=0XFF;//Set baud rate to 115200bps.
    ES=1;                   
    EA=1;                   
    TR1=1;                  
}
void sendByte(uchar byte)
{
    SBUF=byte;
    while(!TI);
    TI=0;
}
void sendString(uchar *s)
{
    while(*s!='\0')
    {
        sendByte(*s);
        s++;
    }
}
void sendMsg(char* msg[]){
    ES=0;
    delayms(100);
    sendString(msg);
    delayus(100);
    ES=1;
}

核心代码:

void receiver() interrupt 4
{

    static char i=0;
    static char flag=0;
    char ch=0;
    static ch2=0;//ch2:How times get ',' to judge the end.

    ch=SBUF;
    if('+'==ch || flag==1){
        flag++;

        if('I'==ch){
            flag++;//flag=3
        }
        else if(flag==2) {
            flag=0;
        }
    }
    if(flag>=3){
        flag++;
        //this time get ':'.
        if(flag>7){
            if(ch==',')
            {
                ch2++;
            }
            if(ch2!=1){
               recMsg[i++]=ch;
            }
            if(ch2==2){
                end++;
                if(end==5){                 
                    recMsg[i++]='\r';
                    recMsg[i++]='\n';
                    recMsg[i++]='\0';
                    i=0;
                    flag=0;
                    ch2=0;

                }
            }           
        }
    }
    RI=0;
}

核心代码分析:

此代码用于对蓝牙模块返回的数据进行净化,过滤掉我用信息,然后将我们所需要的蓝牙地址、
RSSI值返回。以下是蓝牙返回的数据:
+INQ:1234:46:0,1F1F,FFC2
+INQ:C486:E9:1084A1,5A020C,FFC2
+INQ:21:13:18B45,0,FFC4
+INQ:B881:98:AEAF69,2A010C,FFD4
我们根据这个算法可以将这些数据`+INQ:`和两个逗号之间的设备类型给去掉。并在recMsg这个
全局数组结尾加上字符串结束符。

服务器程序编写

我用Java写了一个监听端口信息的程序,将获取到的有用数据保存到文本文件中。这个只是最初
的版本。详细请参考另一篇博客:

+Java端口监听

运行结果展示

运行结果

后续工作

现在基本上完成了硬件上的设计到数据的获取。后面我会利用获取到的数据进行函数拟合,得出
RSSI值到距离的映射关系。并将此套程序进行完善。

最后完整的代码我会在完全完成之后供上,各位莫急。有什么不妥的地方还请各位大侠不吝指教。

猜你喜欢

转载自blog.csdn.net/qq_36278071/article/details/79174349