通过点灯科技云平台实现LED控制

Tutorial: 卓越工程师 Category: 嵌入式 Published: 2026-10-23 11:05:29 Views: 1 Likes: 0 Comments: 0

292.10.通过点灯科技云平台实现LED控制

#define BLINKER_WIFI                    // 选择 Blinker 的 Wi-Fi 接入方式。
#define led 4                           // 把本课使用的 ESP32-CAM 闪光灯 GPIO4 命名为 led。
#include <Blinker.h>                   // 引入 Blinker 库的声明。
#include "ESP32_CAM_SERVER.h"         // 引入配套摄像头服务文件;这里不展开其内部实现。
BlinkerButton Button1("led");         // 建立按键组件对象;"led" 是与 App 组件键名对应的字符串。
void button1_callback(const String & state) // 定义收到该按键指令时执行的回调;state 保存传来的状态。
{                                    // 开始按键回调。
    BLINKER_LOG("get button state: ", state); // 把收到的按键状态写到 Blinker 串口调试日志。
    digitalWrite(led, !digitalRead(led)); // 读出 GPIO4 当前电平、取反,再写回 GPIO4。
}                                    // 结束按键回调。
char auth[] = "c56be051d11f";        // 视频中的设备 Secret Key;复现时换成自己的密钥。
char ssid[] = "302";                  // 视频中的 Wi-Fi 热点名称;复现时换成自己的热点名。
char pswd[] = "12345678";            // 视频中的 Wi-Fi 热点密码;不是 Blinker 账号密码。
bool setup_camera = false;           // 标记摄像头服务尚未由下方代码启动。
void dataRead(const String & data)   // 定义收到未由已绑定组件处理的数据时调用的回调。
{                                    // 开始处理收到的数据。
    BLINKER_LOG("Blinker readString: ", data); // 将收到的内容写到串口调试日志。
    Blinker.vibrate();               // 向 App 发送手机振动请求。
    uint32_t BlinkerTime = millis(); // 读取本次开机以来经过的毫秒数。
    Blinker.print("millis", BlinkerTime); // 以 millis 为键把该数值发送给 App。
}                                    // 结束 dataRead 回调。
void setup()                         // 定义上电或复位后执行一次的初始化函数。
{                                    // 开始初始化。
    Serial.begin(115200);            // 以 115200 波特率启动串口。
    BLINKER_DEBUG.stream(Serial);    // 把 Blinker 的调试输出指向串口。
    pinMode(led,OUTPUT);             // 将 GPIO4 设置成数字输出。
    digitalWrite(led, LOW);          // 启动时输出低电平,让闪光灯初始熄灭。
    Blinker.begin(auth,ssid,pswd);   // 用设备密钥、热点名和密码接入 Blinker。
    Blinker.attachData(dataRead);    // 注册通用数据回调。
    Button1.attach(button1_callback); // 把 Button1 的指令与按键回调关联。
}                                    // 结束初始化。
void loop()                          // 定义 Arduino 反复执行的主循环。
{                                    // 开始本轮循环。
    Blinker.run();                   // 维持 Blinker 通信并处理收到的指令。
    if (Blinker.connected() && !setup_camera) // 连接建立且尚未启动摄像头服务时进入。
    {                                // 开始首次启动摄像头的分支。
        setupCamera();               // 调用配套文件中的摄像头与本地视频流服务初始化。
        setup_camera = true;         // 记录已执行过初始化,避免每轮重复调用。
        Blinker.printObject("video", "{\"str\":\"mjpg\",\"url\":\"http://"+ WiFi.localIP().toString() + "\"}"); // 向 App 的 video 组件发送视频格式和本机局域网 URL。
    }                                // 结束首次启动摄像头的分支。
}                                    // 结束本轮循环,随后再次进入 loop。

一、通过点灯科技云平台实现LED控制

