蓝牙是当前使用最为广泛的无线通讯协议之一。它主要用于短距离设备之间的数据传输,如耳机、鼠标、移动通讯设备等。蓝牙技术的广泛应用使得这些设备之间的连接变得更加方便和高效。
蓝?分为两种不同的技术:经典蓝? (Classic Bluetooth) 和低功耗蓝牙 (Bluetooth Low Energy)。ESP32 ?持双模蓝?,即同时?持经典蓝?和低功耗蓝?。
经典蓝牙 vs 低功耗蓝牙
经典蓝牙和低功耗蓝牙有什么区别呢?
经典蓝牙
经典蓝牙是一种传统的蓝牙技术,泛指支持蓝牙协议在4.0以下的模块技术,用于在短距离范围内进行数据传输和设备连接。它的主要特点如下:
- 传输速率:经典蓝牙支持不同的传输速率,最高可达到3 Mbps(高速蓝牙模块速度达到24Mbps)。这使得它适用于传输大量数据或高质量音频。
- 连接数量:经典蓝牙可以同时连接多个设备,最多支持7个主动连接和255个被动连接。这使得多个设备可以同时进行数据传输和通信。
- 通信范围:经典蓝牙的通信范围通常在10米左右,但在理想条件下可能会更远。这使得设备之间可以在较短的距离内进行通信,适用于个人设备之间的连接。
- 应用领域:经典蓝牙广泛应用于各种领域,如文件传输、音频传输、打印、数据同步等。它可以连接手机、电脑、音频设备等多种设备,提供了方便的数据传输和通信功能。
尽管经典蓝牙在传输速率和连接数量方面具有优势,但它的功耗相对较高。为了满足低功耗需求,低功耗蓝牙(Bluetooth Low Energy,简称BLE)技术应运而生。
低功耗蓝牙
低功耗蓝牙指支持蓝牙协议4.0或更高的模块。BLE被设计为能够在低功耗模式下运行,以延长设备的电池寿命。
相比于经典蓝牙,BLE的功耗要低得多,适用于需要长时间运行的设备,如传感器、健康监测设备等。BLE支持多个设备之间的连接,最多可同时连接到20个设备,这使得它适用于需要与多个设备进行通信的场景,广泛应用于物联网、健康监测、智能家居、运动追踪等领域。它可以连接到智能手机、平板电脑等主设备,实现数据传输、传感器数据采集等功能。
在介绍具体蓝牙实现脚本之前,还是要介绍一下蓝牙架构,否则不太好理解。
蓝牙架构
从整体结构上,蓝?可分为控制器 (Controller) 和主机 (Host) 两?部分。
控制器包括了 PHY、Baseband、Link Controller、Link Manager、Device Manager、HCI 等模块,?于硬件接?管理、链路管理等等;主机则包括了 L2CAP、SMP、SDP、ATT、GATT、GAP 以 及各种规范,构建了向应?层提供接?的基础,?便应?层对蓝?系统的访问。主机可以 与控制器运?在同?个宿主上,也可以分布在不同的宿主上。
ESP32 的控制器同时?持 Classic BT 和 Bluetooth LE,?持的蓝?版本为 V4.2。控制器 中主要集成了 H4 协议、HCI、Link Manager、Link Controller、Device Manager、HW Interface 等功能。
蓝牙技术中几个专用名词:
Central:中心设备,发起蓝牙连接的设备,比如手机,主动扫描、连接外设
Peripheral:外设,被蓝牙连接的设备,比如运动手环,发起广播,提供数据
Service and Characteristic:服务和特征,每个设备会提供服务和特征,每个服务中包含很多特征,这些特征的权限一般分为读(read),写(write),通知(notify)几种,特征值用于保存用户数据
下面来介绍一下如何用micropython来实现BLE功能
创建 BLE 代码流程:
- 1,创建一个BLE 外设。这里使用 ESP32蓝牙功能。
- 2,创建BLE服务
- 3,在服务上创建BLE特性
- 4,在特征上创建一个BLE描述符
- 5,启动服务
- 6,开始广播
蓝牙初始化代码:
class BLE():
def __init__(self, name):
self.name = name
self.ble = bluetooth.BLE()
self.ble.active(True)
self.led = Pin(2, Pin.OUT)
self.timer1 = Timer(0)
self.disconnected()
self.ble.irq(self.ble_irq)
self.register()
self.advertiser()
连接函数:
def connected(self):
self.timer1.deinit()
断开连接:
def disconnected(self):
self.timer1.init(period=1000, mode=Timer.PERIODIC, callback=lambda t: self.led(0))
蓝牙事件处理函数:
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()
蓝牙UUID配置函数,配置蓝牙广播,让手机app可以扫描到esp32的蓝牙信息,从而进行蓝牙连接。
def register(self):
# Nordic UART Service (NUS)
NUS_UUID = '00002101-0000-1000-8000-00805F9B34FB9E'
RX_UUID = '00002102-0000-1000-8000-00805F9B34FB'
TX_UUID = '00002103-0000-1000-8000-00805F9B34FB'
BLE_NUS = bluetooth.UUID(NUS_UUID)
BLE_RX = (bluetooth.UUID(RX_UUID), bluetooth.FLAG_WRITE)
BLE_TX = (bluetooth.UUID(TX_UUID), bluetooth.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.encode(), 'UTF-8')
self.ble.gap_advertise(100, bytearray('\x02\x01\x02'.encode()) + bytearray((len(name) + 1, 0x09)) + name)
另外虽然ESP32是双模蓝牙,但在当前的MicroPython固件中尚不支持传统蓝牙功能,只能使用BLE来通讯,但这个不妨碍物联网场景使用,毕竟BLE的低功耗、快速连接等特性具有相当的优势。