Jackeroo 345aa57163 Update README.md
完善文档,适合小白折腾
2026-05-08 20:53:30 +08:00
NEW
2026-05-08 20:10:40 +08:00
2026-05-08 20:10:12 +08:00
NEW
2026-05-08 20:10:40 +08:00
2026-05-08 20:53:30 +08:00

OpenWrt Monitor

这是一个基于 ESP32 + LCD 屏幕的 OpenWrt 状态监控小屏项目。ESP32 会通过 Wi-Fi 定时访问 OpenWrt 路由器上的 CGI 接口,获取 CPU 负载、内存占用、温度、运行时间、实时上下行速率、内网 IP、公网 IP 和路由器时间,并显示在 LCD 上。

当前代码默认适配:

  • 开发板:Waveshare ESP32-C6-LCD-1.47
  • 屏幕驱动:ST7789
  • 分辨率:172 x 320
  • 开发环境:Arduino IDE
  • 显示库:GFX Library for Arduino
  • UI 库:LVGL 8.x

功能

  • 显示设备名称:C2000 Max
  • 显示 OpenWrt 系统状态:
    • CPU 使用率
    • RAM 使用率
    • CPU 温度
    • OpenWrt uptime
  • 显示网络状态:
    • UP 上传速率
    • DOWN 下载速率
    • LAN IP
    • Public IP
  • 底部显示 OpenWrt 后台 date 获取的当前时间
  • OpenWrt 后端脚本无固定 sleep 阻塞,响应更快
  • 网络速度单位自动切换 Kb/s 和 Mb/s
  • 英文和数字使用 LVGL 内置 Montserrat 字体

项目文件

OpenWrt_Monitor.ino   Arduino 主程序
config.h              Wi-Fi 和 OpenWrt 接口配置
gfx.cpp / gfx.h       屏幕驱动配置
ui.cpp / ui.h         LVGL 界面
openwrt.cpp / .h      HTTP 请求与 JSON 解析
lcd.cpp / lcd.h       备用底层 LCD 驱动,目前主程序未使用
openwrt_status.sh     OpenWrt 后台 CGI 脚本

新手先看:完整流程总览

如果你是第一次使用 Arduino 或 OpenWrt CGI,可以按下面顺序做,不要跳步:

  1. 准备硬件:ESP32-C6-LCD-1.47、USB-C 数据线、OpenWrt 路由器。
  2. 在电脑上安装 Arduino IDE。
  3. 在 Arduino IDE 里安装 ESP32 开发板支持。
  4. 在 Arduino IDE 里安装依赖库:GFX Library for Arduino、lvgl、ArduinoJson。
  5. 修改 config.h 里的 Wi-Fi 名称、Wi-Fi 密码、OpenWrt 接口地址。
  6. 把 openwrt_status.sh 上传到 OpenWrt 的 /www/cgi-bin/status.sh。
  7. 给 /www/cgi-bin/status.sh 添加执行权限。
  8. 检查 OpenWrt 的 uhttpd 是否允许 .sh CGI。
  9. 用浏览器打开 http://192.168.7.1/cgi-bin/status.sh,确认能看到 JSON。
  10. 回到 Arduino IDE,选择开发板和串口,上传 ESP32 程序。
  11. 上传后按一下 ESP32 的 RESET,等待屏幕显示数据。

命令在哪里执行

文档里会出现电脑命令和 OpenWrt 命令。新手最容易混淆,先记住这个表:

命令前面写 scp             在电脑终端执行
命令前面写 ssh             在电脑终端执行,用来登录 OpenWrt
命令路径是 /www/...        登录 OpenWrt 后,在 OpenWrt 终端执行
uci / chmod / ls / mkdir   登录 OpenWrt 后执行
Arduino IDE 菜单操作       在电脑上的 Arduino IDE 里完成

如果你用的是 macOS,打开“终端”执行命令。如果你用的是 Windows,可以用 PowerShell、Windows Terminal,或者安装 PuTTY / WinSCP。

开始前准备

硬件准备

  • Waveshare ESP32-C6-LCD-1.47
  • 一根支持数据传输的 USB-C 线
  • 一台已经刷好 OpenWrt 的路由器
  • 一台电脑,安装 Arduino IDE