本节承接第 291 节的 ESP32-CAM 视频组件实验:保留原有联网、摄像头服务和视频 URL 逻辑,增加 App 按键组件与板载白色闪光灯的控制。上方抄录的是视频烧录时的 Blinker_ESP32_CAM.ino 主草图业务代码(去掉原注释并逐行加教学注释),没有把 ESP32_CAM_SERVER.h 中的库实现抄进来。视频公开展示的 Secret Key 与热点凭据只作课堂记录;自己复现时必须替换,勿公开真实密钥和密码。Blinker 官方 ESP32-CAM 示例

1.1 点灯科技云平台官网

  • 视频打开 diandeng.tech,进入“开发文档 → 快速开始 → ESP32 WiFi 接入”,参考完整示例中的 BlinkerButton 对象、按键回调和 attach() 注册写法。页面上方还有 Arduino 开发环境与库的安装说明;本节沿用上一节已经装好的环境,并非重新安装。Blinker 官方 ESP32/Wi-Fi 入门
  • 本节的控制路径可以分成:App 按键发出带键名的指令 → Blinker 设备收到 → Button1 匹配 led → 回调切换 GPIO4 电平 → 白色闪光灯亮或灭。视频画面仍由板子提供的局域网 HTTP/MJPG 服务读取,和按键指令不是同一份数据;“云平台控制 LED”不等于视频帧也上传到云端。Blinker 按键组件接口、摄像头示例服务

1.2 完整示例程序

  • 官方文档的完整示例采用 BlinkerButton Button1("btn-abc")、button1_callback、Button1.attach(button1_callback),并以 digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)) 演示翻转 LED。本节只把这些与按键有关的示例语句移入上一节的摄像头草图,再按实际板子把示例的 LED_BUILTIN 改为自定义的 led(GPIO4),没有把示例里的计数器、数字组件等无关代码一起复制。官方完整示例及按键说明
  • 代码块保留视频中的变量名、键名和调用形式。BlinkerButton Button1("led") 中 Button1 是程序里的 C++ 对象名,"led" 是 App 组件通信使用的键名;App 上显示的文字可以另设为“灯”。原笔记称“都叫 LED”会误导:视频最终代码和 App 标签均为小写 led,应按字面一致填写,而不是只看显示文字。

1.3 代码分析

1.3.1 组件对象新建
  • #define BLINKER_WIFI 沿用上节的 Wi-Fi 接入配置;#define led 4 是预处理替换,编译时把后文的 led 换成数字 4。它不是 Blinker 组件键名的定义:BlinkerButton Button1("led") 中的字符串是另一件事,恰好也写作小写 led。
  • 在 App 编辑界面给按键组件填键名 led,才能与 Button1("led") 匹配;Button1、led 宏、"led" 字符串分别是对象名、引脚代号、组件键名,不要混为一谈。大小写不一致或多了空格都可能匹配失败。BlinkerButton 官方接口
1.3.2 按键处理函数编写
  • void button1_callback(const String & state) 是收到该组件指令后调用的函数,不是 ESP32-CAM 上新增了一个实体按键,也不是 App 每次屏幕触摸都会无条件调用。视频最终将 App 组件设置为“开关按键”,官方说明这种模式发送 "on" / "off";普通按键模式则可能发送 "tap"、"press"、"pressup"。BlinkerButton 模式与状态值
  • BLINKER_LOG("get button state: ", state) 是设备侧串口调试输出,需串口保持连接且配置好 BLINKER_DEBUG.stream(Serial) 才便于查看;它不是把这段英文文本主动写入 App 的 Monitor。若要向 App 发送组件状态,官方提供 Button1.print(...),但视频最终代码没有这句,精校源码不擅自补入。Blinker 调试配置、按键 print()
  • digitalRead(led) 读 GPIO4 当前数字电平;前面的 ! 把 LOW/0 变成 HIGH/1,或把 HIGH/1 变成 LOW/0;digitalWrite(led, ...) 再写回,因此本例是每收到一次回调就翻转一次。它没有依据传入的 state 决定输出电平,所以不能理解成“收到 on 必定写 HIGH、收到 off 必定写 LOW”。设备重启、App 状态不同步或重复指令时,界面开关与实物灯可能不一致;这属于视频示例的局限,不能未经授权修改上方原代码。官方按钮状态定义
