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

简介: 大家好,我是ST!上次给大家分享了如何使用ESP32实现UDP通信,今天跟大家聊聊如何使用ESP32实现蓝牙通信。

40331ed7cbcc1717eed8c84dc8d525ce.png

一、蓝牙简介

蓝牙是一种无线通讯技术,可实现固定设备、移动设备之间的数据交换。一般将蓝牙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 堆栈的事件注册回调。如下官方给出的事件处理程序(部分截图):


4f9ca341a5b654cedb06385aedea3eba.png

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 Pin
from machine import Timer
from time import sleep_ms
import bluetooth
BLE_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

1e5b4712655c79086a5a0ad54eb92636.jpeg

安卓用户可下载BLE调试宝

f87ade4518f9272445ca1d35421f05de.jpeg

目录
相关文章
|
6月前
|
网络协议 数据处理 数据格式
51单片机ESP8266云端通信的实现
51单片机ESP8266云端通信的实现
415 1
|
网络协议 IDE 开发工具
基于ESP8266远程舵机的控制与实现
基于ESP8266远程舵机的控制与实现
1587 0
基于ESP8266远程舵机的控制与实现
|
5月前
|
网络协议
了解AT指令以及STM32F103如何通过ESP8266连接到WiFi
AT指令是一组用于控制调制解调器的命令,最早由Hayes公司为其智能调制解调器开发。如今,AT指令已被广泛应用于各种通信模块中,包括GSM、Bluetooth和WiFi模块。AT指令通常以“AT”开头,后跟特定的命令和参数。通过这些指令,我们可以执行一系列操作,如设置网络参数、发送数据和查询状态等。
211 0
|
6月前
|
网络协议 物联网
|
网络协议 物联网 数据安全/隐私保护
CC2530+ESP8266与手机APP通信
通过CC2530控制ESP8266将其配置成AP+TCP服务器模式,并通过手机APP连接到TCP服务器并完成数据传输。ESP8266将作为一个热点(AP)来工作,其WiFi模块被配置为建立一个TCP服务器并监听端口号。CC2530将使用其串口与ESP8266进行通信,并通过AT指令控制ESP8266的WiFi模块设置和数据传输。
624 0
|
C语言 开发工具
STM32 ESP8266-01S 简单无线控灯
机智云物联网平台 STM32 ESP8266-01S 简单无线控灯
413 1
|
数据采集 网络协议 人机交互
【STM32】ESP8266 wifi模块创建阿里云产品
什么是ESP8266呢?这个是WiFi模块,是一个由安可信科技公司开发出来的模块,这个模块的核心处理器ESP8266在比较小的尺寸封装中集成了业界领先的微型的MCU,它带有了16位精简的模式,主要的频率支持80MHz和160MHz,支持RTOS,集成WiFi,板载天线。
【STM32】ESP8266 wifi模块创建阿里云产品
|
智能硬件
STM32智能家居(4)ESP8266连接WIFI
STM32智能家居(4)ESP8266连接WIFI
690 0
|
智能硬件
STM32智能家居7天小项目(3)ESP8266和STM32的通信简单介绍
STM32智能家居7天小项目(3)ESP8266和STM32的通信简单介绍
218 0
|
网络协议 算法 安全
ESP8266 WIFI模块的使用
ESP8266 WIFI模块的使用