注意:有些 USB-C 线只能充电,不能传数据。如果 Arduino IDE 看不到串口,优先换一根线。

网络准备

  • ESP32 要连接到能访问 OpenWrt 的 Wi-Fi。
  • 电脑最好也连接到同一个 OpenWrt 网络,方便测试接口。
  • 本文默认 OpenWrt LAN IP 是 192.168.7.1。如果你的路由器不是这个地址,所有命令里的 192.168.7.1 都要改成你的实际地址。

一、Arduino IDE 准备

1. 安装 ESP32 开发板支持

打开 Arduino IDE,进入:

文件 -> 首选项 -> 其他开发板管理器地址

加入 Espressif ESP32 地址:

https://espressif.github.io/arduino-esp32/package_esp32_index.json

然后进入:

工具 -> 开发板 -> 开发板管理器

搜索并安装:

esp32 by Espressif Systems

建议使用较新的 3.x 版本。如果某些旧库不兼容,也可以尝试 2.0.x 版本。

安装完成后,可以在 Arduino IDE 菜单里看到类似:

工具 -> 开发板 -> esp32

如果看不到 ESP32 相关开发板,说明 ESP32 开发板支持还没有安装成功。

2. 安装依赖库

进入 Arduino IDE:

工具 -> 管理库

安装以下库:

GFX Library for Arduino
lvgl
ArduinoJson

建议:

  • LVGL 使用 8.x 版本
  • ArduinoJson 使用 6.x 或兼容版本

如果 Arduino IDE 提示找不到某个头文件,例如:

lvgl.h: No such file or directory
ArduinoJson.h: No such file or directory
Arduino_GFX_Library.h: No such file or directory

说明对应库没有安装成功,需要回到“管理库”重新安装。

二、配置 ESP32 端

打开 config.h,修改 Wi-Fi 和 OpenWrt 接口地址:

#define WIFI_SSID "你的WiFi名称"
#define WIFI_PASS "你的WiFi密码"

#define OPENWRT_URL "http://192.168.7.1/cgi-bin/status.sh"

注意:

  • ESP32 必须能访问 OpenWrt 的这个 IP。
  • 如果你的路由器 LAN IP 不是 192.168.7.1,请改成实际地址。
  • 默认后端脚本路径是 /www/cgi-bin/status.sh。如果你使用其他文件名,这里也要同步修改。

举例:

如果你的 Wi-Fi 名称是 Home-WiFi,密码是 12345678,OpenWrt 地址是 192.168.1.1,则应改成:

#define WIFI_SSID "Home-WiFi"
#define WIFI_PASS "12345678"

#define OPENWRT_URL "http://192.168.1.1/cgi-bin/status.sh"

常见错误:

  • Wi-Fi 名称大小写写错。
  • Wi-Fi 密码写错。
  • ESP32 连接的是访客 Wi-Fi,无法访问 OpenWrt 管理地址。
  • OpenWrt 地址写成了电脑地址或公网地址。

三、部署 OpenWrt 后台脚本

项目里的 openwrt_status.sh 是运行在 OpenWrt 上的 CGI 脚本。

1. SSH 登录 OpenWrt

先确认电脑可以登录路由器:

ssh root@192.168.7.1

如果你的 OpenWrt LAN IP 不是 192.168.7.1,请替换成实际 IP。

第一次登录时,系统可能会询问:

Are you sure you want to continue connecting?

输入:

yes

然后回车。

如果提示密码,请输入 OpenWrt 的 root 密码。输入密码时终端通常不会显示任何字符,这是正常现象。

登录成功后,通常会看到类似:

root@OpenWrt:~#

看到这个提示符,说明你现在已经在 OpenWrt 里面了。

2. 确认 CGI 目录存在

登录 OpenWrt 后执行:

mkdir -p /www/cgi-bin

3. 上传脚本到路由器

可以用 scp 上传:

scp openwrt_status.sh root@192.168.7.1:/www/cgi-bin/status.sh

如果你的路由器 IP 不是 192.168.7.1,请替换成实际 IP。

注意:scp 这条命令是在电脑终端执行,不是在 OpenWrt 里执行。