1.3.3 处理函数代码拷贝
  • 视频查引脚图后确认选的是 ESP32-CAM 白色闪光灯所接的 GPIO4,不是把“GPL 4”当成另一种接口。其 #define led 4、pinMode(led,OUTPUT)、回调里的 digitalWrite(led, !digitalRead(led)) 指向同一编号;若把示例中的 LED_BUILTIN 留在一处,则可能不是本板这盏灯。Zephyr ESP32-CAM 板级定义:GPIO4 为高电平有效的 Flash LED
  • 板上还可能见到红色状态灯,本课控制的是白色补光/闪光灯,不要把二者或板子的复位键混淆。读板级资料时先找板型 AI Thinker ESP32-CAM,再找 Flash LED → GPIO4,最后看有效电平:资料标为 GPIO_ACTIVE_HIGH,即 GPIO4 高电平对应闪光灯点亮、低电平对应熄灭;其他开发板不可照搬此引脚与极性。Zephyr 板级定义
  • 从硬件角度理解:GPIO 是 ESP32 的控制信号端,软件写 HIGH/LOW 改变管脚输出;板上的供电、白色闪光灯和驱动器构成电流回路,LED 有电流才会发光。ESP32-CAM V1.6 参考原理图中,GPIO4 对应 HS2_DATA1 信号,连接到 LED_FLASH 驱动支路,支路中有 Q1 S8050 三极管;高电平让驱动支路导通,低电平使其截止。因此不能把 digitalWrite 理解为向灯“发送网络消息”,也不要把一颗大功率闪光 LED 不经合适的驱动与限流设计直接接到芯片 GPIO 上。GPIO4 同时连向 microSD 的数据线,用 SD 卡相应模式时可能冲突,本视频并未启用 SD 卡。ESP32-CAM V1.6 原理图、Zephyr 板卡硬件说明
  • 视频中的所谓“86 行”是当时 IDE 的行号,受文件头注释和编辑影响会变化。真正关键的是把 Button1.attach(button1_callback) 放进 setup(),由库在识别到 led 指令时调用对应函数;只定义对象和函数而不注册,按键不会进入该回调。Blinker attach() 说明
1.3.4 LED口初始化
  • pinMode(led,OUTPUT) 将 GPIO4 设为输出;接着 digitalWrite(led, LOW) 指定本次启动后的初始低电平,于是白色闪光灯初始熄灭。初始 LOW → 第一次回调取反为 HIGH、灯亮;第二次回调 HIGH → LOW、灯灭。原笔记“初始低电平状态下第一次按下”只有完成这两句初始化之后才成立,未初始化时不能凭空假设引脚电平。
  • 对新手而言,HIGH/LOW 是管脚相对 GND 的数字高/低电平,不是“云平台上的高/低权限”,也不是给灯直接设置亮度;这段代码只有开/关,没有 PWM 调光。板载闪光灯工作时需有稳定供电,若灯亮时板子重启或 Wi-Fi 掉线,应先检查供电与接线,而不能单凭 App 离线判定程序逻辑错误。ESP32-CAM V1.6 原理图
1.3.5 代码上传
  • 视频连接下载线,在 Arduino IDE 选 AI Thinker ESP32-CAM 和对应串口后点击上传(原笔记“点击上的”是 OCR 错字)。上传时视频先显示旧的 pinMode(led,OUPUT) 编译报错;随后代码画面已经改成 OUTPUT 并继续编译、烧录,不能把旧错误当成最终程序仍然失败。视频末尾控制灯成功。Espressif ESP32 下载模式说明
  • ESP32-CAM 若用外置 USB 转串口器并需手动进入下载模式,通常让 GPIO0 在复位时接 GND;烧录完成后移开 GPIO0—GND 下载连接,再复位以运行程序。视频说“拔掉下载线”是其实际操作画面,复现时还必须保留或重新提供可靠的供电与共地;不要在断电且无供电情况下期待设备上线。Espressif 启动模式说明
