注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
icefire2012的个人空间 https://home.eeworld.com.cn/space-uid-404205.html [收藏] [复制] [分享] [RSS]
日志

【树莓派3B+测评】与CC2640R2F通信的简单示例

已有 1516 次阅读2018-9-29 23:49 |个人分类:树莓派

上一篇,树莓派和手机通过蓝牙通信,用的是经典蓝牙。这一篇中将尝试用蓝牙的另外一种模式,低功耗蓝牙BLE。主角当然是树莓派3B+,与之搭配做通信测试的,是当前一款比较流行的BLE SoC,TI的CC2640R2F(以下简称R2F)。

一、R2F上程序的简单介绍
        R2F是CC2640的升级版, 增加了FLASH空间,支持蓝牙5并向下兼容蓝牙4.x。测试时,R2F上跑的是官方提供的SDK中的simple_peripheral demo程序。在SDK中的路径为:
        simple_peripheral文件夹下的README.html是这个demo程序的介绍及演示过程。简单来讲,simple_peripheral例程提供了一个服务custom service,custom service下有五个characteristics,每个characteristics或者可读,或者可写,或者可通知,或者需要先authentication才能读取。README文档展示了手机上的BLE scanner App访问这五个characteristics的过程。这个演示基本涵盖了BLE通信中的常见操作。
        那接下来的操作,将是在树莓派上通过python编程,与R2F通信,逐一访问这五个characteristics,重复一遍README文档中的演示操作。下面是具体的介绍。

二、PYGATT
        上一篇测评中,树莓派和手机之间的经典蓝牙通信,用的是蓝牙中的RFCOMM协议。现在树莓派与R2F之间的通信,用到的是BLE中的GATT协议。Python有一个名为pygatt的模块,提供了python编程时访问GATT descriptors的API接口。
        下面是pygatt的安装方法:
  1. sudo pip install pygatt
复制代码
  1. sudo pip install "pygatt[GATTTOOL]"
复制代码
  1. sudo pip install pexpect
复制代码


        注意:pexpect也是需要手动安装的。否则下面运行代码时会报与pexpect有关的错误。

三、python编程访问R2F的代码
        先将通信代码贴在这里。
  1. import pygatt

  2. import sys

  3. from time import sleep



  4. def notify_callback(handle,value):

  5.     print("notify:handle=%d,value=%d" %(handle,ord(value)))



  6. adapter = pygatt.GATTToolBackend()



  7. try:

  8.     adapter.start()

  9.     device = adapter.connect('54:6C:0E:6D:D7:96')

  10.     dev_name = device.char_read("00002a00-0000-1000-8000-00805f9b34fb")

  11.     print("DevName:%s" %dev_name)



  12.     print("Char 1 wr=66")

  13.     device.char_write_handle(30,bytearray([66]))

  14.     #char1=device.char_read_handle(30)

  15.     char1=device.char_read('0000fff1-0000-1000-8000-00805f9b34fb')

  16.     print("Char 1 rd=%x" %ord(char1))



  17.     #char2=device.char_read_handle(33)

  18.     char2=device.char_read('0000fff2-0000-1000-8000-00805f9b34fb')

  19.     print("Char 2 rd=%x" %ord(char2))



  20.     print("Char 3 wr=88")

  21.     device.char_write_handle(36,bytearray([88]))



  22.     device.subscribe('0000fff4-0000-1000-8000-00805f9b34fb',notify_callback,False)

  23.     sleep(10)



  24.     print("Char 5 rd=")

  25.     char5=device.char_read('0000fff5-0000-1000-8000-00805f9b34fb')

  26.     for i in char5:

  27.         print(i)

  28. finally:

  29.     adapter.stop()
复制代码