上传成功后,可以登录 OpenWrt 检查文件是否存在:

ls -l /www/cgi-bin/status.sh

如果提示:

No such file or directory

说明文件没有传到正确位置,请重新执行 scp 命令。

4. 添加执行权限

SSH 登录 OpenWrt 后执行:

chmod +x /www/cgi-bin/status.sh

确认权限:

ls -l /www/cgi-bin/status.sh

正常应能看到类似:

-rwxr-xr-x    1 root     root          ... /www/cgi-bin/status.sh

5. OpenWrt uhttpd 开启 CGI

OpenWrt 默认使用 uhttpd 提供 Web 服务。为了让 .sh 文件能作为 CGI 脚本运行,需要确认解释器配置。

执行:

uci show uhttpd.main.interpreter

如果已经看到类似:

uhttpd.main.interpreter='.sh=/bin/sh'

说明 .sh CGI 已经配置好。

如果没有输出,或者没有 .sh=/bin/sh,执行:

uci add_list uhttpd.main.interpreter='.sh=/bin/sh'
uci commit uhttpd
/etc/init.d/uhttpd restart

如果你不确定配置是否生效,可以再次查看:

uci show uhttpd.main.interpreter

6. 命令行测试脚本

在 OpenWrt 上直接执行:

/www/cgi-bin/status.sh

正常情况下,开头应输出:

Content-Type: application/json

下面跟着一段 JSON 数据。

如果提示权限不足,重新执行:

chmod +x /www/cgi-bin/status.sh

如果直接执行脚本时看到 JSON,但浏览器打不开,通常是 uhttpd CGI 配置问题,请重点检查上一节的 .sh=/bin/sh。

7. 浏览器测试接口

在浏览器打开:

http://192.168.7.1/cgi-bin/status.sh

正常情况下会看到类似:

{
  "load": 0.08,
  "cpu_load": 0.08,
  "cpu_percent": 12,
  "mem": 42,
  "mem_percent": 42,
  "temp": 48,
  "cpu_temp": 48,
  "uptime": 123456,
  "time": "14:30:08",
  "rx": 123456789,
  "tx": 987654321,
  "rx_speed": 2048,
  "tx_speed": 1024,
  "lan_ip": "192.168.7.1",
  "wan_ip": "10.0.0.2",
  "public_ip": "1.2.3.4"
}

说明:

  • rx_speed 和 tx_speed 单位是 Byte/s。
  • ESP32 会转换成 bit/s 后显示为 Kb/s 或 Mb/s。
  • 第一次请求时速度可能为 0,因为脚本需要先建立一次采样缓存。
  • public_ip 默认通过 api.ipify.org 获取,并缓存 5 分钟,避免频繁访问外网。

如果浏览器显示下载文件,而不是直接显示 JSON,也没有关系,说明 CGI 有返回内容。可以用文本编辑器打开下载的文件确认是否是 JSON。

如果浏览器显示:

404 Not Found

通常表示路径错了,检查:

ls -l /www/cgi-bin/status.sh

如果浏览器显示:

403 Forbidden

通常表示权限不对,执行:

chmod +x /www/cgi-bin/status.sh

如果浏览器显示脚本文本本身,而不是 JSON,通常表示 .sh 没有被当作 CGI 执行,重新检查:

uci show uhttpd.main.interpreter

四、测试接口

完成 OpenWrt 脚本部署和 uhttpd CGI 配置后,建议先测试接口,再上传 ESP32 程序。

1. 浏览器测试

访问:

http://192.168.7.1/cgi-bin/status.sh

能看到 JSON 就说明 OpenWrt 后端正常。

2. ESP32 配置对应 URL

确认 config.h 中的地址一致:

#define OPENWRT_URL "http://192.168.7.1/cgi-bin/status.sh"

如果浏览器里能打开,但 ESP32 显示数据为空,通常是:

  • ESP32 连接的 Wi-Fi 和 OpenWrt 不在同一网络
  • OPENWRT_URL 的 IP 或文件名写错
  • OpenWrt 防火墙或网络隔离阻止访问

五、上传 ESP32 程序

