树莓派蓝牙调试过程

调试硬件NRF51822 树莓派3

软件pyblueZ或者bluepy

 

蓝牙地址或设备地址是蓝牙芯片制造的全球唯一的48位地址。

传输协议:

RFCOM+TCP

RFCOMTCP一样,提供大致相同的服务和可靠性保证。它是模仿RS-232设计的,方便制造商将蓝牙功能添加到下游的串口设备中。RFCOMM是射频通信协议,它可以仿真串行电缆接口协议,符合ETSI0710串口仿真协议。通过RFCOMM,蓝牙可以在无线环境下实现对高层协议,如PPPTCP/IPWAP等的支持。另外,RFCOMM可以支持AT命令集,从而可以实现移动电话机和传真机及调制解调器之间的无线连接。

RFCOMTCP的不同支出在于TCP在机器上支持65535个开放端口,而RFCOM只允许30个   (最可靠的协议)

L2CAP+UDP  (最优的协议)

L2CAP提供了一个面向连接的协议

L2CAP信道有三种类型:

A、面向连接信道:Connection-OrientedCO,用于两个设备之间的数据通信。

B、无连接信道:Connection-LessCL,用来向一组设备广播方式传输数据。CID为固定值:0x0002

C、信令信道:Signaling,用于创建CO通道,可以通过协商改变CO信道的特性。

 

 

当设备地址和传输协议确定后,就该确定端口了。

L2CAP 的端口称为PSM  RFCOM的端口称为通道。

protocol

terminology

reserved/well-known ports

dynamically assigned ports

TCP

port

1-1024

1025-65535

UDP

port

1-1024

1025-65535

RFCOMM

channel

none

1-30

L2CAP

PSM

odd numbered 1-4095

odd numbered 4097 - 32765

 

建立连接,传输数据

 

 

blueZ进行升级

通过命令bluetoothctl -v查看可知,树莓派3上的blueZ5.23的版本,有点老,后面的bluetoothctl命令很多都没有,所以我进行重新安装,将它升级成了5.43的版本。

 

sudo apt-get update

sudo apt-get upgrade

sudo apt-get dist-upgrade

sudo apt-get install -y libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev

 

sudo wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.43.tar.xz

sudo tar xf bluez-5.43.tar.xz

cd bluez-5.43/

 

sudo ./configure

sudo make

sudo make install

sudo reboot

 

# check version

bluetoothctl -v

 

sudo vim /lib/systemd/system/bluetooth.service

        # Add --experimental to this lane

        ExecStart=/usr/local/libexec/bluetooth/bluetoothd --experimental

 

sudo systemctl daemon-reload

sudo systemctl restart bluetooth

sudo hciconfig hci0 up

sudo reboot

 

sudo usermod -G bluetooth -a pi

sudo reboot

 

安装pyblueZ

sudo apt-get install python-dev

sudo apt-get install libbluetooth-dev

sudo pip install pybluez (如果是python3的话执行sudo pip3 install pybluez)

 

与经典蓝牙透传模块连接

关于通过树莓派3和经典蓝牙的连接,这里是用HC-05ET10 (双模)来测试的,他们都是是支持经典模式协议SPP协议的

在通过bluetoothctl工具进行连接的时候出现错误  

Failed to connect: org.bluez.Error.NotAvailable

经过pair后,可以连接,但是瞬间就断开,还是相同的错误,经过查找,找到以下解决方法:

连接命令:sudo rfcomm connect hci0 00:1B:10:F1:FB:D4

http://blog.csdn.net/qq_33518042/article/details/53503492

 

例程(这里例程好似客服端的,将透传模块看做是服务器端):

#!/usr/bin/env python

import bluetooth

import subprocess

 

service_matches = bluetooth.find_service( address = "00:1B:10:F1:FB:D4" )

 

if len(service_matches) == 0:

    print "couldn't find the FooBar service"

    sys.exit(0)

 

first_match = service_matches[0]

port = first_match["port"]

name = first_match["name"]

host = first_match["host"]

 

print "connecting to \"%s\" on %s port:%s" % (name, host, port)

 

sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )

sock.connect((host, port))

while True:

sock.send("012345678901234567890123456789!!\r\n")

sock.close()

 

参考:http://people.csail.mit.edu/albert/bluez-intro/x290.html

http://htmlpreview.github.io/?https://github.com/karulis/pybluez/blob/master/docs/index.html

 

与手机连接蓝牙的调试

开始调试蓝牙。首先简单的例程:

#!/usr/bin/env python

import bluetooth

 

print("performing inquiry...")

nearby_devices = bluetooth.discover_devices(

        duration=8, lookup_names=True, flush_cache=True, lookup_class=False)

print("found %d devices" % len(nearby_devices))

for addr, name in nearby_devices:

    try:

        print("  %s - %s" % (addr, name))

    except UnicodeEncodeError:

        print("  %s - %s" % (addr, name.encode('utf-8', 'replace')))

 