四、代码说明
        在与R2F通信之前,我们需要先获取一些通信对象R2F的参数,这些可以通过python调用pygatt的API获得。这里是在终端里输入几个指令来获取。
        首先是获取R2F的地址,需要先扫描一下:
        sudo hcitool lescan
        
        第五行的SimpleBLEPeripheral便是R2F了,它的地址是54:6C:0E:6D:D7:96
        接下来是获取R2F的service和characteristics信息。
        

        这里需要关注的是蓝框中的handle值和绿框中的uuid。最上面框住的一行,是用来获取设备名称的,最下面框住的五行,就是第一部分中提到的5个characteristics。下面编程访问,都需要对应的char value handle或者uuid(第一部分截图中的uuid是16位的,这里应该是补全成标准格式的uuid了,fff1-fff5还是很好识别的)。
        除了char value handle和uuid,前面的handle似乎就是个顺序标号,在下面的编程中没有用到这个。char properties是指明读写和通知属性的。读=0x02  写=0x08  通知=0x10。 characteristics1(uuid=0xfff1)是可读可写的,那么它的char properties=0x02|0x08=0x0a

        下面简单介绍一下程序内容。
        第12行是通过指定地址,建立与R2F的连接
        第13行是获取R2F的设备名称,char_read的参数是uuid,返回值是characteristics对应的值。
        第17行是通过handle写characteristics1,char_write_handle的第一个参数是上面图片中的char value handle,十六进制的0x1e是十进制的30,第二个参数是要写入的值。
        第19行是通过uuid读characteristics1,我尝试用char_read_handle通过char value handle去读,但总是报错,这个目前还没弄明白是怎么回事。
        第29行是使能characteristics的notification并注册回调函数,subscribe函数的第一个参数是characteristics的uuid,第二个参数是通知的回调函数句柄,第三个参数为True时为indicate,为False时为notification。回调函数的两个参数是系统收到notification传回来的,分别是对应的char value handle以及返回的数值。
        第33行是也是一个读操作,如simple_peripheral例程的介绍文档README中所描述的,要读取characteristics5 先要有认证过程。用BLE scanner读取时,会弹出配对的对话框,并提示输入配对密码(这个密码是R2F那端给出的,会实时通过串口把密码打印出来)。这里python编程读取时,也会尝试与R2F配对,但一般都是失败,这个我猜测可能是没有输入配对密码的缘故(也不会有任何提示要输入配对密码的)。
        为了绕过这个过程,我尝试先让树莓派和R2F配对上,我在图形界面里点击最上方的蓝牙图标,搜索到SimpleBLEPeripheral,点击pair,提示输入配对密码,然后正确配对上了。但是运行程序到读取characteristics5时,依然会提示配对失败。后来我尝试通过在终端中调用bluetoothctl相关的指令建立配对,中间也有曲折,但是按如下操作,也是可以实现配对的,并且此后再一次运行程序读取characteristics5时,是可以成功读取的。
        终端中运行bluetoothctl建立配对的截图如下(左侧是R2F的打印信息,右侧是树莓派终端中的操作,红框是需要输入的指令)。如果上来直接pair device,则会报错。需要先remove device,再trust device,最后pair,这样成功率较高。pair成功后会打印出R2F上的service等信息,因内容较多,这里只截了两行(图片中的最后两行)。

        最后附上python程序运行时,R2F以及python程序的打印信息截图。那两行notify,是在sleep(10)的十秒钟时间内收到的两个通知信息。其余的,与第一部分中介绍的例程中的操作基本一致。

五、总结
        这一篇里,主要是通过python的pygatt模块编程完成了与CC2640R2F的一些通信操作。另外中途还用到了gatttool和bluetoothctl这两个工具。整个流程走下来,还是学到了很多linux上与BLE相关的东西,对BLE的通信过程,以及service,characteristics,notification等概念有了初步的了解。当然对gatt的内容还只是略知皮毛。
        就python下的ble相关的模块而言,我找到的,除了pygatt,还有pygattlib和bluepy。运用另外两个模块我也实现了与R2F的读写操作,但是在处理notification遇到了问题,首先就是不知道如何使能notification,R2F的程序上默认characteristics4 的notification是关闭的,但我在这两个模块上都没有找到打开操作的API,另外回调函数的实现形式上也没有pygatt的API这么容易理解。如果大家谁在这方面有心得,也可以交流一下。
        受时间限制,蓝牙这一块就告一段落了,后续开始实现8266与树莓派的通信。

本文来自论坛,点击查看完整帖子内容。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章