• 童话故事 --- 蓝牙通信 --- 连接手机和嵌入式设备


    高飞狗:

    "常常的想,现在的你"

    布鲁托:

    "哈罗!高飞!心情不错嘛!"

    高飞狗:

    "嗨!又遇到难题了,百思不得其解,头昏眼花的,心情糟透了!"

    布鲁托:

    "又在研究什么高科技项目?"

    高飞狗:

    "根本算不上什么高科技,我有一个PM2.5监测装置,就是能够测量与记录环境温度、湿度和颗粒物浓度的东东,受应用条件的限制,没有配备显示屏,为了能够在现场对其进行配置、管理并获取测量数据,想在这个装置上连接一个蓝牙模块,然后借助手机通过蓝牙通信实现这些功能。"

    布鲁托:

    "蓝牙通信是很成熟的技术,应该不难解决。"

    高飞狗:

    "在手机上当然很容易就搜索到我的蓝牙模块并成功进行了配对,但是接下来如何开发一个AppPM2.5监测装置通信,我是一头雾水啊!"

    布鲁托:

    "开发手机App,用Android Studio就可以。"

    高飞狗:

    "Android Studio开发出来的App无法在iOS上运行。再说,我只会C++语言,而Android Studio要用java语言开发。"

    布鲁托:

    "我们不妨去找找黛丝博士,听听她有什么高见。"

    高飞狗:

    "又去找她? 挺不好意思的。"

    布鲁托:

    "黛丝博士是个热心人,乐于助人,上次咱俩去求助,她一点架子都没有,而且她对你的态度大为好转,难道你没瞧出来? 没准人家天天盼着你去问问题呢!"

    高飞狗:

    "真的吗?你看出来转机来了?我还有机会?"

    布鲁托:

    "咱们这就走吧!"

    高飞狗和布鲁托再次来到黛丝家并按下了门铃,"叮铃铃叮铃铃"。

    黛丝:

    "谁呀? 啊哦!是你们两位,快请进!"

    "快请坐,喝点咖啡还是绿茶?"

    高飞狗:

    "不用这么客气。黛丝,今天来又得麻烦你。"

    黛丝:

    "是什么事呀?"

    高飞狗:

    "我想用C++开发一个手机App,通过蓝牙通信管理我的PM2.5监测装置,而且这个App必须在AndroidiOS上都能运行。"

    黛丝:

    "这有什么难的呀。"

    高飞狗:

    "我就是不知该如何下手,一点思路都没有。"

    黛丝:

    "最近刚刚做了一个类似的项目,正好跟你们说说,对我来说也算温习所学知识吧。"

    布鲁托:

    "您太谦虚了!"

    黛丝:

    "咱们先说蓝牙通信的原理,然后再说具体实现吧。"

    "蓝牙通信和TCP/UDP的原理基本相同,几乎如出一辙。参见下表。"

    通信特征

    TCP/UDP通信

    蓝牙通信

    通信模式

    客户端-服务器模式

    客户端-服务器模式

    通信端点

    TCP端口

    服务

    通信端点标识方法

    TCP端口号,是16位二进制数

    服务UUID,是128位二进制数

    客户端通信过程

    创建客户端Socket

    连接服务器

    发送数据

    接收数据

    创建客户端Socket

    连接服务器

    发送数据

    接收数据

     

    黛丝:

    "看见了吧,与TCP/UDP相比,区别仅仅在于,蓝牙用服务代替端口,用服务UUID代替端口号,且服务UUID较长。"

    "用手机App管理嵌入式设备,手机就是客户端,嵌入式设备上的蓝牙模块就是服务器。"

    高飞狗:

    "真的是一目了然!"

    黛丝:

    "TCP/UDP标准定义了一组固定的端口对应一组标准化服务。例如,TCP端口80用于Web服务;TCP端口21用于FTP服务。"

    "类似地,蓝牙标准也定义了一组固定的服务UUID对应一组标准化服务。"参见下表:

     

    蓝牙服务名称

    服务UUID

    Serial Port

    00001101-0000-1000-8000-00805F9B34FB

    LAN Access Using PPP

    00001102-0000-1000-8000-00805F9B34FB

    DialupNetworking

    00001103-0000-1000-8000-00805F9B34FB

    OBEXObjectPush

    00001105-0000-1000-8000-00805F9B34FB

    OBEXFileTransfer

    00001106-0000-1000-8000-00805F9B34FB

    Cordless Telephony

    00001109-0000-1000-8000-00805F9B34FB

    Audio Source

    0000110A-0000-1000-8000-00805F9B34FB

     

    黛丝:

    "由于蓝牙服务UUID太长,就用16进制数表达,遵循8-4-4-4-12的方法表示。"

    "蓝牙通信与TCP/UDP通信的关键不同在于,蓝牙服务器都有一个SDP服务,也就是服务发现服务,供客户端查询蓝牙服务器能够提供哪些服务。"

    "通常,用于嵌入式设备的蓝牙模块都提供Serial Port服务,简称SPP,然后提供一个UART连接嵌入式设备",如下图所示。

     

    黛丝:

    "由此,手机App与嵌入式设备通信的基本流程如下(假设蓝牙模块已经与手机配对完毕)

    步骤1:选择要进行通信的蓝牙模块

    步骤2:查询蓝牙模块的服务。通常已配对的蓝牙设备的服务列表已缓存在手机里。

    步骤3:如果存在SPP服务,恭喜你!

    步骤4:用SPP服务UUID创建一个客户端Socket

    步骤5:用客户端Socket连接蓝牙模块。

    步骤6:调用客户端SocketSendData()发送数据给蓝牙模块,蓝牙模块会将收到的数据通过UART转发给嵌入式设备。

    步骤7:如果嵌入式设备发送数据给蓝牙模块,蓝牙模块会转发给手机,手机会缓存这些数据,App可调用客户端SocketReceiveData()接收数据。"

    黛丝:

    "蓝牙通信的原理就是这样的。"

    高飞狗:

    "黛丝,你讲得太明白了,今晚我一定要好好请请你、亲亲你!

    黛丝:

    "你就知道邪思歪想!"

    高飞狗:

    "那具体如何实现呢?"

    黛丝:

    "具体实现方法也很简单。我们只要选择Rad Studio作为开发工具,用C++编写一套源代码就可以生成适用于AndroidiOS上运行的App,是不是很酷?"

    "有关Rad Studio就不在此累述,GUI界面的设计也很简单,我们聚焦如何通过蓝牙进行数据收发。"

     

    借助蓝牙SPP服务,实现手机与嵌入式设备之间的通信

    1:本文旨在明晰蓝牙通信原理,仅列出扼要代码,如需完整代码,可联系本人。

    2:确保已开启手机蓝牙

    3:确保蓝牙模块已在手机的已配对设备列表中。

    // 取得并保存蓝牙管理器对象

    TBluetoothManager *BtManager = TBluetoothManager::Current;

     

    // 取得并保存蓝牙适配器对象

    BtAdapter = BtManager ->CurrentAdapter;

     

    // 取得已配对的蓝牙设备列表

    TBluetoothDeviceList *PairedDevices = BtManager ->GetPairedDevices();

     

    // 将蓝牙设备列表显示在组合框cbPairedDevices(代码略)

     

    // 获取组合框中被选中的蓝牙设备对象

    TBluetoothDevice * SelDevice = PairedDevices ->Items[cbPairedDevices->ItemIndex];

     

    // 获取该蓝牙设备的服务列表

    TBluetoothServiceList * ListServices = SelDevice->GetServices();

     

    // 在服务列表中查询是否支持SPP服务(代码略)

     

    // 若支持SPP服务

     

    // SPP服务UUID创建一个客户端Socket

    TBluetoothSocket *BtSocket = SelDevice ->CreateClientSocket(StringToGUID(SPP_GUI), false);

     

    // 用客户端Socket连接蓝牙模块。

    BtSocket ->Connect();

     

    // 调用客户端SocketSendData()发送数据给蓝牙模块,蓝牙模块会将收到的数据通过UART转发给嵌入式设备。

    BtSocket ->SendData(DataArray); // DataArray是一个数组

     

    // 如果嵌入式设备发送数据给蓝牙模块,蓝牙模块会转发给手机,手机会缓存这些数据,App可调用客户端SocketReceiveData()接收数据。"

    BtSocket->ReceiveData(50); // 接收数据,限时等待50ms

     

    黛丝:

    "以上就是手机App与蓝牙模块间收发数据的基本流程及其实现。"

    高飞狗:

    "黛丝,你讲得太深入浅出了!啊哦,快到饭点了,我请你吃个便饭,聊表谢意!"

    黛丝:

    "已经有人约我吃饭了,你们就赶紧回去试验,有什么问题随时Call我。"

  • 相关阅读:
    Vue 左右翻页,点赞动画
    gitbook 使用
    css3 序列帧动画抖动
    ios添加-webkit-overflow-scrolling依然卡顿
    css 多行省略号兼容移动端
    Vue粒子特效(vue-particles插件)
    css3 渐变色兼容移动端
    前端性能优化:客户端从输入到展示讲解
    前端通信:ajax设计方案(六)--- 全局配置、请求格式拓展和优化、请求二进制类型、浏览器错误搜集以及npm打包发布
    前端通信:ajax设计方案(五)--- 集成promise规范,更优雅的书写代码(改迭代已作废,移步迭代10)
  • 原文地址:https://www.cnblogs.com/micemik/p/7679916.html
Copyright © 2020-2023  润新知