本人大四,目前在嵌入式实验室实习,现在想要用MicroPython语言实现两块Wifi Lora 32 v2开发板的蓝牙互联功能并实现数据传输。
我已经在网上查找了很多资料,大部分类似的蓝牙连接都是介于单块开发板与手机、电脑等终端之间的,通过让开发板广播可连接信号,并用终端上的一些BLE控制台来连接,实现数据传输,这一点我在配置外围设备(Peripheral Role)时已经正常实现,具体的自建BLE库如下:
from machine import Pin, Timer
import time
import ubluetooth
class BLE():
def __init__(self, name):
self.name = name
self.connect_sign = False
self.ble = ubluetooth.BLE()
self.ble.active(True)
self.led = Pin(25, Pin.OUT)
self.timer1 = Timer(0)
self.timer2 = Timer(1)
self.disconnected()
self.ble.irq(self.ble_irq)
self.register()
self.advertiser()
def connected(self):
self.timer1.deinit()
self.timer2.deinit()
self.connect_sign = True
def disconnected(self):
self.timer1.init(period=1000, mode=Timer.PERIODIC, callback=lambda t: self.led(1))
time.sleep(0.2)
self.timer2.init(period=1000, mode=Timer.PERIODIC, callback=lambda t: self.led(0))
self.connect_sign = False
def ble_irq(self, event, data):
if event == 1:
'''Central connected'''
self.connected()
self.led(1)
elif event == 2:
'''Central disconnected'''
self.advertiser()
self.disconnected()
elif event == 3:
'''New message received'''
buffer = self.ble.gatts_read(self.rx)
message = buffer.decode('UTF-8').strip()
print(message)
def register(self):
# Nordic UART Service (NUS)
NUS_UUID = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
TX_UUID = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'
RX_UUID = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'
BLE_NUS = ubluetooth.UUID(NUS_UUID)
BLE_RX = (ubluetooth.UUID(RX_UUID), ubluetooth.FLAG_WRITE)
BLE_TX = (ubluetooth.UUID(TX_UUID), ubluetooth.FLAG_NOTIFY)
BLE_UART = (BLE_NUS, (BLE_TX, BLE_RX,))
SERVICES = (BLE_UART, )
((self.tx, self.rx,), ) = self.ble.gatts_register_services(SERVICES)
def send(self, data):
self.ble.gatts_notify(0, self.tx, data + '\n')
def advertiser(self):
name = bytes(self.name, 'UTF-8')
self.ble.gap_advertise(100, bytearray('\x02\x01\x02') + bytearray((len(name) + 1, 0x09)) + name)
这一段主要就是实现在创建BLE类对象后就进行一系列初始化,例如NUS通讯的串口配置,中断回调函数的设定和广播信号,通过这个片段来实现手机和开发板之间的通讯已经完全足够了。
问题出在当我将手机更换为另一块Wifi Lora 32 v2开发板作为中心设备(Central Role)时。当我更换之后,我必须要修改中断回调函数,因为根据micropython官方ubluetooth库的中断向量表,中心设备和外围设备被连接和断连的event值是不同的,详见https://docs.micropython.org/en/v1.15/library/ubluetooth.html%EF%BC%8C%E5%85%B6%E4%B8%AD%E4%B8%AD%E5%BF%83%E8%AE%BE%E5%A4%87%E7%9A%84%E8%BF%9E%E6%8E%A5%E4%B8%8E%E6%96%AD%E8%BF%9E%E6%98%AFevent 7和8,外围设备连接与断连是event 1和2,因此我针对这点对我的BLE库进行了扩展,代码如下:
from machine import Pin, Timer
import time
import ubluetooth
class BLE():
def __init__(self, name):
self.name = name
self.connect_sign = False
self.ble = ubluetooth.BLE()
self.ble.active(True)
self.addr_type = None
self.addr = None
self.led = Pin(25, Pin.OUT)
self.timer1 = Timer(0)
self.timer2 = Timer(1)
self.disconnected()
self.ble.irq(self.ble_irq)
self.register()
self.advertiser()
def connected(self):
self.timer1.deinit()
self.timer2.deinit()
self.connect_sign = True
def disconnected(self):
self.connect_sign = False
self.timer1.init(period=1000, mode=Timer.PERIODIC, callback=lambda t: self.led(1))
time.sleep(0.2)
self.timer2.init(period=1000, mode=Timer.PERIODIC, callback=lambda t: self.led(0))
def ble_irq(self, event, data):
if event == 1:
'''Central connected'''
print("as Peripheral connected")
self.connected()
self.led(1)
elif event == 2:
'''Central disconnected'''
self.advertiser()
self.disconnected()
elif event == 3:
'''New message received'''
buffer = self.ble.gatts_read(self.rx)
message = buffer.decode('UTF-8').strip()
print(message)
elif event == 7:
'''Peripheral connected'''
print("as Central connected")
self.connected()
self.led(1)
elif event == 8:
'''Connected peripheral has disconnected'''
self.advertiser()
self.disconnected()
def register(self):
# Nordic UART Service (NUS)
NUS_UUID = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
RX_UUID = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'
TX_UUID = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'
BLE_NUS = ubluetooth.UUID(NUS_UUID)
BLE_RX = (ubluetooth.UUID(RX_UUID), ubluetooth.FLAG_WRITE)
BLE_TX = (ubluetooth.UUID(TX_UUID), ubluetooth.FLAG_NOTIFY)
BLE_UART = (BLE_NUS, (BLE_TX, BLE_RX,))
SERVICES = (BLE_UART, )
((self.tx, self.rx,), ) = self.ble.gatts_register_services(SERVICES)
def send(self, data):
self.ble.gatts_notify(0, self.tx, data + '\n')
def advertiser(self):
name = bytes(self.name, 'UTF-8')
self.ble.gap_advertise(100, bytearray('\x02\x01\x02') + bytearray((len(name) + 1, 0x09)) + name)
def connect(self, addr_type, addr):
self.addr_type = addr_type
self.addr = addr
self.ble.gap_connect(self.addr_type, self.addr)
增加了作为中心设备的连接功能,增加了中断回调函数中的事件7和8,细心的朋友可能还会发现,我把register中的Rx_UUID和Tx_UUID做了更换(这点我不确定对不对),下面我先说一下我的问题在哪,然后详细告诉大家我的各种尝试和困惑。
首先我已经能够通过shell中print出的内容确定,这两个设备能够互联上,当我用Thonny编译器监测中心设备时,两块开发板板载LED灯很快变为常亮,我在shell中收到as Central connected,当我监测外围设备时,shell中收到as Peripheral connected。但是当我尝试从中心设备向外围设备发消息时,外围设备收不到,收到消息的event 3不会被触发。同时,我的外围设备上挂了一块GPS模块,能够将数据解码并持续发送给已连接的中心设备,同样,中心设备收不到(外围设备发送消息的能力已经验证过是正常的,即我在手机BLE控制台上可以收到消息,也可以向外围设备发送消息,能够在shell上看到我向它发送的消息,证明event 3被触发)。
于是乎我开始怀疑是我的通讯配置有问题,因为能够互联,就是互相收不到消息。因此我调换了两个开发板的Rx_UUID和Tx_UUID,我在网上查到这个通讯方式是类UART的,我以前就有过把TX接TX,RX接RX的小脑行为,但是这次我不论调换还是不调换,都还是没有消息传输。
我已经被这个问题折磨两天了,仍然没有找到任何解决方案,我认为问题还是主要出现在通信上,因此想来CSDN寻求帮助,有人能帮我看看问题出在哪里吗,提前感谢!
文章中链接识别的有问题,还吞掉了我的一句话,“其中中心设备的连接与断连是event 7和8”,链接如下:
https://docs.micropython.org/en/v1.15/library/ubluetooth.html
参考GPT和自己的思路:
根据你提供的信息和代码,我认为出现问题的可能原因有以下几个:
蓝牙连接的状态未能正确判断。在你的代码中,通过中断回调函数监测连接的事件,在事件1和7时你分别将connect_sign设置为True,但在事件2和8时只将其设置为False。这样可能会导致在连接出现异常情况时(比如中途断开),两块开发板之间的连接状态无法正确判断。建议在断开连接时做一些清理工作,比如删除已有的连接对象,确保下次连接时是一个全新的连接。
蓝牙通信的配置可能有误。在你的代码中,通过gatts_register_services注册了一个Nordic UART Service (NUS),同时使用了两个特征值,分别用来接收和发送数据。但是在注册特征值时,你将RX和TX的UUID设置反了,这可能会导致通信无法正常传输。建议调整UUID的设置,将RX和TX正确地对应到自己的特征值上。
数据传输的形式可能有误。在你的代码中,发送数据时通过gatts_notify发送了一个带有换行符的字符串,这意味着对端设备在接收到数据后需要按照特定的格式进行处理。如果对端设备无法正确解析收到的数据,可能会导致通信异常。建议将发送的数据格式化为合适的二进制格式,以确保数据能够正确传输。
综上所述,建议你逐一排查以上可能存在的问题,并针对性进行调整。希望问题能够顺利解决,祝你实习愉快!
不知道你这个问题是否已经解决, 如果还没有解决的话:2S 任务是否明确? (明确)Specific + ( 真诚沟通 ) Sincere communication
W 价值是否显著?(直接+间接)worth
P 数据是否可以共享?privacy
A 是否可以实现?Attainable
L 是否有行业案例或相关可学习资料?learn
U 上层意愿(不见兔子不撒鹰)upper layer
D 模型所需的数据 data
T 时间线(基本节点)Time-bound
H 硬件机器 Hardware machine
C 部门间协作 Cooperate
F 容错性 Fault tolerance
B 项目瓶颈节点 bottleneck (3)
R 人员占比(算法/项目/硬件/外部)Ratio of personnel
I 学术浪潮 Industry wave
E 是否可边缘计算 Edge calculation
F 计算框架 Technical framework
K AI知识普及 Popularization of knowledge