ESP32 Arduino 使用 ESP RainMaker 构建自定义设备:RMakerCustom 完整实战解析

发布时间:2026/9/14 12:34:32
ESP32 Arduino 使用 ESP RainMaker 构建自定义设备:RMakerCustom 完整实战解析 ESP32 Arduino 使用 ESP RainMaker 构建自定义设备RMakerCustom 完整实战解析【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32导读ESP RainMaker 是乐鑫Espressif提供的端到端 AIoT 平台它把设备端ESP32 固件、云服务与手机 App 三者打通开发者无需自建云服务器即可快速完成设备上云。本篇文章以 arduino-esp32 仓库中的RMakerCustom示例为核心完整讲解如何利用 Arduino core 的 RainMaker 封装库绕开框架自带的 Switch、LightBulb、Fan 等标准设备类型直接基于Device基类创建自定义设备一个 AC 调光器 AC dimmer并实现手机端开关与亮度控制、本地按键联动、Wi-Fi 配网、OTA、定时/场景等企业级特性。读完本文你将掌握自定义设备与自定义参数的完整建模流程、参数回调的底层机制以及一键配网与设备重置的实战写法。一、示例概览一个可上云的自定义 AC 调光器RMakerCustom位于 libraries/RainMaker/examples/RMakerCustom/包含三个文件文件作用RMakerCustom.ino完整示例固件实现自定义 Dimmer 设备README.md官方示例说明文档本文骨架来源ci.yml仓库 CI 构建配置声明分区方案与 Kconfig 依赖示例的核心行为来自 README.md使用板载Boot 按键和GPIO16C3/C6 芯片为 GPIO7演示一个 ESP RainMaker AC 调光器设备编译烧录后用ESP RainMaker 手机 AppiOS/Android扫描串口打印的 QR 码完成配网并添加设备在 App 中切换开关状态会同步控制 GPIO16 上的调光器Power 参数按下板载 Boot 按键会本地翻转调光器状态并反向同步到手机 App在 App 中拖动亮度滑块Level 参数设备端会收到对应的数值并以串口消息打印。输出效果示例运行时的典型串口输出如下README.md 原文[ 87][I][RMaker.cpp:13] event_handler(): RainMaker Initialized. [ 94][I][WiFiProv.cpp:158] beginProvision(): Already Provisioned [ 95][I][WiFiProv.cpp:162] beginProvision(): Attempting connect to AP: Viking007_2GEXT Received value false for Dimmer - Power Toggle State to true. [ 22532][I][RMakerDevice.cpp:162] updateAndReportParam(): Device : Dimmer, Param Name : Power, Val : true Received value 73 for Dimmer - Level日志清晰展示了三条链路RainMaker 初始化成功 → WiFi 已配网并自动连接 → App 下发Powerfalse与Level73时设备端回调被触发并打印本地按键翻转状态后updateAndReportParam()把Powertrue上报云端随后 App 界面同步刷新。二、环境与编译前提分区方案和 Kconfig 依赖RainMaker 需要较大的存储空间用于云端证书与固件示例的 CI 配置 ci.yml 给出了明确约束targets: esp32: false fqbn_append: PartitionSchemerainmaker_4MB requires: - CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK[1-9][0-9]* requires_any: - CONFIG_SOC_WIFI_SUPPORTEDy - CONFIG_ESP_HOSTED_ENABLEDyPartitionSchemerainmaker_4MB编译时须选择rainmaker_4MB分区表在 Arduino IDE 的 Tools → Partition Scheme 中选择或命令行 fqbn 追加该参数该分区表为 OTA、NVS 与 RainMaker 数据预留了充足空间CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACKRainMaker 核心代码RMaker.h、RMakerDevice.h等都以#ifdef CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK作为编译开关未使能 RainMaker 组件时整个封装库为空实现requires_any说明该示例需要芯片支持 Wi-FiSOC_WIFI_SUPPORTED或启用 ESP Hosted 方案ESP_HOSTED_ENABLED因此仅在带 Wi-Fi 的 ESP32 系列上可构建。在 Arduino IDE 中只需正常安装 arduino-esp32 core选择对应开发板并切换到rainmaker_4MB分区即可编译本示例。三、代码全解从配网参数到自定义设备建模完整源码见 RMakerCustom.ino下面按逻辑模块逐段剖析。3.1 头文件与关键宏定义#include Arduino.h #include RMaker.h #include WiFi.h #include WiFiProv.h #define DEFAULT_POWER_MODE true #define DEFAULT_DIMMER_LEVEL 50 const char *service_name PROV_1234; const char *pop abcd1234;RMaker.h是 RainMaker 封装库入口导出RMakerClass全局实例RMaker以及Device、Param、Node等类型见 RMaker.hWiFiProv.h提供WiFiProv.beginProvision()与printQR()负责 BLE/SoftAP 配网service_name/pop分别是配网广播的服务名与 Proof of Possession持有证明App 扫码时需与之一致。3.2 跨芯片 GPIO 映射#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 static int gpio_0 9; static int gpio_dimmer 7; #else static int gpio_0 0; static int gpio_dimmer 16; #endifC3/C6 等新芯片的 Boot 引脚与 ESP32 不同C3/C6 的 BOOT 是 GPIO9因此示例用CONFIG_IDF_TARGET_*宏做条件编译非 C3/C6 平台使用 GPIO0Boot 键与 GPIO16调光输出。3.3 配网事件回调独立 FreeRTOS 任务中执行void sysProvEvent(arduino_event_t *sys_event) { switch (sys_event-event_id) { case ARDUINO_EVENT_PROV_START: #if CONFIG_IDF_TARGET_ESP32S2 Serial.printf(\nProvisioning Started with name \%s\ and PoP \%s\ on SoftAP\n, service_name, pop); WiFiProv.printQR(service_name, pop, softap); #else Serial.printf(\nProvisioning Started with name \%s\ and PoP \%s\ on BLE\n, service_name, pop); WiFiProv.printQR(service_name, pop, ble); #endif break; case ARDUINO_EVENT_PROV_INIT: WiFiProv.disableAutoStop(10000); break; case ARDUINO_EVENT_PROV_CRED_SUCCESS: WiFiProv.endProvision(); break; default: ; } }代码注释明确警告sysProvEvent由**独立的 FreeRTOS 任务线程**调用回调内不应执行阻塞操作ARDUINO_EVENT_PROV_START时打印配网名称/PoP 并调用printQR()在串口终端输出 QR 码ESP32S2 用 SoftAP 传输其余芯片用 BLE 传输disableAutoStop(10000)让配网服务在初始化后 10 秒内不自动停止等待用户操作凭据下发成功后endProvision()结束配网流程。3.4 自定义设备基于 Device 基类建模框架内置了Switch、LightBulb、Fan、TemperatureSensor等标准设备实现于 RMakerDevice.h但本示例用更底层的Device基类创建完全自定义的设备类型static Device *my_device NULL; ... my_device new Device(Dimmer, custom.device.dimmer, gpio_dimmer); if (!my_device) { return; } //Create custom dimmer device my_device-addNameParam(); my_device-addPowerParam(DEFAULT_POWER_MODE); my_device-assignPrimaryParam(my_device-getParamByName(ESP_RMAKER_DEF_POWER_NAME));Device构造函数签名Device(const char *dev_name, const char *dev_type, void *priv_data)对应底层esp_rmaker_device_create()RMakerDevice.h。设备名Dimmer会显示在 App 中设备类型custom.device.dimmer是自定义类型标识第三个参数gpio_dimmer作为私有数据透传给回调addNameParam()添加标准 Name 参数ESP_RMAKER_DEF_NAME_PARAMaddPowerParam(DEFAULT_POWER_MODE)添加标准 Power 开关参数默认值为true开assignPrimaryParam(...)把 Power 参数设为主参数App 首页会以主参数作为设备的快捷开关。3.5 自定义参数Level 亮度滑块Param level_param(Level, custom.param.level, value(DEFAULT_DIMMER_LEVEL), PROP_FLAG_READ | PROP_FLAG_WRITE); level_param.addBounds(value(0), value(100), value(1)); level_param.addUIType(ESP_RMAKER_UI_SLIDER); my_device-addParam(level_param);Param构造函数Param(param_name, param_type, val, properties)对应底层esp_rmaker_param_create()RMakerParam.h。value(DEFAULT_DIMMER_LEVEL)使用 RMakerType.h 提供的value(int)等重载构造param_val_t联合体默认亮度为 50PROP_FLAG_READ | PROP_FLAG_WRITE表示该参数既可从云端读取也可被写入。库 READMElibraries/RainMaker/README.md列出了完整属性标志PROP_FLAG_WRITE、PROP_FLAG_READ、PROP_FLAG_TIME_SERIES、PROP_FLAG_PERSISTaddBounds(value(0), value(100), value(1))设置整数参数取值范围 0100、步进 1对应 RMakerParam.h 的addBounds声明addUIType(ESP_RMAKER_UI_SLIDER)告知手机 App 用滑块渲染该参数。标准 UI 类型还包括ESP_RMAKER_UI_TOGGLE、ESP_RMAKER_UI_DROPDOWN、ESP_RMAKER_UI_TEXT见库 README 的 Param API 章节最后my_device-addParam(level_param)把自定义参数挂到设备上。3.6 写回调云端下发 → 本地执行 → 回传确认void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx) { const char *device_name device-getDeviceName(); const char *param_name param-getParamName(); if (strcmp(param_name, Power) 0) { Serial.printf(Received value %s for %s - %s\n, val.val.b ? true : false, device_name, param_name); dimmer_state val.val.b; (dimmer_state false) ? digitalWrite(gpio_dimmer, LOW) : digitalWrite(gpio_dimmer, HIGH); param-updateAndReport(val); } else if (strcmp(param_name, Level) 0) { Serial.printf(\nReceived value %d for %s - %s\n, val.val.i, device_name, param_name); param-updateAndReport(val); } }回调类型deviceWriteCb定义于 RMakerDevice.h通过my_device-addCb(write_callback)注册param_val_t是联合体需按参数类型取字段布尔取val.val.b整数取val.val.i浮点取val.val.f字符串取val.val.s库 README 的 Device API 章节有说明收到Power时按值驱动 GPIO16 高低电平真正点亮调光器收到Level时先打印亮度值关键回调内必须调用param-updateAndReport(val)底层esp_rmaker_param_update_and_report否则参数的新值不会同步到云端App 界面无法确认状态。这是 RMakerParam.h 声明的updateAndReport(param_val_t val)接口库 README 也强调该 API 应在设备写回调内调用。3.7 节点初始化与设备挂载Node my_node; my_node RMaker.initNode(ESP RainMaker Node); ... my_node.addDevice(*my_device);RMaker.initNode(name)创建 RainMaker 节点一个节点可包含多个设备返回Node对象见 RMaker.hmy_node.addDevice(*my_device)把自定义 Dimmer 挂到节点下App 中将以Node → Device → Params的层级呈现。3.8 可选服务OTA、时区、定时与场景//This is optional RMaker.enableOTA(OTA_USING_TOPICS); // RMaker.setTimeZone(Asia/Shanghai); RMaker.enableTZService(); RMaker.enableSchedule(); RMaker.enableScenes();enableOTA(OTA_USING_TOPICS)通过 MQTT 主题下发固件升级无需额外服务器setTimeZone(Asia/Shanghai)被注释可手动为调度Schedule设置时区enableTZService()开启时区服务由手机 App 自动下发时区二者选一即可enableSchedule()/enableScenes()启用定时与场景联动能力这些服务与设备参数共同构成完整的智能家居体验。3.9 启动流程RMaker.start() 与 WiFi 配网RMaker.start(); WiFi.onEvent(sysProvEvent); #if CONFIG_IDF_TARGET_ESP32S2 WiFiProv.beginProvision(NETWORK_PROV_SCHEME_SOFTAP, NETWORK_PROV_SCHEME_HANDLER_NONE, NETWORK_PROV_SECURITY_1, pop, service_name); #else WiFiProv.beginProvision(NETWORK_PROV_SCHEME_BLE, NETWORK_PROV_SCHEME_HANDLER_FREE_BTDM, NETWORK_PROV_SECURITY_1, pop, service_name); #endifRMaker.start()启动 RainMaker 主任务对应RMakerClass::start()WiFi.onEvent(sysProvEvent)注册配网事件回调beginProvision()依芯片选择传输方案ESP32S2 走 SoftAPNETWORK_PROV_SCHEME_SOFTAP其余芯片走 BLENETWORK_PROV_SCHEME_BLE 自由 BTDM handler安全方案统一为NETWORK_PROV_SECURITY_1首次上电 App 扫码配网后凭据存入 NVS此后启动时beginProvision()会打印Already Provisioned并直接连接保存的 AP对应本文开头日志的第 2、3 行。四、本地按键逻辑短按翻转、长按重置loop()中的按键处理是本示例最具实战价值的部分——它把本地控制与云端同步结合起来并实现了两种重置语义if (digitalRead(gpio_0) LOW) { //Push button pressed delay(100); // Key debounce handling int startTime millis(); while (digitalRead(gpio_0) LOW) { delay(50); } int endTime millis(); if ((endTime - startTime) 10000) { // If key pressed for more than 10secs, reset all Serial.printf(Reset to factory.\n); RMakerFactoryReset(2); } else if ((endTime - startTime) 3000) { // If key pressed for more than 3secs, but less than 10, reset Wi-Fi Serial.printf(Reset Wi-Fi.\n); RMakerWiFiReset(2); } else { // Toggle device state dimmer_state !dimmer_state; Serial.printf(Toggle State to %s.\n, dimmer_state ? true : false); if (my_device) { my_device-updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, dimmer_state); } (dimmer_state false) ? digitalWrite(gpio_dimmer, LOW) : digitalWrite(gpio_dimmer, HIGH); } } delay(100);消抖与长按计时按键触发后先delay(100)消抖再用millis()记录按下起始时间while循环等待释放后计算总按压时长按压 10 秒调用RMakerFactoryReset(2)恢复出厂设置清除 NVS 中的 Wi-Fi 凭据与设备数据2 秒后自动重启实现见 RMakerUtils.cpp按压 3 秒且 ≤ 10 秒调用RMakerWiFiReset(2)仅清除 Wi-Fi 配置2 秒后重启方便更换网络而不丢失设备数据短按≤ 3 秒翻转dimmer_state先调用my_device-updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, dimmer_state)把新状态上报云端设备端状态变更反向推送 App 的机制见 RMakerDevice.h 的updateAndReportParam重载再实际驱动 GPIO 输出。这正好回应了示例 README 的说明按下 Boot 键会切换调光器状态GPIO16且同一状态会实时反映到手机 App 上。五、设备重置指南README.md 官方给出的重置操作汇总如下操作效果按住 Boot 键超过 3 秒后松开重置 Wi-Fi 配置设备保留在 RainMaker 中的其他数据按住 Boot 键超过 10 秒后松开恢复出厂默认设置清空全部配置两种重置分别对应代码中的RMakerWiFiReset(2)与RMakerFactoryReset(2)参数2表示执行后延迟 2 秒再重启函数签名见 RMakerUtils.cpp。重置后设备会重新进入配网模式可在 App 中重新扫码添加。六、进阶参考与延伸同一目录下还有 RMakerSwitch标准 Switch 设备与 RMakerCustomAirCooler自定义空调扇含 Toggle、Range、Mode 多种自定义参数等示例可作为自定义设备建模的更多参考库级 API 全量说明Device、Param、Node、RMaker及重置函数的完整参数表见 libraries/RainMaker/README.md若要构建自己的自定义设备只需照抄本示例骨架new Device(name, type, priv_data)→ 添加标准/自定义参数含addBounds、addUIType→addCb(write_callback)→node.addDevice()→RMaker.start()→beginProvision()并在回调内用param-updateAndReport(val)确认状态回传。总结RMakerCustom是理解 ESP RainMaker 自定义设备模型的理想起点它以AC 调光器为业务载体展示了Device基类建模、自定义Param创建属性、边界、UI 类型、write_callback双向往返同步、BLE/SoftAP 一键配网QR 码、OTA 与定时/场景服务以及短按控制、长按重置的完整交互闭环。配合 RMakerCustom.ino 源码与 ci.yml 的分区约束你可以快速将其改造为任意自定义智能设备的可上云固件。【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考