如何用蓝牙实现无线定位(三)--本地定位显示

news2024/12/24 3:34:28

1. 被定位目标

       本项目设计有两个定位装置,一个用于固定目标,一个用于可移动设备。在定位系统的帮助下,我们可以操作可移动设备向固定目标移动。假设这是一个救援场景的话,我们就可以把固定的目标看作等待救援的人或物,把可移动的设备看作前来救援的机器人。

2. 构建待救援者的定位设备

       定位设备主要由1个Arduino Mega2560控制板、1个Bigfish扩展板、2个BLE4.0模块构成。在本实验中,我们为目标安装1个OLED显示屏,以便在调试时查看坐标值。

       两个BLE4.0模块中的一个用于接收3个信号塔的信号(主),在控制板中计算后生成坐标信息。坐标信息可以在OLED显示屏上显示出来,并可以通过另一个BLE4.0模块发送出去(从)。从BLE4.0模块在本功能中暂时用不上,后续的远程定位功能将会用到。

       按照上面的针脚使用杜邦线将待救援设备的主蓝牙和从蓝牙连接到主控板上,注意错误的连接会导致模块损坏

3. 目标的BLE4.0a蓝牙模块配置。

       目标的主蓝牙需要接收三个信号发射塔的信号,从而通过三点定位的算法计算出自己当前的位置信息,并发送显示。

使用下面的命令,配置目标的主蓝牙:

AT+RENEW    //恢复默认设置

AT -- OK//测试模块正常

AT+ADDR? -- MAC//查询模块MAC地址

AT+BAUD0 -- 9600//设置波特率为9600

AT+CLEAR -- OK//清除设备配对信息

AT+IMME1 -- OK    //设置模块工作类型:上电等待触发

AT+ROLE1 -- OK        //设置主从模式:主设备

