给工业视觉质检配一套会自己稳住光照的硬件:ESP32 测光 → 调光 → 闭环稳光, 红绿声光给出检测结果,再配一个可复现的数据集采集台,把"采集 → 训练 → 检测"串成闭环。
本仓库只包含硬件部分(固件、接线、实测记录、数据集设计与采集工具), 不含任何软件系统的源代码与模型权重。
两个上位机工具都是自带页面的本地程序,下面是真实运行的界面截图:
| 数据集采集台(一图一标签,自动裁切) | 硬件演示台(闭环稳光 + 判定反馈) |
|---|---|
![]() |
![]() |
截图中间那块黑色区域是相机预览区:它需要本地摄像头权限,无头浏览器截不出画面, 在真机上打开就是实时画面(截图里的 222.5 lx / 25% 是真实硬件读数)。 两个工具都是 Flask 本地程序(要 Python + 串口 + 摄像头),GitHub 上跑不起来 —— GitHub Pages 只能托管静态页面。想看活的界面:下载仓库后双击
05_数据集与标签设计/console/0_启动采集台.bat或硬件演示系统/演示台/0_启动演示台.bat。
视觉检测最怕的不是算法,而是光照不稳定:同一张标签,光变了,像素分布就变了,模型就判错。 本系统用"闭环稳光"把这件事按住:
BH1750 照度传感器 ──I2C──▶ ESP32 ──PWM──▶ MOS 模块 ──▶ 5V COB 灯带
▲ │
└────── 实测照度 ◀─────┘ (比例控制 + 步长限幅 + 死区,自动收敛到目标照度)
└──▶ 红/绿指示 + 蜂鸣器:正常 / 异常
配套的数据集采集台保证采出来的照片"光照条件完全一致", 并且把每张图当时的照度、亮度、时间一起写进记录表 —— 数据可追溯,训练可复现。
| 位置 | 内容 |
|---|---|
00_从采购到参赛_执行总表.md |
从采购到参赛的执行总表(时间线、验收点) |
01_ESP32固件/ |
正式固件 lightguard_esp32.ino + 5 个验证固件 + 一键烧录脚本 flash_manual.ps1 |
02_硬件安装与接线/ |
接线图、引脚表、接线速查卡(一页打印版)、安装核对单 |
03_采购清单/ |
最低成本采购清单(含型号与替代方案) |
04_硬件验证记录/ |
逐项实测记录(原始串口日志、镜像 Hash 校验、闭环数据、频闪量化) |
05_数据集与标签设计/ |
6 类标签图案与 A4 打印页、采集说明、批处理脚本、网页采集台、独立采集台 console/ |
硬件演示系统/ |
最小硬件版的搭建与演示步骤 + 上位机演示软件 演示台/(自动稳光 + 拍照判定 + 红绿声反馈) |
演示视频拍摄脚本.md |
演示视频分镜与旁白(含口径提醒) |
| 部件 | 型号 / 规格 | 接到哪 |
|---|---|---|
| 主控 | ESP32 开发板(ESP32-D0WD-V3,4 MB Flash) | — |
| 照度传感器 | BH1750(I2C,地址 0x23) | SDA=GPIO21,SCL=GPIO22,3V3 |
| 灯带 | 5V COB 灯带 8 mm 300 灯/米 1 米(中性光) | 经 MOS 模块供电 |
| 驱动模块 | MOSFET 模块(逻辑电平,DC± / OUT± / IN±) |
GPIO25 → IN+ |
| 电源 | 5V 4 A 适配器(灯带独立供电) | 灯带 + MOS 模块 |
| 指示 | 绿色 LED、红色 LED、有源蜂鸣器 | GPIO26 / GPIO27 / GPIO32 |
| 摄像头 | USB UVC 免驱摄像头(1920×1080) | USB |
三条硬规矩:
- 灯带不能直接接 GPIO,必须经 MOS 模块;ESP32 与灯带 5V 电源必须共地;
- 绿 = 正常(GPIO26)、红 = 异常(GPIO27),别接反;
- 换用 ≤1 kHz 的驱动模块时,PWM 频率要相应改回 1 kHz(本仓库默认 8 kHz)。
按住 BOOT 不放 → 按一下 EN/RST → 松开 BOOT → 双手离开板子 → 开始烧录
不想掐时间就用脚本,它会一直等到你按完 BOOT 再开始烧:
powershell -ExecutionPolicy Bypass -File .\01_ESP32固件\flash_manual.ps1 -Sketch .\01_ESP32固件\lightguard_esp32.ino01_ESP32固件/ 里每个外设都有一个独立验证固件(esp32_blink_test、bh1750_test、
light_pwm_test、indicator_test、mos_polarity_probe),按顺序跑一遍就知道哪一段没接好。
cd 05_数据集与标签设计\console
py -3.11 -m pip install flask pyserial # 只需一次
py -3.11 dataset_console.py # 自动找 ESP32 串口,浏览器自动打开浏览器里:打开摄像头 → 设为 25% 亮度 → 等"照度稳定" → 选类别 → Enter 采集。
还没接硬件也能先跑流程:
py -3.11 dataset_console.py --no-serial
cd 硬件演示系统\演示台
py -3.11 -m pip install flask pyserial numpy pillow opencv-python # 只需一次
py -3.11 demo_console.py # 自动找串口,浏览器自动打开页面里三步:放合格品 → 点「设为参考图」 → 稳光(目标 300 lx ±20)→ 换待检品按 Enter, 页面给出 ✅正常 / ⛔异常,硬件同时亮绿灯或红灯(异常还会短鸣)。
不接硬件也能看界面:
py -3.11 demo_console.py --no-serial判定模块可单独自测:py -3.11 test_detect_ref.py(合成图 10 项)
同目录还有三个现场必备的小工具:
| 工具 | 作用 |
|---|---|
calibrate_lux.py + 0_照度标定.bat |
换位置后重新标定照度(拟合 lx/每1%),自动判断目标照度与相机不过曝区间是否冲突,导出 Markdown 报告 |
light_off.py + 关灯_应急.bat |
应急关灯:程序被强杀、板子刚复位后一键关灯,并回读硬件确认 |
banding_check.py |
频闪条纹复测(PWM 频率 × 卷帘快门),自动挑最平坦区域算行 σ,抓帧默认测完即删 |
运行任何抓帧/录制前,先确认画面里没有证件、表格、聊天窗口等个人内容。
硬件演示系统/最小硬件版_搭建与演示.md 有完整步骤(含上电顺序与安全操作)。
| 结论 | 数据 | 适用范围 |
|---|---|---|
| 上位机照度闭环(真机通过) | 目标 300 ± 20 lx:25% → 223.3 lx → 31% → 283.3 lx,9.1 秒收敛 | 演示台 light_loop.py + 正式固件 LIGHT n(增益自动估算) |
| 照度标定曲线(真机) | 0%→0、25%→224.2、50%→466.7、100%→965.8 lx;拟合 9.77 lx / 每 1% 亮度 | 当前几何(传感器在桌面);换位置必须重标 |
| ★ 900 lx 与相机曝光冲突 | 本几何下达到 900 lx 需 94.1% 亮度,而 100% 已过曝;相机安全区间 20% |
需把传感器移入箱内最终位置重标,或改验收点 |
| 拍照 → 判定 → 硬件反馈闭环 | 用 6 种真实标签图案:正常判正常(0.000%),5 种缺陷全判异常(0.33%~22.2%),串口回读的红绿指示每次都对 | 演示台 detect_ref.py(参考图比对) |
| PWM 1 kHz 会让相机画面出现频闪条纹 | 三帧行均值波动标准差 8.85 / 8.78 / 8.80(≈满量程 3.5%),固定相位 —— 典型的"PWM × 卷帘快门" | 实测 |
| 改成 8 kHz 抑制条纹 | 周期 125 µs,单行曝光跨越多个周期被平均掉 | 已改代码,待按同一方法复测 |
| 100% 亮度会过曝 | 纸面一片白、文字被冲掉 | 实测,箱内工作区间取 20%~35% |
| 读数纪律 | 改亮度后必须等 2.2 秒以上再读,否则会读到乱数(15%→12.5 lx 这种) | 已写进上位机软件 |
口径说明:闭环现由上位机实现并在真机验证通过;正式固件本身仍只提供
LIGHT n手动调光。 我们不在文档里把"上位机跑通"写成"固件内置闭环"。
115200 波特率,一行一条 JSON:
| 命令 | 回复 |
|---|---|
PING |
{"ok":true,"device":"LIGHTGUARD_ESP32"} |
STATUS |
{"ok":true,"lux":123.4,"brightness":25,"result":"idle"} |
LIGHT <0-100> |
设置灯带亮度,并回一条 STATUS |
RESULT normal|abnormal|idle |
设置红绿指示与蜂鸣,并回一条 STATUS |
- 6 个类别:正常、断线、缺墨、污点、划痕、偏位重影(缺陷都做到人眼明显可见);
- 标签尺寸 60 × 40 mm:一页 A4 排 18 个,页脚带 100 mm 校验尺(打印后量一下,确认没被缩放);
- 一图一记录:文件名、类别、缺陷类型、照度 lx、亮度 %、时间,写进
采集记录表.csv(带 BOM,Excel 直接打开); - 一致性纪律:固定亮度、盖上箱盖、锁定焦距、机位不动; 训练 / 验证 / 测试按样本划分而不是按图片划分(同一张标签的多张照片必须进同一个集合)。
| # | 坑 | 说明 |
|---|---|---|
| 1 | 烧录要按 BOOT | 本板无自动下载电路,属正常现象 |
| 2 | 必须共地 | 灯带 5V 电源与 ESP32 不共地 → PWM 完全失控(常亮或乱闪) |
| 3 | MOSFET 要逻辑电平型号 | 老式 IRF520 在 5V 栅压下会发烫,别用 |
| 4 | BH1750 用 3V3 | 不要接 5V |
| 5 | 别留下亮着的灯带 | 正式固件默认亮度已改为 0%(复位也不会亮);但调光仍需显式 LIGHT n,收尾建议发 LIGHT 0 |
| 6 | 避开 GPIO6 |
前者接 Flash,后者只能输入 |
| 7 | 采集时别开其它摄像头程序 | 相机、会议软件会抢占 USB 摄像头 |
- 本仓库内容均为本地实测,每条结论都能在
04_硬件验证记录/hardware-test-log.md里找到原始数据; - 标注"待复测 / 未实测"的项不会写成已完成;
- 本仓库不包含软件系统源代码与模型权重,也不包含任何个人信息。

