我一直觉得真正做过灯控项目的人都会明白一个朴素的道理灯控这件事难点从来不在“让一盏灯亮起来”而在“让一堆灯听话地一起亮”。客厅五六路筒灯、五六个射灯再加一组灯带如果用经典蓝牙一对一连手机那体验简直灾难——每盏灯都要单独配对、单独连接手机一走远就断线。所以当我决定用手头的 ESP32 搭一套智能灯控网络时几乎没有犹豫就选了 BLE Mesh。原因很直接蓝牙 Mesh 天生支持自组网、支持消息中继、支持一对多控制手机只需连着网络里的任意一台设备就能控制所有节点。而且 ESP32 这种双核、支持 BLE 和 WiFi 的芯片价格便宜、库又全拿来当 Mesh 节点非常合适。这篇文章我就把整个项目从零到一完整记录一遍硬件怎么选、代码怎么改、nRF Mesh 怎么配网以及在配置过程中我踩过的一堆坑。这套内容适合谁如果你打算用 ESP32 做智能灯控、传感器网络或者单纯想搞懂 BLE Mesh 的配网和模型机制那这篇可以直接照着抄。我会把核心代码逻辑、配置步骤、避坑经验全写出来尽量做到你拿着这篇文章就能把网络搭起来。1. 项目整体设计与方案选型1.1 为什么灯控场景首选 BLE Mesh先说说我为什么没选 WiFi 和 Zigbee。WiFi 的方案我最早试过ESP32 开一个 TCP 服务器手机通过局域网去控制。单灯测试一切正常一旦真正在房间里装五六盏灯问题就来了每盏灯都要连同一个路由器路由器负载一高灯就会出现秒级延迟甚至掉线。更麻烦的是WiFi 的控制依赖路由器断网关灯就全变“孤儿”。Zigbee 确实是为物联网设计的协议成熟、功耗低但 Zigbee 网关和模块的成本摆在那里而且手机没法直接和 Zigbee 节点通信必须经网关中转。BLE Mesh 的优势正好补齐这些短板。它采用的管理型洪泛managed flooding机制消息发出后由邻居节点逐跳转发网络里的中继节点Relay会接力传递消息。这意味着不依赖中心网关任何一个节点挂了消息可以走别的路径。手机只要靠近任意一个节点就能通过该节点控制整个网络。灯控这种低速率控制场景BLE Mesh 的数据吞吐能力绰绰有余。当然BLE Mesh 不是万能的。它的消息洪泛特性决定了它不适合传大量数据控制指令这种几十字节的小消息才是它的舒适区。而灯刚好就是这样开关、亮度、色温指令极小但对响应速度和同步一致性要求高。Bingo完美契合。1.2 硬件选型与组网拓扑硬件方面我用的是最经典的 ESP32-WROOM-32 模组具体买的是 NodeMCU-32S 开发板。这块板子自带 USB 转串口、稳压和一键下载电路非常适合开发调试。如果你用纯模组打板就得自己处理外围电路开发阶段完全没必要。负载部分我用了两种一个 GPIO 直驱的普通 LED 用来做功能验证另外用了一串 WS2812B 灯带做实际灯效。WS2812B 是单总线数字灯珠每颗灯珠都有独立 IC用 ESP32 的 RMT 外设就能驱动控制颜色和亮度非常方便。这里要专门提醒一句WS2812B 全亮时电流非常夸张一条 60 灯珠的灯带全白最亮能到 3.6A 左右千万别用 USB 口供电必须外接 5V 电源而且电源要选足电流的型号我用的是一块 5V 10A 的开关电源。ESP32 本身建议用独立的 AMS1117-3.3 稳压供电避免和灯带共地干扰导致重启。网络拓扑上我规划的是一个经典的 provisioning 结构手机nRF Mesh作为 Provisioner | | BLE 广播/连接 (配网流程) | 主节点 ESP32-A被配网设备 | | Mesh 消息洪泛/中继 | 副节点 ESP32-B、ESP32-C ...手机在这里只负责“配网”和“下发控制指令”两个动作网络内节点之间的通信完全走 Mesh 协议栈不依赖手机持续连接。这样手机离开网络区域后灯还是可以按场景逻辑工作比如定时开关、传感器触发。1.3 开发环境与工具链准备开发环境我用的是 Ubuntu 20.04 ESP-IDF v4.4。ESP-IDF 提供了官方 BLE Mesh 示例路径在examples/bluetooth/mesh/下里面有onoff_server和onoff_client两个最基础也最重要的例程。个人建议哪怕是老手第一次做 BLE Mesh 也先从官方的 onoff_server 例程开始改不要自己从头写协议栈调用逻辑坑太多得不偿失。环境搭建按官方文档执行就行核心是三步git clone --recursive https://github.com/espressif/esp-idf.git cd esp-idf ./install.sh esp32 source ./export.sh需要提醒的是ESP-IDF 的版本对 BLE Mesh 功能影响很大。我用的 v4.4 整体比较稳定v5.x 也支持但 API 有调整如果你照着网上的旧教程写代码发现编译不过第一件事就去查版本差异。编译环境搞定之后先把onoff_server编译烧录一遍确认硬件和链路没问题再动代码。2. 核心代码与协议栈拆解2.1 Mesh 模型机制先把概念理清楚BLE Mesh 里最核心的概念是 Model模型。我给大家打个比方Model 就像小区物业里的“岗位分工”。Generic On/Off Server 是“执行岗”——就是一个开关能接收开/关指令也能上报状态Generic On/Off Client 是“发号施令岗”——负责发送开/关指令。一个节点可以挂多个 Model比如一个灯既可以响应开/关也可以响应亮度调节。节点Node上有 Element元素一个 Element 里可以放多个 Model。实际代码里你配置的.models[]数组就是在给节点“招聘岗位”。配网时手机Provisioner拿到节点的 Composition Data就能知道这个节点有哪些 Element、哪些 Model这样才知道能对它下发什么类型的消息。还有个重要概念是地址单播地址Unicast每个节点唯一的地址配网时由 Provisioner 分配。组地址Group Address一组节点的公共地址往组地址发消息订阅了该组的所有节点都能收到。灯控组网主要就用这个。虚拟地址类似组地址但更灵活可以根据业务标签生成这里不做展开。理解了这几个概念整个项目的逻辑就串起来了手机把每个 ESP32 配成网络里的节点给每个节点分配单播地址然后配置它们“订阅”某个组地址手机或任意一个控制端往这个组地址发On/Off消息所有灯同时收到命令、同时动作。2.2 节点初始化与配网回调下面直接上核心代码。我基于官方onoff_server改动的重点有几块配网状态处理、按键扫描、灯效驱动。先看初始化部分static void mesh_init(void) { esp_ble_mesh_cfg_t cfg { .mesh_bearer ESP_BLE_MESH_BEARER_ADV, }; esp_ble_mesh_provisioning_cb_t prov_cb { .prov_cb prov_cb_handler, }; esp_ble_mesh_model_cb_t model_cb { .model_cb model_cb_handler, }; esp_ble_mesh_init(cfg, prov_cb, model_cb); }ESP_BLE_MESH_BEARER_ADV指定使用广播承载Advertising Bearer。BLE Mesh 有两种承载广播承载ADV和 GATT 承载GATT。广播承载用于节点之间的 Mesh 消息传递GATT 承载是为了兼容那些不支持 Mesh 协议栈的手机或平板它们通过 Proxy 节点接入网络。nRF Mesh 配网时走的是广播承载控制时如果手机已经处于 Mesh 网络里走的也是广播承载。然后是配网回调函数这个函数会在配网的不同阶段被协议栈调用。我把关键事件处理列一下static void prov_cb_handler(esp_ble_mesh_prov_cb_event_t event, esp_ble_mesh_prov_cb_param_t *param) { switch (event) { case ESP_BLE_MESH_PROV_REGISTER_EVT: ESP_LOGI(TAG, Mesh 协议栈注册完成); break; case ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT: ESP_LOGI(TAG, 配网连接已建立); break; case ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT: ESP_LOGI(TAG, 配网成功, 分配的地址: 0x%04x, param-node_prov_complete.net_idx); break; case ESP_BLE_MESH_NODE_PROV_RESET_EVT: ESP_LOGI(TAG, 节点被重置重新进入未配网状态); // 这里需要把设备恢复出厂重新广播 Unprovisioned Beacon break; default: break; } }这里最关键的几个事件是PROV_REGISTER、PROV_LINK_OPEN、PROV_COMPLETE、PROV_RESET。PROV_RESET是配网失败或者被手机重置节点时触发必须在这个事件里恢复设备到初始状态否则后续再配网会出现状态错乱。我实际测试时发现有些设备被重置后不重新广播未配网信标就是因为没处理这个事件卡在了半配网状态。2.3 按键扫描与灯控逻辑配网完成之后节点就进入正常工作状态。我设计了一个 GPIO 按键短按切换 GPIO 直驱 LED 的亮灭同时往组地址发布开关状态长按则清空配网信息让设备重新进入待配网状态。static void button_scan_task(void *arg) { uint8_t last_level 0; for (;;) { if (gpio_get_level(BUTTON_GPIO) 0) { // 按下为低电平 vTaskDelay(pdMS_TO_TICKS(50)); if (gpio_get_level(BUTTON_GPIO) 0) { last_level !last_level; gpio_set_level(LED_GPIO, last_level); esp_ble_mesh_generic_client_set_state( led_onoff_client, LED_GROUP_ADDR, ESP_BLE_MESH_GEN_ONOFF_MSG_SET, onoff_set, false); } } vTaskDelay(pdMS_TO_TICKS(100)); } }这段代码简洁但有一个细节要注意esp_ble_mesh_generic_client_set_state里的最后一个参数false表示不需要服务端回复确认消息直接发出去不管结果。对灯控这种场景我一般建议设成false因为灯的状态本来就是会周期性上报的没必要一条指令等一个 ACK反而拖慢响应。那接收端怎么处理收到的开关消息关键在于model_cb_handler里的ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET事件static void model_cb_handler(esp_ble_mesh_model_cb_event_t event, esp_ble_mesh_model_cb_param_t *param) { switch (event) { case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_EVT: { uint8_t onoff param-model_operation.msg[0]; gpio_set_level(LED_GPIO, onoff); ESP_LOGI(TAG, 收到开关指令: %d, onoff); break; } case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET_EVT: // 上报当前状态这里需要填充状态值然后调用 state_response break; default: break; } }我这个版本做了精简实际上要做 Server 主动上报状态开发者需要注册esp_ble_mesh_server_recv_gen_onoff_set对应的回调并调用esp_ble_mesh_server_model_update_state把新状态同步到节点状态表。具体实现参考官方例程即可逻辑不复杂关键是记住收到指令后要同时更新物理 GPIO 和协议栈内的状态表否则 Provisioner 查询状态时会返回旧值出现“灯实际亮了但手机显示灭”的诡异问题。2.4 编译配置与烧录细节编译前需要在 menuconfig 里配置 BLE Mesh 相关参数。重点看这几个选项idf.py menuconfigComponent config - Bluetooth - Bluedroid Options - Enable BLE Mesh必须打开。Component config - Bluetooth - Bluedroid Options - BLE Mesh - Maximum number of elements默认 1如果节点有多个 Element 可以加大。Component config - Bluetooth - Bluedroid Options - BLE Mesh - Relay是否启用中继功能。如果这个节点要帮其他远处节点转发消息必须打开。烧录用idf.py -p /dev/ttyUSB0 flash monitor一次搞定。如果遇到下载失败大概率是串口占用或者没进下载模式NodeMCU-32S 一般会自动进入下载模式纯 ESP32 模组则需要手动按住 BOOT 再按 EN。这里有个非常有价值的建议调试 Mesh 网络一定要开着日志看ESP-IDF 的 Mesh 日志非常详细把日志等级调到 Debug能直接看到配网每个阶段的执行情况排查问题效率翻倍。在 menuconfig 里Component config - Log Output - Default log verbosity选择 Debug 即可。3. nRF Mesh 配网实操全程3.1 配网前的准备工作固件烧录完成、串口日志正常打印之后就轮到手机端的 nRF Mesh 出场了。nRF Mesh 是 Nordic 出品的一款免费 App可以当作 Provisioner 来配网不要把它当成普通蓝牙控制软件用它是整个网络的“配置中心”。配网前建议做三件事手机系统蓝牙打开屏幕常亮nRF Mesh 保持在前台。ESP32 开发板重新上电确保它处于未配网状态。日志里能看到周期性的BLE Mesh: Unprovisioned device beacon输出。手机尽量靠近 ESP32尤其是第一次配网距离保持在 1 米以内减少广播丢失概率。3.2 识别、配网与配置 AppKey打开 nRF Mesh如果手机之前有旧网络先点击左上角切换到一个新网络或者直接新建一个网络。主界面点击Scan扫描稍等几秒就能看到未配网设备列表显示的内容包括设备的名称比如 “ESP-BLE-MESH”和一个 “Unprovisioned” 标签。这一步如果什么都扫不到别急着怀疑硬件先把手机挪近一点确认串口日志里有 Beacon 广播再检查 ESP32 是否被旧网络残留数据污染了。长按板子按键或者执行idf.py erase-flash可以清掉旧配网信息。识别到设备后点击右上角的Identify识别ESP32 板载的 LED 会闪烁几下这是 Mesh 标准里的识别信号确认你正在操作的就是目标设备。然后点击Provision配网App 会弹出认证方式选择No OOB不需要额外认证最简单适合开发调试。Static OOB需要输入一串固定密钥。Output OOB设备显示一段数字由人输入到手机。Input OOB手机显示数字由人输入到设备比如点按按键。开发阶段我强烈建议选No OOB先跑通流程。生产环境再考虑 Static OOB。配网过程通常几秒内完成nRF Mesh 会显示一个进度条包括 Invite、Exchange Public Keys、Authentication、Distribution of Provisioning Data 等阶段。如果进度条长时间卡住然后报错基本就是认证超时或者广播丢包。配网成功之后设备在 App 里变成普通节点并显示一个 0x000X 格式的单播地址。这时候别急着控制关键的一步还没做给节点添加应用密钥AppKey。没有 AppKey节点就像锁在保险箱里的开关谁都没法操作。在节点详情页点击 “Add Application Key”跟随提示操作。如果你想让一个密钥管理所有灯也可以把一个 AppKey 绑定到多个节点。3.3 配置发布与订阅让手机控制灯AppKey 绑定完成后往下走就是最核心的发布/订阅配置。BLE Mesh 的消息收发逻辑可以理解为Client 往某个地址“发布”消息Server 提前“订阅”了某个地址就能收到发往该地址的消息。我的配置方法是这样的在 nRF Mesh 中选中已配网的 ESP32 节点进入节点详情。选择 Generic On/Off Server 模型点击Publish或Subscription进行配置。新建或选择已有的 Group Address组地址比如 0xC001指定这个组作为 Server 的订阅地址。回到网络主界面用 App 自带的 Generic On/Off Client 模型往组地址发送控制指令。也就是说节点订阅了组地址手机往组地址发布消息所有订阅该组的灯都会收到。如果你有多块 ESP32每块都订阅同一个组地址就能实现“一盏手机控制所有灯同步亮灭”。这里还要提一下0xFFFF这个地址它表示所有节点All Nodes。开发时图省事可以往 0xFFFF 发消息所有配网节点都会收到。但在实际项目中千万别这么干因为广播洪泛会让网络里每个节点都处理并转发这条消息网络负载大增。正确做法是给不同房间、不同用途的灯分配不同的组地址。3.4 多节点组网与中继扩展一块灯板只能算“单灯遥控”真正体现 Mesh 优势的是多节点组网。我在原网络上又加了两块 ESP32分别重复上面的配网流程。配网完成后我在网络的节点详情里分别给节点 1、节点 2、节点 3 配置了同一个组地址 0xC001 作为订阅地址。然后我用手机 App 里的 Client 模型往 0xC001 发一条 ON 指令神奇的一幕发生了三块 ESP32 上的 LED 几乎同一时间点亮肉眼根本分辨不出先后顺序。这说明 Mesh 网内转发效率相当高队列延迟在毫秒级。要注意的是多节点组网时中继Relay功能至关重要。三个节点距离较近时消息一跳就全到了Relay 作用不明显。但如果节点分布在房间不同角落两个节点距离超过蓝牙直连范围就需要中间的节点开启 Relay 帮忙转发。开启方式是在 menuconfig 里把BLE Mesh Relay打开重新编译烧录。另外nRF Mesh 里也可以查看节点的特性Features确认 Relay 状态是 Enabled。我实测过一组数据三个 ESP32 节点呈三角形分布任意两个间距约 20 米中间隔了两堵普通砖墙。没有 Relay 时手机只能在其中一个节点附近控制把中间节点开启 Relay 后手机在任意位置都能通过中继节点控制另外两盏灯响应延迟在 100ms 到 200ms 之间体感上没有明显卡顿。4. 避坑指南nRF Mesh 配置踩坑实录这一节是整个项目调试期间最珍贵的部分。我在配网和调试过程中至少踩过 10 个坑这里挑最典型的 8 个写出来。先给一张速查表方便大家直接对照排查。编号问题现象主要原因解决办法1nRF Mesh 扫描不到 ESP32Beacon 未广播或广播被过滤确认日志有 Unprovisioned Beacon手机靠近设备清除残留配网数据2配网进度卡在 90% 后失败认证超时或广播丢包选择 No OOB缩短距离期间不要切后台3配网成功但无法控制灯AppKey 未绑定或订阅地址未配置确认节点已绑定 AppKey模型已订阅组地址4手机断开后灯也失控对手机连接产生了依赖分清配网和控制的区别控制应通过 Mesh 节点直接下发5多节点消息“扯皮”有的亮有的不亮节点订阅地址不一致或 Relay 未开逐节点检查订阅地址远处节点开启 Relay6ESP32 异常重启日志指向看门狗电源不稳或任务栈溢出用独立稳压电源增加按键任务栈大小7开启 WiFi 后配网失败或断连ESP32 蓝牙和 WiFi 不能同时工作要么禁用 WiFi 功能要么切换为共存模式先跑通蓝牙 Mesh8节点重置后无法重新配网PROV_RESET 事件未处理在回调里清空 FLASH 并重启设备4.1 问题一扫描不到 ESP32这是新手遇到最多的问题。头一天晚上我烧好固件满怀期待地打开 nRF Mesh扫了半天啥都没有。排查下来发现是 ESP32 一直处于“半配网”状态——之前调试时配网配到一半失败节点已经记录了一部分网络信息但又没法正常使用导致 Unprovisioned Beacon 不再广播。解决办法是彻底清空配网信息我的做法是直接执行idf.py erase-flash然后再烧录一次固件开机日志里就能重新看到周期性的 Beacon 广播。另外有些开发板的天线设计一般手机和板子保持在 1 米以内成功率会高很多。4.2 问题二配网进度条卡住然后失败这个坑我在调试时反复出现。现象是 nRF Mesh 扫描到了设备点击 Provision 后进度条走到 Exchange Public Keys 或者 Authentication 阶段就停住最后超时失败。排查方向有几个一是广播丢包严重解决方案是配网过程中手机保持静止不要切后台、不要接电话二是 OOB 认证方式不合适开发调试直接选 No OOB把可能的变量降到最低三是 ESP32 供电不稳定导致射频性能下降。我后来给 ESP32 换了单独的 3.3V 稳压供电配网成功率明显提升几乎一次就能成。4.3 问题三配网成功但灯控制没反应这个坑很容易被忽略。AppKey 没有绑定到节点时节点根本不会理会任何应用消息。解决办法是在节点详情页里手动添加 AppKey。另外还要检查订阅地址。如果 Server 模型没有订阅任何组地址手机往组地址发的消息它根本收不到。我把节点订阅配置从 Publish/Subscription 页面设置好后顺手确认了 Client 模型的发布地址和 Server 的订阅地址一致问题才彻底解决。4.4 问题四ESP32 的 WiFi 和蓝牙打架这个可能很多没接触过的人不清楚。ESP32 是双模的既能连 WiFi 又能跑 BLE但两者不能同时正常工作除非使用 Wi-Fi 与蓝牙共存coexistence模式。在蓝牙启用期间WiFi 的扫描和连接会出现明显退化甚至失败反过来WiFi 的持续收发也会抢占 BLE 广播/扫描的时间片导致配网成功率骤降。我调试 Mesh 时是直接把 WiFi 功能“扣掉”的只在项目里保留蓝牙部分。如果你打算做“WiFi 配网 蓝牙 Mesh 控制”的双模设备请务必查阅官方coexistence文档和例程同时做好行为测试并且让手机配网时保证 WiFi 路由器不在同一频段附近造成干扰。4.5 问题五节点重置后无法重新配网这是个比较隐蔽的问题。当我主动测“撤下节点重配”的时候发现节点日志停在PROV_RESET事件但设备既不广播 Beacon也没有进入待配网状态。原因是默认的 PROV_RESET 只是把协议栈状态清除并没有把设备彻底重置到刚出厂的未配网状态。我的处理方式是在PROV_RESET回调里增加 nvs_flash 清除和重启逻辑case ESP_BLE_MESH_NODE_PROV_RESET_EVT: ESP_LOGI(TAG, 节点重置清除 Flash 并重启); nvs_flash_erase(); esp_restart(); break;这样长按按键触发 reset 后设备会自动清空所有网络数据并重启重新进入未配网状态后续再配网就顺利了。5. 实测效果、细节优化与经验总结5.1 实测数据响应延迟与多灯同步项目基本跑通之后我花了一天时间专门做测量主要看两个指标单灯响应延迟和多灯同步误差。测试环境是普通住宅三块 ESP32 分别位于客厅三个角落手机在客厅中间。通过 nRF Mesh 的 Generic On/Off Client 发出控制指令重复 50 次取平均值结果如下表所示测试项最差延迟最好延迟平均延迟备注单灯 ON1 跳180ms40ms95ms手机直接连到节点双灯 ON经 1 个 Relay320ms120ms210ms经中间节点转发三灯同步亮起时间差60ms10ms25ms肉眼不可分辨这个成绩对灯控来说是合格的。普通人眼能感知到明显“先后亮”的延迟阈值大概在 100ms 以上25ms 的同步差完全无感。如果你对同步有更极致的要求可以考虑在节点本地维护一个定时器收到指令后延迟几十毫秒再统一执行让所有灯在网络消息到达后几乎同时动作。5.2 细节优化电源、天线与发射功率这几个优化点都是实测后有明显效果的强烈建议照着改。电源方面ESP32 射频瞬间电流峰值可以达到 500mA 左右如果电源纹波大蓝牙广播的成功率会肉眼可见地下降。我当时换了一路独立 LDO 给 ESP32 供电同时把输入端加了一个 470uF 电解电容和一个 0.1uF 陶瓷电容滤波配网和消息转发的稳定性都提升了一截。天线方面ESP32-WROOM-32 的 PCB 天线对周围金属件很敏感。开发板悬空竖放的时候信号最好贴在金属桌面或者放在金属盒子里时广播范围能缩水一半以上。嵌入式安装时尽量让天线区域露出外壳。发射功率方面BLE Mesh 默认发射功率是 0dBm可以调到 8dBm 甚至 9dBm。ESP-IDF 官方没有直接暴露 Mesh 的发射功率配置但可以通过蓝牙控制器 API 实现。我调高功率后隔一堵墙的控制响应明显加快代价是功耗高了一些。如果是电池供电的场景建议保持 0dBm 甚至更低。5.3 给后面项目留的扩展思路这套网络跑通之后扩展空间非常大。最自然的升级是加传感器在某个 ESP32 节点上接一个 PIR 人体感应传感器触发时往组地址发一条 ON 指令整个客厅的灯都会自动亮起。这就是 Mesh 的“本地联动”能力不依赖任何云端。我目前也在尝试把 BLE Mesh 网络接入 Home Assistant思路是做一个 ESP32 网关节点该节点同时具备 BLE Mesh 的 Proxy 功能和 WiFi/TCP 上网能力把 Mesh 消息翻译成 MQTT 主题从而实现整个智能家居系统和中控平台的双向联动。这个方向需要解决 WiFi 和 BLE 共存的问题但完全可行。5.4 一点真心话最后想分享一点个人体会。BLE Mesh 的上手门槛确实比普通 BLE 外设高一大截它的协议栈分层多、概念多配网流程也比想象中繁琐。但一旦把配网和模型机制吃透后面做多设备联动几乎是一马平川。整个项目从头到尾我最有成就感的不是“灯亮了”而是看着三块板子通过网络彼此协作的那一瞬间——那种“设备之间开始对话”的感觉只有玩过 Mesh 的人才能体会。如果你也准备踩进这个坑我建议给自己留足耐心严格按照“先 Single Node、再 Multi Node、最后加 Relay”的顺序推进一步一个脚印基本就能避开大多数人踩过的雷。祝大家都能点亮自己的一套 Mesh 灯控网络。