AT+MODE1 -- OK//设置模块工作模式:远控模式

       各设备主从蓝牙的MAC地址(以下地址可根据自己的BLE4.0a蓝牙模块的实际MAC地址进行修改,详细参考:蓝牙配置说明.txt

信号塔MAC地址:

0:D8A98B788750 (从)

1:D8A98B788732 (从)

2:380B3CFFC5B0 (从)

目标1设备地址:

B:F83002253178 (从)

主:D8A98B788758 (主)

4. 坐标位置的本地显示

将OLED模块按如图所示的方法连接在Bigfish扩展板上

 按照上面的针脚使用杜邦线将OLED显示屏连接到主控板上,注意错误的连接会导致模块损坏

5. 位置的获取与发送

烧录以下程序(human_rssi.ino),移动目标的位置,可观察到OLED模块显示坐标值的变化。

注意:该例程仅作调试使用,后期构建完整系统时会使用新的程序。

/*------------------------------------------------------------------------------------

  版权说明:Copyright 2022 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.

           Distributed under MIT license.See file LICENSE for detail or copy at

           https://opensource.org/licenses/MIT

           by 机器谱 2022-5-30 https://www.robotway.com/

  -------------------------------------------------------------------------------------*/

//蓝牙4.0无线连接定位实验:待救援主控接收例程

//配置模块:(模块在配置时与正常工作时TX、RX线序不同,请注意)

//第一步:使用AT指令将所使用的四个模块其中一个设置为主模式,其余三个为从模式;所有模块波特率全部为默认的9600,并记录三个从模块的地址(AT+ADDR?);

//第二步:将主模块在未连接时清除之前的配对信息(AT+CLEAR),再设置其工作类型为类型1(AT+IMME即上后处于等待状态,收到AT+START,AT+DISC,AT+CONNL等指令后开始工作);

//开始工作:

//第三步:将所有模块上电(主模块使用杜邦线接在MEGA2560上,从模块只给两个电源引脚提供3.3或5V电源即可);

//第四步:将本程序下载进MEGA2560中,将从模块分别摆开,观察显示屏数据;

//按救援机器人的场地在信号塔位置放置3个从模块,主模块放置在中间区域;

//本实验使用的3个从模块地址分别为:

/*********从设备地址********/

// "D8A98B788750",

// "D8A98B788732",

// "380B3CFFC5B0"

/*********从设备地址********/

/**********头文件***************/

#include <Arduino.h>

#include <Wire.h>

#include <MultiLCD.h>

#include <RssiPositionComputer.h>

/***********宏定义**************/

#define DEBUG_SERIAL Serial //打印信息串口

#define CON_SERIAL Serial1 //蓝牙通信串口

#define SEND_SERIAL Serial2 //数据发送串口

#define CMD_CON "AT+CON"

#define CMD_DIS_CON "AT"

#define CMD_GET_RSSI "AT+RSSI?"

LCD_SSD1306 lcd;

RssiPositionComputer myPositionComputer;

Point2D master_point;

//基站数量

#define SLAVENUMBER 3

//基站地址

String BLUETOOTHADDRESS[3] = {

"D8A98B788750",

"D8A98B788732",

"380B3CFFC5B0"

};

//位置发送蓝牙地址

// D8A98B788758

String search_result_string[SLAVENUMBER] = {""};

String rssi[SLAVENUMBER] = {""};

float distance[SLAVENUMBER] = {};

void setup()

{

#if defined(DEBUG_SERIAL)

DEBUG_SERIAL.begin(9600);

#endif

CON_SERIAL.begin(9600);

SEND_SERIAL.begin(9600);

delay(1000);

lcd.begin();

lcd.clear();

lcd.setCursor(25, 3);

lcd.print("Hello World!");

delay(1000);

init_ble();

}

void loop()

{

read_ble(BLUETOOTHADDRESS);

to_axis(distance, &master_point);

}

//读取串口

String serial_read(int _len)

{

String data = "";

int len = 0;

unsigned long t = millis() + 500;

while(1)

{

while(CON_SERIAL.available())

{

char c = CON_SERIAL.read();

data += c; len++;

}

if(len == _len)

{

Serial.println("the len");

Serial.println(data);

break;

}

if(millis() > t)

{

Serial.println("the t");

Serial.println(data);

break;

}

}

#if defined(DEBUG_SERIAL)

//DEBUG_SERIAL.println(data);

#endif

return data;

}

//初始化

void init_ble()

{

CON_SERIAL.print(CMD_DIS_CON);

delay(100);

serial_read(2);

}

//获取设备 RSSI

void read_ble(String * address)

{

for(int i=0;i<SLAVENUMBER;i++)

{

CON_SERIAL.print(CMD_DIS_CON);

delay(100);

serial_read(2);

CON_SERIAL.print(CMD_CON + address[i]);

serial_read(8);

delay(500);

CON_SERIAL.print(CMD_GET_RSSI);

String rssi_str = serial_read(10);

String _rssi = rssi_str.substring(7, rssi_str.length());

//rssi

rssi[i] = _rssi;

//distance

distance[i] = rssiToDistance(rssi[i].toFloat());

#if defined(DEBUG_SERIAL)

DEBUG_SERIAL.println("BLE_" + String(i) + ": " + rssi[i]);

//DEBUG_SERIAL.println("BLE_" + String(i) + ": " + distance[i]);

#endif

//delay(800);

}

}

//计算距离

float rssiToDistance(float rssi)

{

float dis = 0;

//dis = pow(10.0,((abs(rssi)-56)/10.0/1.05));

dis = pow(10.0,((abs(rssi)-56)/5.0/1.65));

return dis;

}

//转换为2d坐标x,y

void to_axis(float * dis, Point2D* actual_master_point)

{

//myPositionComputer.distanceToPoint(*dis,*(dis+1),*(dis+2),actual_master_point);   

myPositionComputer.distanceToPoint(*dis,*(dis+1),random(0,77),actual_master_point);

int x = master_point.x*100;

int y = master_point.y*100;

char point[100];

sprintf(point, "[ax:%3d,ay:%3d]\n",abs(x),abs(y));

#if defined(DEBUG_SERIAL)

DEBUG_SERIAL.println(point);

lcd.clear();

lcd.setCursor(10, 1);

lcd.print("a: human");

lcd.setCursor(25, 5);

lcd.print(point);

#endif

SEND_SERIAL.print(point);

}

6. 待救援定位装置的摆放

       使用下图场地进行构建,在信号塔的位置分别放置三个信号发射塔,将待救援定位装置尽量放置在三个信号塔连线构成的三角形内。依次开启3个信号塔、目标的电源,观察目标的OLED屏幕上显示的坐标位置值(注:目标的电源必须最后打开)

定位效果如下图所示:

 

7. 资料内容

① 函数库

② 目标定位设备调试例程

③ 蓝牙配置说明.txt 

资料内容下载请参考如何用蓝牙实现无线定位

---------------------------------------------------未完待续---------------------------------------------------

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/51253.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【使用 BERT 的问答系统】第 2 章 :用于自然语言处理的神经网络

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

大数据开发之词频统计传参打包成jar包发送到Hadoop运行并创建可执行文件方便运行

文章目录添加spark的jar包main传参调试打包成jar包发送到Hadoop运行使用脚本运行参考添加spark的jar包 点击Project Structure Global Libararies中 点击 选择java 然后选择spark文件里的jars下所有的jar包 然后点击ok即可。 main传参调试 首先给出词频统计代码 //包 imp…

OpenCV图像处理——光流估计

总目录 图像处理总目录←点击这里 二十二、光流估计 22.1、原理 光流 是空间运动物体在观测成像平面上的像素运动的“瞬时速度”&#xff0c;根据各个像素点的速度矢量特征&#xff0c;可以对图像进行动态分析&#xff0c;例如目标跟踪。 亮度恒定&#xff1a;同一点随着时…

HTML5期末考核大作业——学生网页设计作业源码HTML+CSS+JavaScript 中华美德6页面带音乐文化

&#x1f468;‍&#x1f393;静态网站的编写主要是用HTML DIVCSS JS等来完成页面的排版设计&#x1f469;‍&#x1f393;,常用的网页设计软件有Dreamweaver、EditPlus、HBuilderX、VScode 、Webstorm、Animate等等&#xff0c;用的最多的还是DW&#xff0c;当然不同软件写出的…

LeetCode HOT 100 —— 76 .最小覆盖子串

题目 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空字符串"" 。 思路 **滑动窗口&#xff1a;**题目要求返回字符串s中包含字符串t的全部字符的最小窗口&#xff0c;即包含t的…

世界杯的那些二三事

文章目录 &#x1f525;关于世界杯 &#x1f525;关于2022卡塔尔世界杯 &#x1f525;我与世界杯 ⚽分享一颗足球 ⚽实现效果 &#x1f525;关于世界杯 大力神杯 国际足联世界杯&#xff08;FIFA World Cup&#xff09;&#xff0c;简称“世界杯”&#xff0c;是由全世界…

【自然语言处理(NLP)】基于Bi-DAF的机器阅读理解

【自然语言处理&#xff08;NLP&#xff09;】基于Bi-DAF的机器阅读理解 作者简介&#xff1a;在校大学生一枚&#xff0c;华为云享专家&#xff0c;阿里云专家博主&#xff0c;腾云先锋&#xff08;TDP&#xff09;成员&#xff0c;云曦智划项目总负责人&#xff0c;全国高等学…

java+jsp基于ssm汽车配件管理系统-计算机毕业设计

项目介绍 本汽车配件管理系统是针对目前网上车企的实际需求&#xff0c;从实际工作出发&#xff0c;对过去的汽车配件管理系统存在的问题进行分析&#xff0c;结合计算机系统的结构、概念、模型、原理、方法&#xff0c;在计算机各种优势的情况下&#xff0c;采用目前最流行的…

利用Python生成随机密码,灰常简单,小伙伴可以试试哟

知识点 文件读写 基础语法 字符串处理 字符拼接 Python合集视频 【整整800集】Python爬虫项目零基础入门合集&#xff0c;细狗都学会了&#xff0c;你还不会&#xff1f;代码解析 导入模块 import platform import string import random将string的几大字符串拼接在一起&…

Spring Boot实现任意位置的properties及yml文件内容配置与获取

〇、参考资料 1、Spring Boot 中文乱码问题解决方案汇总 https://blog.51cto.com/u_15236724/5372824 2、spring boot读取自定义配置properties文件★ https://www.yisu.com/zixun/366877.html 3、spring boot通过配置工厂类&#xff0c;实现读取指定位置的yml文件★ https://b…

TensorFlow之文本分类算法-5

1 前言 2 收集数据 3 探索数据 4 选择模型 5 准备数据 6 模型-构建训练评估 构建输出层 构建n-gram模型 根据前面章节的描述&#xff0c;n-gram模型是独立地处理分词&#xff0c;与原文中的单词顺序不相关。简单的多层神经感知&#xff08;逻辑回归&#xff09;、梯度推…

SCP命令在不同远程服务器之间发送文件(指定端口)

最近想把数据集放在另一个服务器上&#xff0c;但是如果先下载到本地然后再上传过去&#xff0c;则需要浪费好久时间。 特总结下如何快捷的通过命令完成不同远程服务器之间的文件传输&#xff0c;以及遇到的问题。 SCP命令 Linux scp 命令用于 Linux 之间复制文件和目录。1 s…

第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(上海),签到题6题

文章目录E.Strange IntegersD.Strange FractionsG.Edge GroupsI.Steadily Growing SteamH.Life is a GameK.Circle of Life补题链接&#xff1a;https://codeforces.com/gym/103446 E.Strange Integers E. Strange Integers time limit per test1 second memory limit per te…

搭建Docker+SRS服务器实现推流拉流的效果

最初的一个想法&#xff0c;是针对当前的网络电视去的&#xff0c;很多网络电视买回家&#xff0c;还要充很多会员&#xff0c;甚至跌入连环坑。我想给妈妈买一台电视&#xff0c;想把我自己收集的电影电视剧做成一个影视库&#xff0c;通过搭建家庭影院服务器&#xff0c;然后…

基于PHP+MySQL保险理赔系统的设计与实现

随着我国经济的发展,车辆的数量也在不断的增加相对应的车辆保险理赔的数量也在不断的增加,但是目前市面上很多理赔要么就是通过手工管理的方式进行管理,要么就是管理软件太过于的专业,为了能够让大众都能够在线通过网络进行在线理赔,我开发了本系统。 本设计尝试用PHP开发一个保…

SpringCloud_第3章_微服务保护_Sentinel

SpringCloud_第3章_微服务保护 文章目录SpringCloud_第3章_微服务保护1.初识Sentinel1.1.雪崩问题及解决方案1.1.1.雪崩问题1.1.2.超时处理1.1.3.仓壁模式1.1.4.断路器1.1.5.限流1.1.6.总结1.2.服务保护技术对比1.3.Sentinel介绍和安装1.3.1.初识Sentinel1.3.2.安装Sentinel1.4…

vue2.x和vue3.x 环境相关配置

1.vue2.x配置多个环境 在根目录下创建多环境配置文件 例如&#xff1a; env.devlopment、env.prod、env.sit等&#xff0c;我的环境文件有以下几个: 分别配置各文件的参数 比如说uat环境和生产环境请求url是不同的 uat环境env.uat: # uat环境 NODE_ENV uat# uat环境请求…

java锁

java锁 乐观锁和悲观锁 悲观锁 悲观锁认为自己在使用数据的时候一定有别的线程来修改数据&#xff0c;因此在获取数据的时候会先加锁&#xff0c;确保数据不会被别的线程修改。 悲观锁的实现方式 synchronized关键字Lock的实现类都是悲观锁 适合写操作多的场景&#xff0c;…

面向物联网应用的6G技术

摘要 在物联网(Internet of Things,IoT)快速发展和5G已经规模化的商业部署的背景下,在不久的将来,5G的技术指标将无法完全满足大规模IoT的应用需求。而6G技术由于其具备高传输、低时延等出色的性能指标,受到了学术界和工业界的广泛关注。因此,为了促使IoT网络能够更好地发…

此框架是SQL Server增量订阅,用来监听增删改数据库数据变更

目前仅支持SQL Server&#xff0c;后续会支持MySQL和Oracle&#xff0c;Nuget上可以下载安装 或者使用Nuget命令添加包 dotnet add package Kogel.Subscribe.Mssql --version 0.0.0.1 可以用来处理DB主从同步&#xff0c;跨库同步&#xff0c;数据备份&#xff0c;同步ES&…