美文网首页Android
android与蓝牙通讯记录

android与蓝牙通讯记录

作者: 梧叶已秋声 | 来源:发表于2017-12-28 13:53 被阅读66次

    首先,android设备与蓝牙连接有两种方式。不同的连接,代码是不一样的,应该是uuid不一样。

    1. android设备 与android设备连接。

    2. android设备 与非android设备连接。

    如下图

    我做的是与非android蓝牙设备相关的通讯,以下全为非android蓝牙设备的相关内容。

    蓝牙目前可以分为2种。

    经典蓝牙(Classic)

    低功耗蓝牙(BLE   android4.3以上支持ble)

    这两种蓝牙从扫描到连接到数据的传输api完全不一样,因此拿到蓝牙设备之后,要确认好蓝牙种类。

    关于BLE蓝牙,可参考谷歌官方demo

    https://github.com/googlesamples/android-BluetoothLeGatt

    由于这个官方代码是很久之前的,因此,在android6.0以及以上的系统需要加上权限的相关设置。

    并且这里只有读,没有写入数据的操作。

    写入的操作,我是参考的这个。

    https://github.com/Jasonchenlijian/FastBle

    经典蓝牙,参考了这个demo,连接的时候有一个选项,不要选与android设备相连,选另一个。

    https://github.com/akexorcist/Android-BluetoothSPPLibrary

    我是在这个demo的基础上进行修改。

    Android-BluetoothSPPLibrary应该是在官方demo的基础上修改的。

    https://github.com/googlesamples/android-BluetoothChat

    目前是使用经典蓝牙串口调试通讯(ble蓝牙只做了扫描、连接到读写数据等)。

    使用SSCOM5.12(pc端软件)这个串口调试工具。当android设备与蓝牙连接之后,通过app发送命令,电脑上就可以收到数据(蓝牙要通过线连接到电脑)。

    期间遇到的问题:

    未断开的情况下重连,要先做断开操作,然后在断开后要加一定的延时再进行重新连接,否则容易报错。

    Android-BluetoothSPPLibrary 的代码中数据的发送与接收那里在断开与重连的过程中容易报错,改成跟 android-BluetoothChat一样就不会报错了。

    根据Android-BluetoothSPPLibrary 修改的代码,蓝牙断开后4.4直接崩溃。未断开的情况下重连 7.0不会报错,5.0以及6.0会无法连接,要断开后再连接才可以连接上。

    解决完蓝牙的连接问题之后,下面来看看通讯问题。

    蓝牙串口是什么。

    首先看串口的解释:

    https://zh.wikipedia.org/wiki/%E4%B8%B2%E8%A1%8C%E7%AB%AF%E5%8F%A3

    串口包括RS-232-C、RS-422、RS485、USB等。

    这里串口指的是usb接口。

    蓝牙开发板上的usb接口通过线接到pc的usb接口。

    串口是指利用串行方式传输数据的接口,它是一大类接口,USB接口RS232接口、网线RJ45接口RS485接口SATA接口等等都属于串口。各种串口之间的通讯协议、接口电平等并不完全相同,因此有一种串口得到另一种串口时需要转换。

    一般来说,串口默认是指RS232接口,所谓的USB转串口实际上就是USB转RS232装置。

    https://zhidao.baidu.com/question/340354937.html

    蓝牙模块也称蓝牙串口通讯模块

    http://www.shaoguoji.cn/2016/04/16/usage-of-bluetooth-model/

    蓝牙的真正作用就是代替了那根tx ,rx的数据线。

    蓝牙通讯也有相关协议。

    蓝牙协议相关:

    https://langw.gitbooks.io/blesummary-/content/lan_ya_xie_yi_zhan_fen_xi.html

    http://www.cnblogs.com/zjutlitao/p/4742428.html

    可以粗略的看下,不必深入。

    因此,蓝牙串口就是蓝牙开发板通过串口连接(这里是usb接口连接,实际应用中是可以自行封装串口通讯协议?通讯的本质是?协议?),进行通讯。

    那么这里是怎么进行通讯的?

    1.当android设备与蓝牙连接之后,app就可以发生数据到蓝牙模块。

    2.蓝牙模块接收到命令之后,通过串口(这里是usb接口)传输给电脑,使用 SSCOM5.12软件读出数据。这里主要就是 SSCOM5.12这个软件的作用了。 使用SSCOM5.12串口调试助手的时候,注意设置波特率。

    使用SSCOM5.12注意以下几处。

    整个发送数据的流向是:

    app--->android 设备蓝牙 -->非android设备蓝牙模块-->pc端--> 使用SSCOM5.12解析数据。

    实际使用中非android设备蓝牙模块后面不会接到pc端,而是别的串口,这里只是前期调试。

    实际使用如下

    当app的蓝牙连接到非android设备的蓝牙模块时,会收到一条指令。

    IM_CONN:0,683E344FA855,0100,0,490

    01 00这个数据是发送数据时需要用到的。0100要反过来。00 01  。注意句柄(handle

    https://www.zhihu.com/question/22950899)。

    发送数据:

    41 54 3E 01 01 08 00 00 01 31 32 33 34 35 36 0d

    成功发送数据会返回ok,否则是error。

    [15:24:22.762]发→◇AT>���\0\0�123456□

    [15:24:22.767]收←◆

    OK

    蓝牙断开显示

    [15:24:50.336]收←◆

    IM_DISC:0100,0

    以上就是经典蓝牙相关的。

    ------------------------------BLE----------------

    下面来看看ble的。

    ble相关概念看这篇,很详细。

    Android 上的低功耗蓝牙实践

    https://www.race604.com/android-ble-in-action/

    BLE 的协议栈

    作为 Android 开发者,我们不必理解 BLE 的协议栈每个细节,这里大概介绍一下协议架构。我们都知道,协议一般都是分层设计的。BLE 协议栈也不例外。我们来看一下这个图。整个协议栈大致分为三部分,从下到上分别为,控制器(Controller)→主机(Host)→应用(Applications)。

    控制器:它是协议栈的底层的实现,直接与硬件相关,一般直接集成在 SoC 中,由芯片厂商实现,包括物理层和链路层。 主机:这是协议栈的上层实现,是硬件的抽象,与具体的硬件和厂家无关。 应用层:就是使用 Host 层提供的 API,开发的应用。

    下面具体围绕这张图进行分析。

    ATT与GATT

    [翻译]ATT和GATT概述

    http://legendmohe.net/2015/01/16/%E7%BF%BB%E8%AF%91att%E5%92%8Cgatt%E6%A6%82%E8%BF%B0/

    ATT,即属性协议

    GATT,全称叫做通用属性配置文件

    上图 中的Host 部分,属性协议,即 ATT,它是 BLE 通信的基础。ATT 把数据封装,向外暴露为“属性”,提供“属性”的为服务端,获取“属性”的为客户端。ATT 是专门为低功耗蓝牙设计的,结构非常简单,数据长度很短。

    接下来我们看一下 GATT,全称叫做通用属性配置文件,它是建立在前面说的 ATT 的基础上,对 ATT 进行进一步的逻辑封装,定义数据的交互方式和含义。

    这是我们做 BLE 开发的时候直接接触的概念。

    GATT 按照层级定义了三个概念:服务(Service)、特征(Characteristic)和描述(Descriptor)。他们的包含关系如右边这个图所表示的:一个 Service 包含若干个 Characteristic,一个 Characteristic 可以包含若干 Descriptor。而 Characteristic 定义了数值和操作。

    Characteristic 的操作这几种权限:读、写、通知等权限。我们说的 BLE 通信,其实就是对 Characteristic 的读写或者订阅通知。

    还有最外面一层,Profile配置文件,把若干个相关的 Service 组合在一起,就成为了一个 Profile,Profile 就是定义了一个实际的应用场景。

    详细的图:

    那么如何操作Characteristic ,关键在于UUID。

    Service、Characteristic 还有 Descriptor 都是使用 UUID 唯一标示的。

    下面来看看什么是uuid。

    关于 UUID 有一些规范,为了避免冲突,一般都不会自己手动去定义。例如 Android 中提供了 UUID.randomUUID() 来生成一个随机的 UUID。我们也看到,UUID 有点太长了,在低功耗蓝牙中这种数据长度非常受限的情况下,使用起来肯定不方便,所以蓝牙又使用了所谓的 16 bit 或者 32 bit 的 UUID。其实本质上并没有什么 16bit 或者 32 bit UUID,蓝牙 SIG 定义了一个基础的UUID(Bluetooth Base UUID),形式如下。除了 XXXX 那几位意外,其他都是固定,所以说,其实 16 bit UUID 是对应了一个 128 bit 的 UUID。这样一来,UUID 就大幅减少了,例如 16 bit uuid 只有有限的 65536 个,所以 16 bit UUID 并不能随便使用。SIG 已经预先定义了一些 UUID,如果你想添加一些自己的 16 bit 的 UUID,可以花钱买。

    16*16*16*16 = 65536 

    BLE 应用可以分为两大类:基于非连接的和连接的。


    基于非连接的,这种应用就是依赖 BLE 的广播,也叫作 Beacon。这里有两个角色,发送广播的一方叫做 Broadcaster,监听广播的一方叫 Observer。

    基于连接的,就是通过建立 GATT 连接,收发数据。这里也有两个角色,发起连接的一方,叫做中心设备—Central,被连接的设备,叫做外设—Peripheral。

    我这里做的是连接式的应用。

    这里总结一下扫描中一些建议。

    1、首先,尽可能使用新的 API,功能更强大;

    2、尽可能少地扫描,因为毕竟扫描是一个比较重的操作,耗电,也会减慢 BLE 连接速度;

    3、扫描的时候,尽量设置 ScanFilter,只扫描那些你感兴趣的设备,而不是全盘扫描;

    4、正确使用 API,特别是合理停止扫描,防止资源泄漏。

    这里有一个中心设备和外设的概念。

    可以尽量遵循如下一些原则:尽量少的连接数量,尽量短的连接时间,尽量少的扫描,至于尽量少的 ClientIf,如果在 APP 中多个模块中都要扫描或者连接,应该做尽可能的合并。尽量少的广播数据,尽量少的并行请求,在回调中要做尽量少的工作。

    以上大部分文字都是抄的,这里只是做个记录。

    具体代码分析可以看这里,可对照谷歌官方源码去参照。

    Android BLE 蓝牙开发入门

    https://www.jianshu.com/p/3a372af38103

    BLE的坑:Android蓝牙4.0 BLE开发坑总结

    参考连接:

    https://www.mianbaoban.cn/blog/post/133095

    相关文章

      网友评论

        本文标题:android与蓝牙通讯记录

        本文链接:https://www.haomeiwen.com/subject/vikdgxtx.html