Waveshare ESP32-C6-LCD-1.47 推荐设置

Arduino IDE 中选择:

工具 -> 开发板 -> ESP32 Arduino -> ESP32C6 Dev Module

常见设置:

USB CDC On Boot: Enabled
Upload Speed: 460800 或 921600
Flash Size: 4MB
Partition Scheme: Default

不同 Arduino ESP32 Core 版本的菜单项可能略有不同,能正常编译上传即可。

上传步骤

  1. 用 USB-C 线连接 ESP32 和电脑。
  2. 打开 Arduino IDE。
  3. 打开本项目的 OpenWrt_Monitor.ino。
  4. 选择开发板:
工具 -> 开发板 -> ESP32 Arduino -> ESP32C6 Dev Module
  1. 选择串口:
工具 -> 端口

如果看不到串口:

  • 换一根支持数据传输的 USB-C 线。
  • 换电脑 USB 口。
  • 按一下开发板 RESET。
  • macOS 或 Windows 可能需要安装 USB 串口驱动,具体看开发板使用的 USB 芯片。
  1. 点击 Arduino IDE 左上角的“验证”按钮,先确认能编译。
  2. 编译通过后,点击“上传”按钮。
  3. 上传完成后,按一下开发板 RESET。
  4. 等待 ESP32 连接 Wi-Fi 并访问 OpenWrt 接口。

如果上传失败,可以尝试手动进入下载模式:

  1. 按住 BOOT
  2. 点一下 RESET
  3. 松开 BOOT
  4. 再点击 Arduino IDE 上传
  5. 上传完成后按一下 RESET

上传成功后的正常现象

正常情况下,屏幕会显示:

C2000 MAX
SYSTEM
CPU / RAM / TEMP / UPTIME
NETWORK
UP / DOWN / LAN / PUB

如果 Wi-Fi 或 OpenWrt 接口暂时不可用,部分数据可能显示为 --。

建议先打开串口监视器

Arduino IDE 中可以打开:

工具 -> 串口监视器

波特率选择:

115200

当前程序主要显示在屏幕上,串口输出不多,但串口监视器可以帮助判断开发板是否已经正常启动。

六、默认屏幕参数

当前 gfx.cpp 默认使用 Waveshare ESP32-C6-LCD-1.47 参数:

constexpr int LCD_MOSI = 6;
constexpr int LCD_SCLK = 7;
constexpr int LCD_CS = 14;
constexpr int LCD_DC = 15;
constexpr int LCD_RST = 21;
constexpr int LCD_BL = 22;
constexpr int LCD_WIDTH = 172;
constexpr int LCD_HEIGHT = 320;
constexpr int LCD_X_OFFSET = 34;
constexpr int LCD_Y_OFFSET = 0;

对应官方参数:

MOSI   GPIO6
SCLK   GPIO7
CS     GPIO14
DC     GPIO15
RST    GPIO21
BL     GPIO22
LCD    ST7789
Size   172 x 320
Offset X = 34

七、适配不同 ESP32 型号或不同屏幕

适配其他 ESP32 板子时,主要改 4 类东西:

  1. 开发板型号
  2. LCD 引脚
  3. LCD 驱动型号
  4. 分辨率、偏移和旋转方向

1. 修改开发板型号

在 Arduino IDE 选择与你硬件匹配的板型,例如:

ESP32 Dev Module
ESP32-S3 Dev Module
ESP32-C3 Dev Module
ESP32-C6 Dev Module
ESP32C6 Dev Module

如果屏幕驱动和引脚都正确,但一直黑屏,优先确认板型是否选错。

2. 修改 LCD 引脚

打开 gfx.cpp,修改:

constexpr int LCD_MOSI = 6;
constexpr int LCD_SCLK = 7;
constexpr int LCD_CS = 14;
constexpr int LCD_DC = 15;
constexpr int LCD_RST = 21;
constexpr int LCD_BL = 22;

不同开发板的屏幕接线不同,必须按实际原理图或商家 Wiki 修改。

如果你的屏幕没有背光控制脚,可以把:

constexpr int LCD_BL = 22;

改成实际背光脚,或者在 gfx_init() 中去掉:

