文章目录
- [双手机 nRF Connect 蓝牙配网完整模拟教程](#双手机 nRF Connect 蓝牙配网完整模拟教程)
-
- [1. 角色划分与环境准备](#1. 角色划分与环境准备)
- [2. 流程鸟瞰](#2. 流程鸟瞰)
- [3. 手机 A:创建并启动虚拟蓝牙设备](#3. 手机 A:创建并启动虚拟蓝牙设备)
-
- [3.1 启动广播](#3.1 启动广播)
- [3.2 配置 GATT 服务](#3.2 配置 GATT 服务)
- [4. 手机 B:扫描、连接并进入配网页面](#4. 手机 B:扫描、连接并进入配网页面)
- [5. 发送 WiFi JSON 并校验](#5. 发送 WiFi JSON 并校验)
-
- [5.1 小程序发送](#5.1 小程序发送)
- [5.2 nRF Connect 验证](#5.2 nRF Connect 验证)
- [6. 手动推送设备响应](#6. 手动推送设备响应)
- [7. 全流程核对清单](#7. 全流程核对清单)
- [8. 常见问题速查](#8. 常见问题速查)
双手机 nRF Connect 蓝牙配网完整模拟教程
目标:利用两部手机(A 手机模拟蓝牙设备,B 手机扮演用户端/小程序),完整复现"设备上线并接收 WiFi 配网数据"的交互闭环,便于在没有真实硬件时验证配网协议、界面流程与异常分支。
1. 角色划分与环境准备
| 角色 | 设备与系统 | 需要安装的 App | 主要职责 |
|---|---|---|---|
| 手机 A | Android 9+/iOS 14+,建议电量 >40% | nRF Connect (Nordic Semiconductor) | 创建虚拟 BLE 外设,模拟 AI 笔的广播、GATT 服务与响应逻辑 |
| 手机 B | Android 8+/iOS 13+,具备蓝牙与 WiFi | 微信(或调试用 H5/原生 App) | 运行小程序或调试客户端,扫描设备、发送 WiFi JSON、接收通知 |
- 两部手机需放在 1 米内,并开启蓝牙与 WiFi。
- 若手机 B 需访问真实后台,请确认可联网;若仅验证 BLE 流程,可在离线环境使用调试版小程序。
2. 流程鸟瞰
手机 A(nRF Connect) 手机 B(小程序)
┌──────────────────────┐ ┌──────────────────────┐
│Advertiser: 广播 ZWAI001 + FFF0 UUID │ │
│Server: FFF0 -> FFF1(Write) / FFF2(Notify) │ │
└──────────────┬──────────────┘ │
│扫描 / 连接 │
└────────────────────────────────────►│扫描列表出现设备 → 连接 → 订阅 Notify
│→ 录入 WiFi → 写入 JSON
◄────────────────────────────────────┘
│接收 JSON、手动发 Notify
┌──────────────┴──────────────┐ ┌──────────────────────┐
│FFF1: {"ssid":"...","pwd":"..."} │ │
│FFF2: {"status":0,"message":"配网成功"} → 推送 │→ 展示状态、跳转下一步 │
└──────────────────────────────┘ └──────────────────────┘
3. 手机 A:创建并启动虚拟蓝牙设备
3.1 启动广播
- 打开 nRF Connect,切换到 ADVERTISER。
- 点击右上角 + 创建配置,命名为
ZWAI001(项目约定以ZWAI开头)。 - 在 Add Record 中添加:
Complete Local Name:ZWAI00116-bit Service UUIDs→Complete List:FFF0
- 确保 Connectable 打开,其余参数保持默认,保存后点击播放键开始广播。
3.2 配置 GATT 服务
-
切换到 SERVER ,点击 + →
Add Service,设置:- Service Type:
Primary - UUID Type:
16-bit - UUID:
FFF0
- Service Type:
-
在 FFF0 服务下添加两个特征值:
- FFF1(写入 WiFi)
- Properties: 勾选
WRITE+WRITE WITHOUT RESPONSE - Permissions:
WRITE - Value Type:
Text,初始可留空
- Properties: 勾选
- FFF2(通知状态)
- Properties: 勾选
NOTIFY - Permissions:
READ - Value Type:
Text,初始值{"status":0}
- Properties: 勾选
- FFF1(写入 WiFi)
-
返回服务列表确认结构如下:
Service FFF0 ├── Char FFF1 (WRITE/WRITE_NR) └── Char FFF2 (NOTIFY)
4. 手机 B:扫描、连接并进入配网页面
- 打开微信 → 项目小程序 → 进入"蓝牙配网"页面。
- 点击"开始扫描",等待 ≤10 秒看到
ZWAI001。 - 点击设备卡片或
+号创建连接,成功后小程序应提示"设备已连接"并显示 WiFi 配置表单。 - 在 nRF Connect 的 SERVER 顶部可看到
Connections: 1 device,证明连接建立。 - 展开 FFF2,若显示小铃铛图标即代表通知已订阅;如未自动订阅,可在小程序端重新进入页面或手动触发订阅逻辑。
5. 发送 WiFi JSON 并校验
5.1 小程序发送
-
在 WiFi 页面填写:
- SSID:如
TestAP - 密码:不少于 8 位,如
test123456
- SSID:如
-
点击"下一步/开始配网",客户端会向 FFF1 写入 JSON:
json{"ssid":"TestAP","pwd":"test123456"} -
控制台需能看到日志:
[蓝牙写入] 成功: {"ssid":"TestAP","pwd":"test123456"} [配网] 已提交,等待设备响应...
5.2 nRF Connect 验证
- 在 FFF1 特征详情查看 Last Value → 切换为
Text。 - 应显示与小程序一致的 JSON;若默认是 HEX,可手动切换或复制后用在线工具转码。
- 勾选验证项:
- 字符串为 UTF-8,无乱码
-
ssid/pwd字段完整 - 若长度 >20 字节,确认分包逻辑仍可写入成功
6. 手动推送设备响应
- 在 FFF2 右侧点击铅笔图标进入编辑。
- 选择
Text,输入期望的 JSON,例如:- 配网成功:
{"status":0,"message":"配网成功"} - 进行中:
{"status":1,"message":"正在连接WiFi"}(可在 2 秒后再发成功包,模拟状态流) - 失败:
{"status":2,"message":"密码错误"}或包含错误码的结构
- 配网成功:
- 点击 Send Notification 。此时:
- 小程序控制台输出
[蓝牙通知] ... - UI 根据
status切换至"成功/失败/重试"页面
- 小程序控制台输出
- 如需模拟多次重试,可依次发送不同
status,观察前端策略是否符合 PRD。
7. 全流程核对清单
准备阶段
- 手机 A 广播
ZWAI001,Connectable 已开启 - FFF0/FFF1/FFF2 服务结构正确
- 手机 B 小程序进入蓝牙页面
扫描与连接
- 小程序 10 秒内发现设备
- 点击连接后提示成功,并展示 WiFi 表单
- nRF Connect 显示
Connections: 1 - FFF2 显示通知订阅(铃铛图标)
配网数据
- 小程序写入 JSON 成功
- FFF1
Last Value显示相同 JSON - 无乱码或截断
通知与 UI
- FFF2 推送
{"status":0}后,小程序跳转成功页面 - 推送
{"status":2}时 UI 能提示失败并允许重试 - 多次通知时客户端能覆盖旧状态
收尾
- 断开连接(nRF Connect → Connections → Disconnect)
- 停止广告 → 保存配置以便下次复用
- 将本次日志、截图归档到测试记录
8. 常见问题速查
| 问题 | 现象 | 解决方案 |
|---|---|---|
| 扫不到设备 | 小程序长时间显示"未发现设备" | 确认手机 A 广播仍在运行、设备名以 ZWAI 开头,必要时重启广告;保证 BLE 权限已授权 |
| 连接失败 | 点击 + 后立即报错 |
检查 Advertiser 是否允许连接;确认服务器端存在 FFF0 服务;尝试关闭手机 A 其他蓝牙连接后重试 |
| 看不到 JSON | FFF1 没有最新值或显示乱码 | 切换显示模式为 Text,确认写入权限为 WRITE;若仍为空,可在小程序端打印 wx.writeBLECharacteristicValue 返回值 |
| 通知没反应 | 小程序收不到 FFF2 的通知 | 确认已经订阅 Notify(铃铛点亮);发送时务必使用 Send Notification;检查 JSON 是否为合法 UTF-8 |
| 多次重试后挂起 | 小程序停留在加载态 | 先发送 {"status":2} 观察失败流;若需要重置,可断开连接后重新扫描 |