利用ESP32实现蓝牙通信的方法

​大家好,我是ST!

上次给大家分享了如何使用ESP32实现UDP通信,今天跟大家聊聊如何使用ESP32实现蓝牙通信。

目录

一、蓝牙简介

二、miropython有关蓝牙的实现方法

三、我的实验代码

四、手机调试APP


利用ESP32实现蓝牙通信的方法_第1张图片

一、蓝牙简介

蓝牙是一种无线通讯技术,可实现固定设备、移动设备之间的数据交换。一般将蓝牙3.0之间的BR/EDR蓝牙称为传统蓝牙,而将蓝牙4.0规范下的LE蓝牙称为低功耗蓝牙。目前,蓝牙技术已经应用到各个领域,并已经成为接入物联网的主要技术。如今,借助于ESP32平台,MicroPython中也能够使用蓝牙BLE协议进行通信。这对MicroPython平台而言,自然丰富了其生态,增强了其技能,反过来讲,蓝牙BLE能够在MicroPython中得以集成,借助Python语言的易用性,亦将大大降低其入门门槛。

二、miropython有关蓝牙的实现方法

在miropython官网中,提供蓝牙接口模块为bluetooth,下面简单介绍一下本次实验用到的一些方法。

网址:http://docs.micropython.org/en/v1.18/library/bluetooth.html

1)BLE.active([active, ]/)

可选地更改BLE无线电的活动状态,并返回当前状态。在此类上使用任何其他方法之前,必须使无线电处于活动状态。

2)BLE.config(*, param=value, ...)

获取或设置 BLE 接口的配置值。要获取一个值,参数名称应该作为字符串引用,并且一次只查询一个参数。要设置值,请使用关键字语法,一次可以设置一个或多个参数。

3)BLE.irq(handler, /)

为来自 BLE 堆栈的事件注册回调。如下官方给出的事件处理程序(部分截图):

利用ESP32实现蓝牙通信的方法_第2张图片

4)BLE.gap_advertise(interval_us, adv_data=Non,*,resp_data=None,...)

以指定的时间间隔(以微秒为单位)开始广播。此间隔将向下舍入到最接近的 625us。要停止广播,请将interval_us设置为None。

adv_data和resp_data可以是实现缓冲协议的任何类型(例如bytes, bytearray, str)。adv_data包含在所有广播中,resp_data发送以回复主动扫描。

注意:如果adv_data(或resp_data)是None,那么传递给先前调用的数据gap_advertise将被重新使用。这允许广播公司仅使用gap_advertise(interval_us). 要清除广告有效载荷,请传递一个空的bytes,即b''。

5)BLE.gatts_register_services(services_definition, /)

用指定的服务配置服务器,替换任何现有的服务。services_definition是一个服务列表,其中每个服务是一个包含一个UUID和一个特征列表的双元素元组。每个特征都是两个或三个元素的元组,包含一个UUID、一个标志值和可选的描述符列表。每个描述符都是一个包含UUID和标志值的双元素元组。这些标志是下面定义的标志的位或组合。这些设置了特征(或描述符)的行为以及安全和隐私需求。返回值是一个元组列表(每个服务一个元素)(每个元素是一个值句柄)。按照定义的顺序,特征和描述符句柄被平展到同一个元组中。

以下官方示例注册了两个服务(Heart Rate, and Nordic UART):

HR_UUID = bluetooth.UUID(0x180D)HR_CHAR = (bluetooth.UUID(0x2A37), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,)HR_SERVICE = (HR_UUID, (HR_CHAR,),)UART_UUID = bluetooth.UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E')UART_TX = (bluetooth.UUID('6E400003-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,)UART_RX = (bluetooth.UUID('6E400002-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_WRITE,)UART_SERVICE = (UART_UUID, (UART_TX, UART_RX,),)SERVICES = (HR_SERVICE, UART_SERVICE,)( (hr,), (tx, rx,), ) = bt.gatts_register_services(SERVICES)

6)BLE.gatts_read(value_handle, /)

读取此句柄(已由gatts_write或远程客户端写入)的本地值。

7)BLE.gatts_notify(conn_handle, value_handle, data=None, /)