出现了错误:

  File "/usr/local/lib/python2.7/dist-packages/bluetooth/bluez.py", line 26, in discover_devices

    device_id = _bt.hci_get_route()

OSError: [Errno 19] No such device

可能是因为我蓝牙没有打开吧,我把蓝牙打开后程序正常运行

注意:本例程不能发现ble(低功耗蓝牙4.0)设备

结果:

performing inquiry...

found 2 devices

  A4:44:D1:AA:9B:6A - note 3

  AC:CF:85:B0:AE:A4 - huawei

现在蓝牙开发的整体思路是通过脚本来运行蓝牙,然后通过pybulez来控制数据传输

blueZ开发参考:

http://htmlpreview.github.io/?https://github.com/karulis/pybluez/blob/master/docs/index.html

http://people.csail.mit.edu/albert/bluez-intro/index.html

 

通过RFCOM进行数据传输(服务器端):

例程:

#!/usr/bin/env python

import bluetooth

import subprocess

 

sub=subprocess.Popen("sudo hciconfig hci0 up",shell=True) //开启设备

sub=subprocess.Popen("sudo hciconfig hci0 piscan",shell=True) //使设备能够被扫描到

 

server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )

 

port = 1

server_sock.bind(("",port))

server_sock.listen(1)

 

client_sock,address = server_sock.accept()

print "Accepted connection from ",address

 

data = client_sock.recv(1024)

print "received [%s]" % data

注意:本例程不适用ble(低功耗蓝牙4.0)设备

蓝牙调试工具

Hciconfig 命令:http://xu1347.blog.163.com/blog/static/1613788612011624023429/

Hcitool 工具:http://blog.chinaunix.net/uid-27875-id-5187357.html

现在先介绍一下命令连接。命令连接有三种,bluetoothctlgatttoolhcitool我测试通过的是两种bluetoothctl。不过可能是因为版本的问题,我的bluetoothctl的命令少了一些,智能进行简单的连接操作

pi@scream:~$ sudo bluetoothctl

[NEW] Controller B8:27:EB:35:34:90 scream [default]

[NEW] Device C4:62:EA:DB:72:F3 Galaxy Note3

[bluetooth]# power on

Changing power on succeeded

[bluetooth]# scan on

Discovery started

[CHG] Controller B8:27:EB:35:34:90 Discovering: yes

[NEW] Device 55:7E:64:96:79:F5 55-7E-64-96-79-F5

[NEW] Device E3:47:55:D3:22:77 SCREAM

[NEW] Device 56:11:F4:A1:AA:0F 56-11-F4-A1-AA-0F

[bluetooth]# agent on

Agent registered

[bluetooth]# connect E3:47:55:D3:22:77

Attempting to connect to E3:47:55:D3:22:77

[CHG] Device E3:47:55:D3:22:77 Connected: yes

Connection successful

[CHG] Device E3:47:55:D3:22:77 UUIDs:

        00001800-0000-1000-8000-00805f9b34fb

        00001801-0000-1000-8000-00805f9b34fb

        6e400001-b5a3-f393-e0a9-e50e24dcca9e

[CHG] Device E3:47:55:D3:22:77 Appearance: 0x1234

[NEW] Device F8:DF:A8:1D:C8:02 F8-DF-A8-1D-C8-02

[bluetooth]# disconnect E3:47:55:D3:22:77

Attempting to disconnect from E3:47:55:D3:22:77

Successful disconnected

[CHG] Device E3:47:55:D3:22:77 Connected: no

中间少了个pair命令,不过我之前pair过所以没问题。

参考:http://blog.csdn.net/bona020/article/details/52141363

参考:https://www.jerryzone.cn/raspi-bluetooth-socket/

在开启的过程中可能会出现错误:Failed to connect: org.bluez.Error.Failed 

这是由于蓝牙设备没有上电造成的,可通过如下命令解决此问题: 
rfkill unblock bluetooth 
hciconfig hci0 up

gatttool

然后就是gatttool,之前这个命令来连接一直实现不了总是提示:

Error connect: Connection refused (111)

后来在网上找了解决的方法

首先:vim /etc/bluetooth/main.conf

在最下面添加

EnableLE = true       

AttributeServer = true    

DisablePlugins=pnat

使用的时候通过sudo gatttool -t random -b E3:47:55:D3:22:77 -I来打开

感觉主要应该是因为命令中加入了random所以才能连上的

如下

pi@scream:~$ sudo gatttool -t random -b E3:47:55:D3:22:77 -I

[E3:47:55:D3:22:77][LE]> connect

Attempting to connect to E3:47:55:D3:22:77a

Connection successful

[E3:47:55:D3:22:77][LE]> primary

attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb

attr handle: 0x0008, end grp handle: 0x000b uuid: 00001801-0000-1000-8000-00805f9b34fb

attr handle: 0x000c, end grp handle: 0xffff uuid: 6e400001-b5a3-f393-e0a9-e50e24dcca9e