pinMode(LCD_BL, OUTPUT);
digitalWrite(LCD_BL, HIGH);

3. 修改屏幕分辨率和偏移

仍然在 gfx.cpp 修改:

constexpr int LCD_WIDTH = 172;
constexpr int LCD_HEIGHT = 320;
constexpr int LCD_X_OFFSET = 34;
constexpr int LCD_Y_OFFSET = 0;

常见 ST7789 屏幕参数示例:

240 x 240: offset 0, 0 或 0, 80
240 x 320: offset 0, 0
172 x 320: offset 34, 0
170 x 320: offset 35, 0

偏移不对时,常见现象:

  • 画面偏移
  • 画面只显示一部分
  • 边缘有彩条
  • 屏幕亮但内容不在可见区域

4. 修改 LCD 驱动类型

当前使用:

Arduino_GFX *gfx = new Arduino_ST7789(...);

如果你的屏幕不是 ST7789,需要换成对应驱动。例如:

Arduino_GFX *gfx = new Arduino_ILI9341(...);
Arduino_GFX *gfx = new Arduino_GC9A01(...);
Arduino_GFX *gfx = new Arduino_ST7735(...);

具体支持哪些驱动,请查看 GFX Library for Arduino 文档或示例。

5. 修改 SPI 总线

当前使用:

Arduino_DataBus *bus = new Arduino_ESP32SPI(
    LCD_DC, LCD_CS, LCD_SCLK, LCD_MOSI, GFX_NOT_DEFINED
);

大多数 ESP32 SPI 屏幕都可以这样使用。

如果你的屏幕需要 MISO,可以把最后一个参数改成实际 MISO 引脚:

Arduino_DataBus *bus = new Arduino_ESP32SPI(
    LCD_DC, LCD_CS, LCD_SCLK, LCD_MOSI, LCD_MISO
);

6. 修改 UI 分辨率

当前 UI 按 172 x 320 竖屏设计:

disp_drv.hor_res = 172;
disp_drv.ver_res = 320;

如果屏幕分辨率不同,需要在 ui.cpp 里同步修改:

static lv_color_t buf[172 * 40];
disp_drv.hor_res = 172;
disp_drv.ver_res = 320;

例如 240 x 320 竖屏:

static lv_color_t buf[240 * 40];
disp_drv.hor_res = 240;
disp_drv.ver_res = 320;

如果改成横屏,还需要重新调整 ui.cpp 里的控件坐标和宽高。

八、OpenWrt 接口字段说明

ESP32 当前支持以下字段:

{
  "load": 0.08,
  "cpu_percent": 12,
  "mem": 42,
  "temp": 48,
  "uptime": 123456,
  "time": "14:30:08",
  "rx": 123456789,
  "tx": 987654321,
  "rx_speed": 2048,
  "tx_speed": 1024,
  "lan_ip": "192.168.7.1",
  "public_ip": "1.2.3.4"
}

也兼容这些旧字段:

{
  "cpu_load": 0.08,
  "mem_percent": 42,
  "cpu_temp": 48
}

字段说明:

load        CPU load average,浮点数,兼容旧字段
cpu_percent CPU 使用率百分比,0-100
mem         内存占用百分比,0-100
temp        CPU 温度,摄氏度
uptime      OpenWrt 运行时间,单位秒
time        OpenWrt 当前时间,建议 HH:MM:SS
rx          网卡累计接收字节数
tx          网卡累计发送字节数
rx_speed    接收速度,Byte/s
tx_speed    发送速度,Byte/s
lan_ip      内网 IP
public_ip   公网 IP

九、修改监控网卡

OpenWrt 脚本默认监控:

IFACE="${IFACE:-br-lan}"

如果你要监控 WAN 口、PPPoE 或其他接口,可以改成实际网卡名,例如:

IFACE="${IFACE:-pppoe-wan}"

查看网卡:

ip link

也可以临时用环境变量运行:

IFACE=pppoe-wan /www/cgi-bin/status.sh

十、常见问题

1. 屏幕完全不亮

优先检查:

  • LCD_BL 背光引脚是否正确
  • LCD_CS、LCD_DC、LCD_RST 是否正确
  • 开发板型号是否选对
  • USB 供电是否稳定