向已连接的客户端发送通知请求。

如果data不是None,那么该值将作为通知的一部分发送给客户端。本地值不会被修改。否则,如果data为None,则将发送当前本地值(与gatts_write设置的一样)。注意:无论客户端对该特性的订阅状态如何,通知都将被发送。

8)bluetooth.UUID(value, /)

使用指定的值创建一个UUID实例。取值为:

16位整数,例如0 x2908

128位的UUID字符串,例如:'6E400001-B5A3-F393-E0A9-E50E24DCCA9E'

三、我的实验代码

from machine import Pinfrom machine import Timerfrom time import sleep_msimport bluetoothBLE_MSG = ""class ESP32_BLE():    def __init__(self, name):        self.led = Pin(22, Pin.OUT)        self.timer1 = Timer(0) #创建定时器0对象        self.name = name        self.ble = bluetooth.BLE() #创建蓝牙对象        self.ble.active(True) #启动蓝牙        self.ble.config(gap_name=name) #给蓝牙设置一个名字        self.disconnected()        self.ble.irq(self.ble_irq) #蓝牙中断函数        self.register()        self.advertiser()    def connected(self):        self.led.value(0)  #点亮LED指示灯        self.timer1.deinit() #取消定时器    def disconnected(self):  #100ms调用一次 mode循环计时  lambda匿名函数              self.timer1.init(period=100, mode=Timer.PERIODIC, callback=lambda t: self.led.value(not self.led.value()))    def ble_irq(self, event, data):        global BLE_MSG  #替换外部的同名变量        if event == 1: #_IRQ_CENTRAL_CONNECT 手机链接了此设备            self.connected()        elif event == 2: #_IRQ_CENTRAL_DISCONNECT 手机断开此设备            self.advertiser() #向外发送信号,广播            self.disconnected()        elif event == 3: #_IRQ_GATTS_WRITE 手机发送了数据             buffer = self.ble.gatts_read(self.rx)            BLE_MSG = buffer.decode('UTF-8').strip()                def register(self):                service_uuid = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'        reader_uuid = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'        sender_uuid = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'        #创建一个元组        services = (            (                bluetooth.UUID(service_uuid), #服务ID,可以定义多个服务                (                    (bluetooth.UUID(sender_uuid), bluetooth.FLAG_NOTIFY), #服务具体类型                    (bluetooth.UUID(reader_uuid), bluetooth.FLAG_WRITE),  #服务具体类型                )            ),         )        ((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')        adv_data = bytearray('\x02\x01\x02') + bytearray((len(name) + 1, 0x09)) + name        self.ble.gap_advertise(100, adv_data)  #100us发布一次广告        print(adv_data)        print("\r\n")def buttons_irq(pin):    led.value(not led.value())    print('LED is ON.' if led.value() else 'LED is OFF')    ble.send('LED is ON.' if led.value() else 'LED is OFF')if __name__ == "__main__":    ble = ESP32_BLE("ESP32BLE")    but = Pin(0, Pin.IN)    but.irq(trigger=Pin.IRQ_FALLING, handler=buttons_irq)    led = Pin(22, Pin.OUT)    while True:                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        if BLE_MSG == 'read_LED':            led.value(not led.value())            print(BLE_MSG)            BLE_MSG = ""            print('LED is ON.' if led.value() else 'LED is OFF')            ble.send('LED is ON.' if led.value() else 'LED is OFF')        sleep_ms(100)

程序代码思路:蓝牙在未连接时,指示灯不断闪烁,当蓝牙被连接时,指示灯由闪烁变为常亮。当用户用手机APP发送“read_LED”时,指示灯翻转,并打印出接收到的消息。用户可通过手机APP设置提醒功能。ESP32可通过中断控制指示灯亮灭并提醒手机用户。

四、手机调试APP

IOS用户可下载LightBlue

利用ESP32实现蓝牙通信的方法_第3张图片

安卓用户可下载BLE调试宝

利用ESP32实现蓝牙通信的方法_第4张图片

你可能感兴趣的:(单片机项目实战操作之优秀,单片机)