[E3:47:55:D3:22:77][LE]> characteristics

handle: 0x0002, char properties: 0x0a, char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb

handle: 0x0004, char properties: 0x02, char value handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb

handle: 0x0006, char properties: 0x02, char value handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb

handle: 0x0009, char properties: 0x20, char value handle: 0x000a, uuid: 00002a05-0000-1000-8000-00805f9b34fb

handle: 0x000d, char properties: 0x10, char value handle: 0x000e, uuid: 6e400003-b5a3-f393-e0a9-e50e24dcca9e

handle: 0x0010, char properties: 0x0c, char value handle: 0x0011, uuid: 6e400002-b5a3-f393-e0a9-e50e24dcca9e

[E3:47:55:D3:22:77][LE]> char-write-req 0x0011 24

Characteristic value was written successfully

 

但是第三种方法没有实现,在用hcitool进行连接的时候,总是出现错误

Could not create connection: Connection timed out

没有找到解决的办法。

pyblueZ 在树莓派上安装使支持ble

方法1pyblueZ

源码下载地址:https://github.com/karulis/pybluez 0.22版本的)

可以通过 sudo git clone https://github.com/karulis/pybluez.git 来下载。

完成后来进行安装

sudo apt-get install python-dev

sudo apt-get install libbluetooth-dev

sudo pip install pybluez (如果是python3的话执行sudo pip3 install pybluez)

然后需要安装依赖:

pkg-config

libboost-python-dev

libboost-thread-dev

libbluetooth-dev >= 4.101 (前面已安装)

libglib2.0-dev  (前面在安装blueZ5.43的时候应该也已安装)

python-dev(前面已安装)

分别运行命令:sudo apt-get install pkg-config

sudo apt-get install libboost-python-dev

sudo apt-get install libboost-thread-dev

sudo apt-get install libglib2.0-dev

然后进行下面的安装

sudo pip install pybluez[ble]  (包含了gattlib

sudo python setup.py install  (在下载下来的pyblueZ的文件夹下运行)

sudo pip install -e .[ble]

 

通过对pyblue源码的查看,其ble功能用到的一些接口函数都是从gattlib模块中导入的。

关于gattlib模块可以参考pygattlib https://bitbucket.org/OscarAcena/pygattlib

 

例程:

#!/usr/bin/env python

from bluetooth.ble import GATTRequester

address="E3:47:55:D3:22:77"

nrf=GATTRequester(address, False)

nrf.connect( wait=True, channel_type="random")

nrf.write_by_handle(0x0011, "123456")

1、其中connect中的参数random很重要,之前一直没有添加这个参数,默认的是public,一直连接不上,后来添加了random,蓝牙可以和nrf51822连接了,是否需要加random需要看设备的地址类型, nRF51822采用的是Random Static address,在启动的时候协议栈从FICR里面读取作为设备的蓝牙地址.如果用户需要使用Public address,则需要使用sd_ble_gap_address_set()这个函数重新设定蓝牙地址。

2、write_by_handle()中的参数0x0011charhandle。之前在用gatttool调试的时候出现过,就是那个值。第二个参数是要发送的数据。

方法2bluepy

关于介绍和安装方法 http://www.elinux.org/RPi_Bluetooth_LE

API文档:http://ianharvey.github.io/bluepy-doc/index.html

源码:https://github.com/IanHarvey/bluepy

安装过程:

sudo apt-get install python-pip

sudo apt-get install libglib2.0-dev

sudo pip install bluepy

 

简单例程:

#!/usr/bin/env python

from bluepy import btle

conn = btle.Peripheral("E3:47:55:D3:22:77", "random")

conn.writeCharacteristic(0x0011,"12345",withResponse=True)

1、其中Peripheral中的参数random很重要,之前一直没有添加这个参数,默认的是public,一直连接不上,后来添加了random,蓝牙可以和nrf51822连接了。是否需要加random需要看设备的地址类型, nRF51822采用的是Random Static address,在启动的时候协议栈从FICR里面读取作为设备的蓝牙地址.如果用户需要使用Public address,则需要使用sd_ble_gap_address_set()这个函数重新设定蓝牙地址。

2、参数0x0011charhandle。之前在用gatttool调试的时候出现过,就是那个值。第二个参数是要发送的数据

关于publicrandom 的描述:

http://blog.csdn.net/sinat_23338865/article/details/52189538

http://blog.csdn.net/suxiang198/article/details/47730649

异常:bluepy.btle.BTLEException: Device disconnected

BluetoothError


测试代码: https://github.com/IJustLoveMyself/Raspberry-Pi/blob/master/test2/BLE-connect.py

https://github.com/IJustLoveMyself/Raspberry-Pi/blob/master/test2/BLE-trans.py (低功耗)

https://github.com/IJustLoveMyself/Raspberry-Pi/blob/master/test2/EDR-trans.py (普通蓝牙)

你可能感兴趣的:(蓝牙学习,python-树莓)