1.3.6 组件编辑
  • 视频在 Blinker App 中打开已有设备,进入组件编辑,拖入一个按键组件,在参数里把“组件键名”改为小写 led。这一步才使 App 的组件发来的指令对应 Button1("led");原笔记只说“名字一样”却未分清键名与显示文本。
  • 视频左侧还保留上一节的 video 视频组件,板子的 loop() 也继续发送视频组件的 MJPG URL。两种组件可在同一设备页面并存:视频组件负责看画面,按键组件负责发控制指令,不需要重新改摄像头服务源码。
1.3.7 样式设置
  • “显示文本”可填“灯”,按钮大小、图标、颜色、背景透明度按喜好设置;这些只是 App 界面外观,不能替代通信键名 led。编辑完按界面确认并保存。视频中的操作发生于当时的 App 版本,新版本位置或名称可能不同。
  • 视频中对开发板按复位键,是为了进入后续烧录/启动流程;复位键不负责保存 App 组件配置。按复位会让 setup() 重新运行,GPIO4 再次被设为 LOW,所以灯会回到初始关闭状态。
1.3.8 程序烧录
  • 视频一边等待编译和上传,一边调 App 布局,最后将按钮类型切到开关按键,并在页面底部加入 Monitor 调试窗口。按钮类型要和课堂展示一致;但由于程序不读取 state 决定输出,仅通过取反切换,开关的画面状态不具备设备真实状态的强一致保证。Blinker 按键模式与状态反馈
  • 原笔记说“调试窗口关联 67—77 行代码”不准确:视频草图的那段是 dataRead() 通用数据回调,里面会请求振动、回传 millis;绑定到 Button1 的按键指令走 button1_callback()。视频 Monitor 画面可见类似 {"led":"on"} 的通信记录;它不是 BLINKER_LOG("get button state: ", state) 自动在手机上打印的文本。要看后者应检查设备串口日志。Blinker 通用数据与按键回调、调试说明
  • IDE 显示写入完成、校验通过后,让板子退出下载模式,复位启动,再开启视频所用手机热点;等待板子连接热点和 Blinker 平台。热点名称、密码必须对应草图里的 ssid、pswd,而实际复现应换成自己的值。
1.3.9 设备查看状态
  1. 视频先确认手机热点显示有设备连接,再在 Blinker App 的设备列表下拉刷新,等设备从离线变为在线。热点“有设备连接”只证明 Wi-Fi 关联,App 显示在线还要看 Blinker 通信是否成功;下拉两次仍离线不是硬件故障的严格判定,应检查供电、热点名称/密码、设备密钥、网络连通性和串口日志。
  2. 进入设备页后,上方视频组件恢复画面,点击“灯”开关时白色闪光灯亮,再点一次熄灭;Monitor 记录里可看到 led 的 on/off 指令。原笔记中的“ESB 32K”“GPL口”“高电瓶”分别应为 ESP32-CAM、GPIO 引脚、高电平。
  3. 验证时区分四层:App 组件键名正确 → 指令到达设备 → 回调执行并写 GPIO4 → 白灯实际亮灭。如果设备在线但灯不响应,先查 led 键名与按键模式,再看串口是否打印 get button state:,最后查 GPIO4、LED 和供电;不要只看界面开关的图标就认定硬件真的改变了状态。视频示例每次回调取反,也没有从设备主动用 Button1.print() 回报真实灯态。Blinker 按键组件接口

核对依据

  • 本地 videos/292.10.通过点灯科技云平台实现LED控制.mp4 的最终 Arduino 草图、App 组件编辑、烧录结果和 LED 控制演示;对照 transcripts/292.10.通过点灯科技云平台实现LED控制.txt 与原始 notes/md/292.10.通过点灯科技云平台实现LED控制.md。
  • 上节精校稿 notes/md_proofread_version/291.9.连接点灯科技云平台.md 与课程配套 Blinker 摄像头示例,用于核对本节未改动的联网、摄像头及视频 URL 部分;官方 Blinker ESP32 Wi-Fi 教程、Arduino 组件接口。
  • ESP32-CAM V1.6 原理图及 Zephyr AI-Thinker ESP32-CAM 板级资料,用于核对 GPIO4、闪光灯有效电平与 microSD 复用关系。