Python学习笔记之蓝牙模块通讯-Pybluez

Python学习笔记之蓝牙模块通讯-Pybluez

最近要写一款蓝牙耳机PC端的调试工具,和蓝牙耳机进行通讯卡了整整一周,总算是搞定了,鉴于网上相关资料实在太少,避免后面的朋友跟我一样走弯路,简单写一下实现过程。

环境配置(windows10+python3.83+pybluez0.22):

下面简单介绍一下环境的配置:
1.SDK,地址:https://developer.microsoft.com/zh-cn/windows/downloads/windows-10-sdk/,装了win10的SDK之后,要在SDK的安装目录中,将文件名由:v10.0A为v7.0A,不然会报错
2. 最新的Visual C++ Redistributable:https://www.microsoft.com/en-us/download/details.aspx?id=48145
3. NET.Framework,网址就不贴了,好像很多电脑自带的都有,没有的就装一个。
4. 另外,现在pybluez库最新的版本为0.23,但使用的时候,connect和find_service函数会报错,原因尚不清楚,后来换成0.22就不存在该问题了。

官方资料(来自pybluez库):

蓝牙通讯双方通讯,一端为server,一端为client,移动端蓝牙大部分都是server;
#server端:

from bluetooth import *

server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)

port = server_sock.getsockname()[1]

uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"

advertise_service( server_sock, "SampleServer",
                   service_id = uuid,
                   service_classes = [ uuid, SERIAL_PORT_CLASS ],
                   profiles = [ SERIAL_PORT_PROFILE ], 
#                   protocols = [ OBEX_UUID ] 
                    )
                   
print("Waiting for connection on RFCOMM channel %d" % port)

client_sock, client_info = server_sock.accept()
print("Accepted connection from ", client_info)

try:
    while True:
        data = client_sock.recv(1024)
        if len(data) == 0: break
        print("received [%s]" % data)
except IOError:
    pass

print("disconnected")

client_sock.close()
server_sock.close()

client端:

from bluetooth import *
import sys

if sys.version < '3':
    input = raw_input

addr = None

if len(sys.argv) < 2:
    print("no device specified.  Searching all nearby bluetooth devices for")
    print("the SampleServer service")
else:
    addr = sys.argv[1]
    print("Searching for SampleServer on %s" % addr)

# search for the SampleServer service
uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
service_matches = find_service( uuid = uuid, address = addr )

if len(service_matches) == 0:
    print("couldn't find the SampleServer 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" % (name, host))

# Create the client socket
sock=BluetoothSocket( RFCOMM )
sock.connect((host, port))

print("connected.  type stuff")
while True:
    data = input()
    if len(data) == 0: break
    sock.send(data)

sock.close()

官方的文档还是可以的,运行可能会存在一点小问题。看不懂的朋友可以试试下面的内容,亲测可行;

蓝牙连接:

我写的是PC端的工具,代码为client,话不多说直接公布代码吧:

import bluetooth
import sys
import time
name='小米手机10pro'#需连接的设备名字
nearby_devices = bluetooth.discover_devices(lookup_names=True)
print(nearby_devices)#附近所有可连的蓝牙设备


addr=None
for device in nearby_devices:
    if name==device[1]:
        addr = device[0]
        print("device found!",name," address is: ",addr)
        break
if addr==None:
    print("device not exist")
services = bluetooth.find_service(address=addr)
print(services)
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"])	#打印蓝牙设备的各种属性

sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
'''sock.connect((addr, 2))
print("连接成功,端口:")'''
i=0
while i<255:
    try:
        sock.connect((addr, i))
        print("连接成功,端口:",i)
        break
    except Exception as e:
        print("端口:",i,"连接失败",e)
        i=i+1							#遍历端口号,进行连接
C:\Users\Administrator.DESKTOP-2F8V7EJ\AppData\Local\Programs\Python\Python38\python.exe D:\Python\2\bt_connect.py
[('41:42:21:9C:43:1F', 'F9  '), ('A4:4B:D5:09:A9:14', '小米手机10pro')]
device found! address is  A4:4B:D5:09:A9:14
...篇幅原因,省略中间蓝牙属性打印
端口: 0 连接失败
端口: 1 连接失败
端口: 2 连接失败
连接成功,端口: 3
Process finished with exit code 0

用这个基本能实现PC端和各种移动蓝牙设备的连接,包括手机,蓝牙耳机,蓝牙音箱等;

蓝牙通讯:

虽然蓝牙连接上了,但是蓝牙那端不一定能正常收发数据,pybluez创建套接字是在RFCOMM这一层,蓝牙耳机用的是SPP协议,所以需找到对应的SPP协议,才能完成正常通讯,可以通过uuid找到SPP协议对应的端口,然后再进行通讯,代码如下:

import time
import sys
import bluetooth

#uuid = "98B97136-36A2-11EA-8467-484D7E99A198"
nearby_devices = bluetooth.discover_devices(lookup_names=True)
print(nearby_devices)
uuid = "00001101-0000-1000-8000-00805f9b34fb"
service_matches = bluetooth.find_service( uuid = uuid )
if len(service_matches) == 0:
    print("couldn't find the FooBar service")
    sys.exit(0)

first_match = service_matches[0]
print(first_match)
port = first_match["port"]
name = first_match["name"]
host = first_match["host"]

print("connecting to \"%s\" on %s" % (name, host))
sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
'''sock.connect((addr, port))
print("连接成功")'''
sock.connect((host, port))
print("连接成功")
while True:								#进入循环,不然通讯会自动关闭
	sock.send("12345".encode('utf-8'))
	sock.send("hello".encode('utf-8'))
	data=sock.recv(10)				#1024为数据长度
	print("received:",data)
	time.sleep(5)
以下为打印结果:
C:\Users\Administrator.DESKTOP-2F8V7EJ\AppData\Local\Programs\Python\Python38\python.exe D:/Python/project/test8.py
[('41:42:21:9C:43:1F', 'F9  '), ('A4:4B:D5:09:A9:14', '小米手机10pro')]
{'host': 'A4:4B:D5:09:A9:14', 'name': b'Spp Server', 'description': '', 'port': 5, 'protocol': 'RFCOMM', 'rawrecord': b'6\x00E\t\x00\x00\n\x00\x01\x00\x0e\t\x00\x015\x03\x19\x11\x01\t\x00\x045\x0c5\x03\x19\x01\x005\x05\x19\x00\x03\x08\x05\t\x00\x055\x03\x19\x10\x02\t\x00\t5\x085\x06\x19\x11\x01\t\x01\x02\t\x01\x00%\nSpp Server', 'service-classes': [b'1101'], 'profiles': [(b'1101', 258)], 'provider': None, 'service-id': None, 'handle': 65550}
connecting to "b'Spp Server'" on A4:4B:D5:09:A9:14
连接成功
received: b'12345'  #移动端蓝牙采用应答模式,即发什么,会马上回一个相同的字符串
received: b'hello'

用这个便能成功实现蓝牙通讯啦!!!

  • 18
    点赞
  • 158
    收藏
    觉得还不错? 一键收藏
  • 39
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 39
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值