寻求Seeed XIAO nRF52840的BLE配对示例(Arduino/CircuitPython均可)
Seeed XIAO nRF52840 BLE配对(手动确认+加密读写)实现方案
针对你需要的设备端按钮确认配对、加密后才能读写BLE数据的需求,以下是Arduino和CircuitPython两个平台的完整实现方案:
Arduino 实现方案
核心依赖
使用Adafruit Bluefruit nRF52 Library,该库原生支持Seeed XIAO nRF52840,包含配对绑定、权限控制等核心BLE功能。
配对流程
- 设备初始化BLE服务,设置特征访问权限为仅加密连接可读写
- 服务器发起配对请求时,设备LED闪烁提示用户确认
- 用户按下板载按钮后,设备接受配对并完成绑定
- 配对完成后,服务器可加密访问设备的BLE数据
代码示例
#include <Adafruit_BluefruitLE_SPI.h> // BLE SPI引脚配置(XIAO nRF52840默认引脚) #define BLUEFRUIT_SPI_CS 8 #define BLUEFRUIT_SPI_IRQ 7 #define BLUEFRUIT_SPI_RST 4 Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST); // 硬件引脚配置 #define PAIR_BUTTON_PIN 2 // 板载按钮引脚 #define STATUS_LED_PIN 13 // 状态LED引脚 bool pairConfirmed = false; bool pairingInProgress = false; void setup() { pinMode(PAIR_BUTTON_PIN, INPUT_PULLUP); pinMode(STATUS_LED_PIN, OUTPUT); Serial.begin(115200); while (!Serial); // 初始化BLE模块 if (!ble.begin(false)) { Serial.println("BLE模块初始化失败"); while (1); } // 配置BLE安全参数:需要配对+MITM保护+绑定 ble.sendCommandCheckOK("AT+GAPSETSEC=1,3"); // 1=强制配对,3=MITM保护(需手动确认) ble.sendCommandCheckOK("AT+GAPSETBOND=1"); // 启用绑定,保存配对信息 // 添加自定义服务和加密读写特征 ble.sendCommandCheckOK("AT+GATTADDSERVICE=UUID16=0xFFF0"); // PROPERTIES=0x12(可读可写),PERMISSIONS=0x0018(仅加密连接可访问) ble.sendCommandCheckOK("AT+GATTADDCHAR=UUID16=0xFFF1,PROPERTIES=0x12,PERMISSIONS=0x0018,VALUE=00"); // 开始广播 ble.sendCommandCheckOK("AT+GAPSTARTADV"); Serial.println("等待连接配对..."); } void loop() { ble.update(); // 处理连接事件 uint8_t event = ble.getEvent(); if (event == BLE_EVENT_GAP_CONNECTED) { Serial.println("设备已连接,等待配对请求"); pairingInProgress = true; digitalWrite(STATUS_LED_PIN, HIGH); } // 处理配对请求 if (event == BLE_EVENT_GAP_PAIRING_REQUEST) { Serial.println("收到配对请求,请按下按钮确认"); // 等待用户按下按钮 while (!pairConfirmed) { if (digitalRead(PAIR_BUTTON_PIN) == LOW) { pairConfirmed = true; ble.sendCommandCheckOK("AT+GAPACCEPTPAIR"); Serial.println("配对已确认"); digitalWrite(STATUS_LED_PIN, LOW); } delay(100); } } // 配对成功处理 if (event == BLE_EVENT_GAP_PAIRING_SUCCESS) { Serial.println("配对绑定完成,可加密读写数据"); pairingInProgress = false; pairConfirmed = false; } // 读取加密特征数据 if (ble.connected()) { uint8_t buffer[20]; uint16_t len = ble.readCharacteristic(0xFFF1, buffer, sizeof(buffer)); if (len > 0) { Serial.print("收到加密数据: "); for (int i=0; i<len; i++) { Serial.print(buffer[i], HEX); Serial.print(" "); } Serial.println(); } } }
关键说明
AT+GAPSETSEC=1,3:开启MITM保护,确保配对必须经过设备端手动确认,防止恶意配对PERMISSIONS=0x0018:限制特征仅允许加密连接访问,未配对设备无法读写数据- 按钮引脚可根据XIAO nRF52840实际硬件调整(板载按钮默认接D2)
CircuitPython 实现方案
核心依赖
使用adafruit_ble和adafruit_ble_security库,可通过CircuitPython官方Bundle安装对应版本的依赖包。
配对流程
- 初始化BLE外设,配置安全策略为MITM保护+绑定
- 服务器发起配对请求时,LED闪烁提示用户确认
- 用户按下按钮后,设备接受配对并保存绑定信息
- 自定义服务特征设置为加密访问权限,配对后服务器可读写数据
代码示例
import time import board import digitalio from adafruit_ble import BLERadio from adafruit_ble.advertising import Advertisement from adafruit_ble.services.nordic import UARTService from adafruit_ble_security import Security, PairingRequest # 硬件初始化 pair_button = digitalio.DigitalInOut(board.D2) pair_button.switch_to_input(pull=digitalio.Pull.UP) status_led = digitalio.DigitalInOut(board.D13) status_led.switch_to_output() # BLE初始化 ble = BLERadio() uart_service = UARTService() advertisement = Advertisement() advertisement.complete_name = "XIAO-BLE-Secure" # 安全配置:强制配对+MITM保护+绑定 security = Security() security.authentication = Security.AUTHENTICATION_REQUIRED security.encryption = Security.ENCRYPTION_REQUIRED security.mitm = True # 启用MITM保护,需手动确认 security.bonding = True # 保存配对信息,自动重连 pairing_confirmed = False def handle_pairing(event): """处理配对请求回调""" global pairing_confirmed if isinstance(event, PairingRequest): print("收到配对请求,请按下按钮确认") status_led.value = True # 等待用户确认 while not pairing_confirmed: if not pair_button.value: pairing_confirmed = True event.accept() print("配对已确认") status_led.value = False time.sleep(0.1) # 注册配对事件回调 ble.register_callback(handle_pairing) while True: if not ble.connected: print("开始广播,等待连接...") ble.start_advertising(advertisement, uart_service) pairing_confirmed = False else: # 配对完成后,处理加密UART数据 if uart_service.in_waiting: data = uart_service.read(uart_service.in_waiting) print(f"收到加密数据: {data.decode('utf-8').strip()}") uart_service.write(b"已收到: " + data) time.sleep(0.1) ble.update()
关键说明
security.mitm = True:开启中间人攻击防护,必须通过设备端按钮确认才能完成配对security.bonding = True:保存配对密钥,后续连接自动加密,无需重复配对- 若需自定义服务,可通过
adafruit_ble.services.Service创建,并为特征设置access_requirements=Security.ENCRYPTION_REQUIRED
内容的提问来源于stack exchange,提问作者Clyde
相关产品推荐
相关产品推荐