当前默认背光是:

pinMode(LCD_BL, OUTPUT);
digitalWrite(LCD_BL, HIGH);

如果你的屏幕背光是低电平点亮,需要改成:

digitalWrite(LCD_BL, LOW);

2. 屏幕亮,但没有内容

可能原因:

  • ST7789 偏移参数不对
  • 分辨率不对
  • SPI 引脚不对
  • 屏幕驱动型号不对

重点检查 gfx.cpp 中的:

LCD_WIDTH
LCD_HEIGHT
LCD_X_OFFSET
LCD_Y_OFFSET
Arduino_ST7789

3. 一直显示空数据或网速为 0

先在浏览器打开:

http://你的路由器IP/cgi-bin/status.sh

确认 JSON 是否正常返回。

如果网页打不开:

  • CGI 脚本没有执行权限
  • 路径不对
  • OpenWrt 没启用 uhttpd CGI
  • ESP32 和 OpenWrt 不在同一网络

建议按这个顺序排查:

  1. 电脑浏览器能否打开 status.sh。
  2. 手机或电脑连接同一个 Wi-Fi 后,能否打开 status.sh。
  3. config.h 中的 OPENWRT_URL 是否和浏览器地址完全一致。
  4. OpenWrt 的 LAN IP 是否变化。
  5. ESP32 连接的 Wi-Fi 是否是同一个内网。

如果浏览器能打开,但 ESP32 还是没有数据,优先检查 Wi-Fi 名称和密码。

4. 公网 IP 显示为空

脚本会访问:

http://api.ipify.org

如果路由器不能访问外网,公网 IP 会回退为 WAN IP。某些内网、多级 NAT、旁路由环境下,公网 IP 和 WAN IP 可能不同。

5. 时间显示不对

底部时间优先显示 OpenWrt 的:

date '+%H:%M:%S'

如果时间不对,请先修正 OpenWrt 时间同步:

date

或者检查 OpenWrt 的 NTP 设置。

如果 OpenWrt 自己的 date 时间就是错的,ESP32 屏幕底部时间也会错。请先让 OpenWrt 能正常同步时间。

6. 上传失败

ESP32-C6 有时需要手动进入下载模式:

  1. 按住 BOOT
  2. 点一下 RESET
  3. 松开 BOOT
  4. 点击 Arduino IDE 上传
  5. 上传完成后再按一下 RESET

7. 编译失败

如果 Arduino IDE 报错,请先看第一行真正的错误。

常见情况:

No such file or directory

通常是缺少库,回到“管理库”安装对应库。

undefined reference

通常是代码引用了没有参与编译的对象。当前版本已经移除了中文 CJK 字库依赖,如果仍出现这类错误,请清理 Arduino 缓存或重启 Arduino IDE 后再编译。

Sketch uses too much program storage space

通常是启用了过大的字体或图片资源。当前项目已经改为全英文显示,正常不会再因为中文字体导致体积过大。

十一、交付客户前建议

交付给客户前,建议确认:

  • Wi-Fi 名称和密码已经改成客户环境
  • OPENWRT_URL 是客户路由器地址
  • OpenWrt 脚本已经部署并能浏览器访问
  • 屏幕能正常点亮
  • CPU/RAM/TEMP/UP 有数据
  • UP/DOWN 网速会变化
  • LAN/PUB IP 正常
  • 底部时间与 OpenWrt 时间一致

十二、安全提醒

当前 config.h 中会明文保存 Wi-Fi 密码。公开代码或交付第三方前,建议删除真实密码,改成占位内容:

#define WIFI_SSID "YOUR_WIFI"
#define WIFI_PASS "YOUR_PASSWORD"

OpenWrt 的 status.sh 接口默认没有鉴权,建议只在内网使用,不要暴露到公网。

S
Description
使用微雪ESP32-C6-1.47的小屏幕做为OPENWRT的运行状态监控屏幕,以鲲鹏C2000 Max刷了第三方OP作为实际例子进行
Readme
34 MiB
0 Stars 1 Watchers 0 Forks
Languages
C 94.9%
C++ 4.5%
Python 0.5%