MicroPython双Wifi Lora 32 v2开发板蓝牙互联

本人大四,目前在嵌入式实验室实习,现在想要用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. 蓝牙连接的状态未能正确判断。在你的代码中,通过中断回调函数监测连接的事件,在事件1和7时你分别将connect_sign设置为True,但在事件2和8时只将其设置为False。这样可能会导致在连接出现异常情况时(比如中途断开),两块开发板之间的连接状态无法正确判断。建议在断开连接时做一些清理工作,比如删除已有的连接对象,确保下次连接时是一个全新的连接。

  2. 蓝牙通信的配置可能有误。在你的代码中,通过gatts_register_services注册了一个Nordic UART Service (NUS),同时使用了两个特征值,分别用来接收和发送数据。但是在注册特征值时,你将RX和TX的UUID设置反了,这可能会导致通信无法正常传输。建议调整UUID的设置,将RX和TX正确地对应到自己的特征值上。

  3. 数据传输的形式可能有误。在你的代码中,发送数据时通过gatts_notify发送了一个带有换行符的字符串,这意味着对端设备在接收到数据后需要按照特定的格式进行处理。如果对端设备无法正确解析收到的数据,可能会导致通信异常。建议将发送的数据格式化为合适的二进制格式,以确保数据能够正确传输。

综上所述,建议你逐一排查以上可能存在的问题,并针对性进行调整。希望问题能够顺利解决,祝你实习愉快!

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 文章:简述物联网系统的分层架构,简要说明各层级的功能,并结合课程内容谈谈各层有哪些物联网的技术运用,在DIY智慧小屋案例中各层都有哪些软硬件构成。 中也许有你想要的答案,请看下吧
  • 除此之外, 这篇博客: AI技术工业落地法则序中的     毫无疑问人工智能(AI)是当前社会最火爆的技术,上到国家政策的制定,将AI定为未来20年中国崛起的核心驱动力,下到各省市陆续出版的小学生AI教辅材料,以及资本市场对AI这一领域的持续疯狂投入,加上BAT,TMD,华为等这些大企业铺天盖地的宣传,似乎一夜之间我们就迈入了人工智能的时代。是,也不是,之所以这么说是因为展现在我们手机屏幕上的各种新闻都在给我们灌输着人工智能无处不在,从百度无人车的批量下线运行,到已经烂大街的天猫精灵音响和小米智能音响,以及偶尔出现在我们视野中的彩虹无人机到荣登今年315晚会的智能电话客服,这一切都在表明我们正在步入人工智能的时代。由大数据,人工智能,云计算,5G等多个领域技术掀起的第4次工业革命正在有条不紊的拉开大幕渗透进我们的生活当中,不可否认AI在图像识别,NLP,语音等领域所取得的突破和带来的变化,让数百万的电话接线员缓缓的退出历史舞台,让不同语言交流的困难渐渐缩小,也让无人驾驶汽车从不可能变为可能。媒体,互联网公司,程序员,学校,家长一切的一切都在将AI推向神坛,典型例子就是创业公司不带上AI宣传字样仿佛就是另类,于是乎大大小小的企业都开始了追寻AI之路。 回到标题,你会疑惑为何要加上工业二字,没错本人从事的一直都是工业物流这块,是因为AI在互联网领域已经取得了不错的成绩和大量成熟的案例,在推荐,金融贷款审核,智能客服等等可谓百花齐放,用一个公式来简单概括AI技术:神经网络算法+海量数据=AI,只有满足这两点才能够发挥AI的潜力。对于互联网公司来说基于海量移动端客户的数据加上日新月异的算法可谓天时地利人和。可是为什么我们身边大大小小的工厂,以及身处实业的朋友却还没有感受到AI技术的落地呢?用侦探柯南的一句话来说“真相只有一个”——需要满足AI落地工业的18个条件,是的你没有看错,是18个。为什么是18个条件,而不是3个条件,对于每一个条件的思考和实践都是本人这些年参与项目所积累的心得体会,酸甜苦辣个中滋味都希望通过这一系列的博客与大家分享项目的成功经验与解决思路,把更多更好实用的AI技术带到我们的身边。后面我会通过一系列文章来阐述这些条件的由来和原因。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    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


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^