• 蓝牙 - BLE SPP实现举例 (Bluecode Protocol Stack)


    这里以一个无线扫描枪设备为例,这个设备会通过蓝牙通讯协议连接一个底座,使用的是BLE SPP进行通讯。

    扫描枪用来扫条码,解析出条码信息后,将数据通过无线传输给底座,底座再通过USB将数据传送给电脑。

    底座是Central device,扫描枪是peripheral device,因为底座需要连接多个扫描枪。通常是扫描枪提供数据给底座,没数据可能会进入休眠状态。底座有USB供电,处于一直等待接收数据的状态。

    也就是说扫描枪发布蓝牙广播信息,底座作为扫描方,接收蓝牙广播信息,发现扫描枪后,发起连接。

    当底座连接多个扫描枪时,对Service的Characteristic进行读写操作,来实现串口通讯功能。一个通讯链路,需要一套用于数据通讯的Service和Characteristic。扫描枪和底座连接,这个Service和Characteristic实例放在扫描枪上。如果放在底座上,则会存在多个Service和Characteristic实例,会出现冲突,难以管理。故应由扫描枪来作为GATT Server,底座作为GATT Client。这里的Service和Characteristic指的是用于BLE SPP的,使用的是指定UUID,不同厂商(协议栈不同)使用的UUID可能是不同的。

    本文使用的是Bluecode蓝牙协议栈,是和Telit公司提供的蓝牙模组一起使用的。参考的是此蓝牙扫描枪和蓝牙底座项目。

    扫描枪的蓝牙操作

    1,设置广播数据

    在想连接的Target Device的地址发生变化时,才需要更新广播数据。

    广播类型是非定向广播。

    数据构造是小端顺序。

    这里设置的数据分为广播数据及扫描响应数据,两个都是31字节。

    • 广播数据里是Flags,16bit Service UUID,Manufacturer Specific Data。在Manufacturer Specific Data的数据格式为:VendorID、TIO Data ID、Data Version、Bondable and functional mode、connection requested、Connect option、BT Address。默认情况下,Connect option值为0,表示连接的是Base,即底座。

    • 扫描响应数据里的数据是Complete local name。

    扫描枪发布广播数据,底座想连接的话,收到广播数据,使用里面的地址,就可以连接扫描枪设备了。

    Flags是0x06,16bit Service UUID是0xFEFB。Manufacturer Specific Data里,VendorID是0x008F。

    2,注册相关服务。

    在扫描枪这个产品中,注册了两个服务。一个DIS,Device Information service,160bit UUID是0x180A。

    另一个就是BLE SPP service,即TIO profile了。

    但具体的Service注册过程,在此项目中没有看到。需另外查询此协议栈的相关文档或SDK的demo。

    底座的蓝牙操作

    1,创建一个Periodic Scan Timer,作为GATT client设备,启动后就开始周期扫描,扫描方式是passive被动性扫描。

    • 参数设置:

    scanInterval,128 tick (0.625ms one tick),80ms。

    scanWindows,128 tick (0.625ms one tick),80ms。

    开启Duplicate Filter。

    • 时序:

    开始扫描,并启动一个300ms Timer;300ms Timer到了,停止扫描;Delay 300ms,等待协议栈线程的扫描结果处理;300ms时间到了,查询是否发现新设备;再等300ms;一个周期结束,重复上个周期操作,开始扫描。

    大概就是900ms一个周期,有300ms的扫描时间。

    2,收到并处理广播数据

    进入被动扫描模式后,当接收到广播数据包,协议栈会发送事件,调用事件处理函数。

    此处理函数是HandleBlueAPIMessage,处理的消息事件是blueAPI_EventLEScanInfo。

    接受的数据就是31个字节,

    要判断的条件有三个:

    a, TIO Service UUID的值是否是0xFEFB,Telit Wireless Solutions (Formerly Stollmann E+V GmbH),在Assigned Numbers里能查到。

    b, Vendor ID是否是0x008F(Telit Wireless Solutions GmbH),在Assigned Numbers里能查到。

    c,Data ID是否是TIO ID,0xB009。

    d,Connect option字节是否为0,表示请求连接。

    然后将地址后面地址信息存储下来。

    3,广播数据处理成功

    在广播数据处理成功后,即得到了一个请求连接的蓝牙地址。在上面的Period Scan处理过程中,在查询是否发现新设备的处理中,使用得到的蓝牙设备地址请求一个GATT链接。

    等待GATT链接请求的反馈结果,结果正确后,针对此蓝牙地址发送Discover Request,并等待反馈结果。

    结果正确后,调用BLE SPP的请求连接的函数,反馈结果成功,则连接过程结束。

    4,Discover过程

    上面发送了Discover请求后,会收到协议栈反馈的Endpoint Indicate事件,里面包含了SPP的port信息。在BLE SPP请求连接时要使用这个信息,确定想连接的SPP port端口。

  • 相关阅读:
    【psychopy】【脑与认知科学】认知过程中的面孔识别加工
    阿里二面:如何定位&避免死锁?连着两个面试问到了!
    [附源码]JAVA毕业设计仟侬堂茶具网站(系统+LW)
    首个中文Stable Diffusion模型开源,玩转中文-图片”的跨模态生成任务
    C# Socket通信从入门到精通(10)——如何检测两台电脑之间的网络是否通畅
    戴尔PowerEdge服务器R450装centos7步骤
    蓝桥杯练习题——多路并归
    python绘制混淆矩阵
    Nougat:一种用于科学文档OCR的Transformer 模型
    从0开始写一个简单的vite hmr 插件
  • 原文地址:https://blog.csdn.net/guoqx/article/details/134123610