1、搭建蓝牙开发环境
蓝牙开发可以使用C语言开发或python语言开发,使用的是蓝牙开发库为bluez库。
本文开发使用python语言开发,安装bluez库,可以使用pip install PyBluez来安装。
如果安装不上的话,可以使用sudo apt install python3-bluez来安装。
安装成功后可以通过pip list来查看一下是否安装成功。如下看到PyBluez 0.22表示安装成功了。
firefly@firefly:/usr/lib/bluetooth$ pip list
Package Version
---------------------- --------------------
attrs 23.1.0
blinker 1.4
certifi 2023.7.22
chardet 3.0.4
command-not-found 0.3
cryptography 2.8
dbus-python 1.2.16
distro 1.4.0
entrypoints 0.3
exceptiongroup 1.1.2
h11 0.14.0
httplib2 0.14.0
idna 2.8
keyring 18.0.1
launchpadlib 1.10.13
lazr.restfulclient 0.14.2
lazr.uri 1.0.3
netifaces 0.10.4
oauthlib 3.1.0
onboard 1.4.1
outcome 1.2.0
pip 20.0.2
PyBluez 0.22
pycairo 1.16.2
PyGObject 3.36.0
PyJWT 1.7.1
PyQt5 5.14.1
PySocks 1.7.1
python-apt 2.0.0+ubuntu0.20.4.8
PyYAML 5.3.1
requests 2.22.0
requests-unixsocket 0.2.0
SecretStorage 2.3.1
selenium 4.10.0
setuptools 45.2.0
simplejson 3.16.0
sip 4.19.21
six 1.14.0
sniffio 1.3.0
sortedcontainers 2.4.0
ssh-import-id 5.10
trio 0.22.2
trio-websocket 0.10.3
ubuntu-advantage-tools 27.10
urllib3 1.21.1
wadllib 1.3.3
wheel 0.34.2
wsproto 1.2.0
2、建立蓝牙服务端程序
蓝牙的程序编写与tcp/ip协议很像,基于socket进行编程的。所以有客户端与服务器的角色。服务器的程序代码如下,代码在服务器端建立一个zsm-server的服务器,对应的uuid为00001101-0000-1000-8000-00805F9B34FC。服务端程序运行在设备A上面。
#! /usr/bin/python3.8
import bluetoothserver_sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
server_sock.bind(("", bluetooth.PORT_ANY))
server_sock.listen(1)port = server_sock.getsockname()[1]uuid = "00001101-0000-1000-8000-00805F9B34FC"bluetooth.advertise_service(server_sock, "zsm-service", uuid)print("Waiting for connection on RFCOMM channel %d" % port)client_sock, client_info = server_sock.accept()
print("Accepted connection from ", client_info)while True:data = client_sock.recv(1024)print("Received ", data)client_sock.send(data)client_sock.close()
server_sock.close()
运行时发现程序报错,报错的函数为bluetooth.advertise_service(server_sock, "zsm-service", uuid), 报错的内容为(2, 'No such file or directory')。
经过分析与百度,查找到的解决办法为蓝牙服务启动时需要增加-E -C的选项。解决办法参考:树莓派-蓝牙
bluetoothd -E -C
是蓝牙守护进程(bluetoothd)运行时的命令行选项。下面是每个选项的功能:
-
-E
:此选项启用扩展模式。在扩展模式下,蓝牙守护进程将提供更多的功能和调试选项。这些功能包括支持调试输出、启用 experimental 模式、允许加载外部插件和驱动程序等。 -
-C
:此选项指定了蓝牙守护进程的配置文件路径。在默认情况下,配置文件是在/etc/bluetooth/main.conf
。使用-C
选项可以指定一个不同的配置文件路径,让蓝牙守护进程使用自定义的配置文件。
3、建立蓝牙客户端程序
客户端的程序相对简单一些,客户端程序如下所示,运行在设备B上面。
#! /usr/bin/python3.8
# -*- coding: utf-8 -*-
import bluetooth
from bluetooth import *
import timenearby_devices = bluetooth.discover_devices(duration=10, lookup_names=True)
print("Found %d devices" % len(nearby_devices), nearby_devices)con_addr = ""
con_name = "WL18xx Device"
for addr, name in nearby_devices:print("Find bluetooth device %s - %s" % (addr, name))if name == con_name:services = bluetooth.find_service(address=addr)for svc in services:print("Service Name: %s" % svc["name"])print(" Host: %s" % svc["host"])print(" Description: %s" % svc["description"])print(" Provided By: %s" % svc["provider"])print(" Protocol: %s" % svc["protocol"])print(" channel/PSM: %s" % svc["port"])print(" svc classes: %s "% svc["service-classes"])print(" profiles: %s "% svc["profiles"])print(" service id: %s "% svc["service-id"])print("\n")con_addr = addrif con_addr == "":print("not find!")
else: # Create the client socketclient_socket=BluetoothSocket( RFCOMM )client_socket.connect((con_addr, 3))print("connect the device:%s addr:%s"%(con_name, con_addr))client_socket.send("Hello World")print("Finished")while True:time.sleep(1)client_socket.close()
4、测试蓝牙通信
先启动设备A的服务器程序,再启动设备B的客户端程序,如果一切正常的话,设备B会收到发送出去的数据,再接收到服务器返回来的数据。