AI 编程课
完整教案
自学课件
20 课 · 共 20/48

蓝牙 BLE ——附近设备如何发现彼此

课时
待定
器材
ESP32-S3 触摸屏板 + USB 线
前置知识
配套代码
见项目 demo 目录

自学读本:跟着读、照着做,卡住就问 AI

你好,我是吴老师。

这份是给你自己读的——不用等我讲,你一段一段往下看,看到让你停下来的地方,就照着做一遍。看不懂的整段复制给 AI,加一句"请一次只解释一个概念,讲完问我一个小问题"。

读完之后,你应该能:说出 BLE 靠"广播+扫描"互相认识;用"文件夹/文件"解释服务和特征值;亲手让板子扫描出周围的 BLE 设备;用电脑 Python 脚本读写板子的特征值(开关灯/读温度/看电量)。

用时:60–90 分钟。准备:板子、数据线、Skill 已接入的 WorkBuddy;demo01/03 不需要电脑,demo02 需要一台开了蓝牙的教室电脑(装一次 pip install bleak)。


一、板子能"不联网"就和别人说话吗?

过去几课,板子跟别人说话都要先连 WiFi(17 连路由器、18 局域网、19 上互联网)。

问题来了:如果身边没有路由器、没有 WiFi,两块板子还能说话吗?

能。你的无线耳机、手环、鼠标都在用这个答案——蓝牙。今天用它的低功耗版本 BLE(Bluetooth Low Energy),让板子当一回"手环",跟教室电脑用 BLE 说话。

悬念:板子不连 WiFi、不插网线,电脑打开蓝牙就能发现它、还能读写它的数据。中间到底发生了什么?

二、BLE 世界里,设备怎么"认识"?

WiFi 靠"连同一个路由器"认识。BLE 只有两件事:

  • 广播:设备不停喊"我在这,我是 XXX"(像举着灯牌晃)
  • 扫描:别的设备竖起耳朵听,把喊话的记下来(像观众找灯牌)

先让板子当"观众":

请使用课程的 esp32s3-touchboard-hardware-dev Skill,
烧录本课配套程序 assets/codes/demo01_ble_scan_radar:
板子变成"蓝牙雷达",每 5 秒扫一次,把正在广播的设备按信号强弱列出来
(名字 + RSSI)。烧录后告诉我你扫到了什么。

打开教室电脑蓝牙,按 BOOT 让板子立刻扫一次。

我观察到的现象勾选
列表里出现电脑/其他设备的名字
每台设备后面有负数 RSSI(如 -58dBm)
板子拿远一点再扫,RSSI 更负了
电脑蓝牙一关,它就从列表消失

为什么板子没连上它们,却"知道"它们在?因为每台开着蓝牙的设备都在不停广播,板子只是听见了。

代码关键:BLEDevice::getScan()->start(...) 让板子开始"听";每台设备带名字和 RSSI(信号强度,越接近 0 越近)。

三、把"耳朵"和"嘴"分开看

扫描是"耳朵","嘴"呢?让一两块板子闭嘴喊话:

请给一两块板子改烧录 assets/codes/demo03_ble_advertise_card:
它只做一件事——不停广播自己(默认 AI-PAD-6)。
让旁边跑 demo01 雷达的板子扫一扫,看会不会多出 AI-PAD-6。

demo01 = 观众(扫描),demo03 = 演员(广播)。广播自己不需要对方同意——你喊你的,谁听见算谁的。

⚠️ 比喻有边界:"广播像喊话"是指它单向、公开、省电(不是真的大喊);RSSI 只能比较远近(墙/人会干扰),量不出"正好 3 米"。

改一个条件:把 demo03 顶部的 AD_NAME 改成别的名字,重烧。旁边雷达屏上这个名字立刻变了——广播里喊什么,由喊的人决定

四、听见了,然后呢?——服务与特征值

光认识没用,你要能读写它的数据。BLE 把数据组织得像文件夹:

  • 服务文件夹(这块板子是一个"教室灯"文件夹)
  • 特征值 像文件夹里的文件:能读的(温度/电量)、能写的(开关)、会自己变还"通知"你的(电量)

让板子当"教室灯",把三个文件摆出来:

请改烧录 assets/codes/demo02_ble_light_server:
板子广播自己叫 ESP32-LIGHT,身上三个特征值:
   开关(可写):写"1"灯亮、写"0"灯灭
   电量(可读+通知):每秒自己变,变了通知电脑
   温度(可读):每次读都会变
烧录后告诉我板子显示什么。

板子屏幕有一盏大灯(灭的)。电脑不装 App、不连 WiFi,用一小段 Python 当遥控器:

pip install bleak            # 只装一次
python pc/ble_light_peer.py  # 在 assets/codes/pc/ 目录下

它会自动找到 ESP32-LIGHT 并连上。然后:

按键我预测板子会怎样实际看到
w(写"1")自己填实验后填
x(写"0")自己填实验后填
r(读温度)自己填实验后填
b(盯 3 秒电量)自己填实验后填

回答:这次板子和电脑之间有 WiFi 吗?有网线吗? 都没有。BLE 的"连接"不过是:先听见你(广播+扫描)→ 翻开你的文件夹(服务)→ 读读写写里面的文件(特征值)。

两个代码名:

  • 服务端 createCharacteristic(..., PROPERTY_WRITE/READ/NOTIFY) = 在文件夹里放一个文件,贴标签说"能写/能读/会通知"
  • 电脑端 read_gatt_char(读文件)/ write_gatt_char(写文件)。

BLE 通信不是"发一条消息过去"那么自由,而是大家都按"文件夹+文件"的规矩来(这套规矩叫 GATT)。

五、一条完整的"蓝牙认识-读写"链路

BLE 设备怎么互相读写(最小闭环):
    广播:每个设备不停喊"我在这,我叫 XXX"
    扫描:想找设备的板子竖起耳朵听,记下名字和 RSSI
    连接:听到后去敲门,自动配对(just works,不用输密码)
    服务 = 文件夹,特征值 = 文件
        能读的文件:电脑 read_gatt_char 拿走值
        能写的文件:电脑 write_gatt_char 写进值
        会变的文件:一变就 notify 通知订阅过的人
    没有 WiFi、没有网线——靠的就是蓝牙这根"近处的线"

一句记牢:BLE 用"广播+扫描"让人互相发现,用"服务+特征值"让人互相读写;省电、近距、小数据,是给智能灯、手环、遥控准备的。

六、故障排查:电脑连不上板子怎么办

现象观察还是推测?下一步
脚本打印"没找到板子"观察推测广播没被听到 → 板子真在跑 demo02?屏幕"广播中"?
板子"广播中"但电脑找不到观察距离/遮挡 → 放 1 米内;Windows 蓝牙开了吗?
能连上但读写报错观察UUID 对不上 → 电脑脚本与板子代码的 UUID 一致吗?
"配对框都没弹就失败"观察Windows 蓝牙驱动问题 → 换 USB 蓝牙口

老规矩:"电脑找不到板子"是观察,"板子没广播"是推测。 用另一块跑 demo01 雷达的板子反扫它,雷达也看不到才是真没广播。

七、过关检查

不看 AI,自己说:

  1. BLE 靠哪两件事"认识"?广播/扫描分别像生活里的什么?
  2. RSSI 越大越接近 0 说明什么?能量出"正好 3 米"吗?
  3. 服务和特征值像文件夹里的什么?举例一个"能写"、一个"会通知"的特征值。
  4. demo02 写"1"灯亮——这条路上有 WiFi 或路由器吗?
  5. BLE 适合传大文件吗?为什么?
  6. 想让板子"电量掉到 20% 才通知一次",该改谁?

八、还能玩什么

方向想法继续想
蓝牙雷达屏加"信号最强"高亮,最近的设备跳出来怎么把远近做成游戏?
智能灯三件套可读亮度 + 可写开关 + 可通知温度电脑一次把三个都读回来?
BLE 遥控器电脑按键,板子翻 PPT / 换图除了开关还能让板子做什么?
谁是广播王多块板同时广播,雷达屏排信号榜挤在一起会互相干扰吗?

下一课预告:ESP-NOW——不要路由器、不要文件夹,两块板子直接点对点喊话。

本节配套资源 · 在线烧录

查看全部固件 →

下列演示程序已编译为可烧录固件。把你的 ESP32-S3 触摸屏板 用 USB 接上电脑(需 Chrome / Edge 浏览器),点「在线烧录」即可直接写入,无需安装任何软件。

第 20 课 · 蓝牙雷达
可烧录

每 5 秒扫一遍周围 BLE 设备,按信号强弱排序显示——教室电脑、别的板子都能扫到(耳朵)。

20 蓝牙BLE
第 20 课 · 蓝牙智能灯
可烧录

板子当 GATT 服务端:电脑用 bleak 脚本开关大灯、读温度、订阅电量通知——不用 WiFi 不用网线。

20 蓝牙BLE
第 20 课 · 广播名片
可烧录

板子不停广播自己的名字(嘴),旁边跑雷达 demo 的板子立刻扫到它;改 AD_NAME 重烧名字就变。

20 蓝牙BLE