Buck Blog · 博客正文

返回技术分享首页
「芯火·破浪」STM32嵌入式AI开发训练营(L2)— 工业边缘传感网络高级进阶

🌊「芯火·破浪」STM32嵌入式AI开发训练营(L2)

工业边缘传感网络 — FreeRTOS + Modbus + DSP + PyQt5 工业面板 · 30天高级进阶
STM32F407ZGT6FreeRTOS 多任务 Modbus RTUMQTT CMSIS-DSP卡尔曼滤波 FFT 频谱分析PID 闭环控制 PyQt5 工业面板Claude Code + DeepSeek 单人独立量化展示
训练营级别
L2 高级进阶(须先完成 L1)
实训时长
30天(不限定起始日期)
每日时段
8:30 — 17:30(白天实验室)
学生起点
已完成L1,能独立驱动STM32外设和传感器
主控芯片
STM32F407ZGT6(Cortex-M4+FPU, 168MHz)
开发环境
Win + VS Code + PlatformIO + Claude Code + DeepSeek
新增硬件
无(完全复用 L1 器材,¥0 额外支出)
结题
工业边缘传感网络 + 量化指标展示 + 技术答辩
📈 L1 → L2 核心提升

L2 在 不增加任何外围硬件 的前提下,从软件架构、通信协议、数据处理、上位机四个维度全面升级。以下是具体变化对比:

维度L1「芯火·启航」L2「芯火·破浪」提升价值
软件架构 裸机 Super Loop
(while(1) 大循环)
FreeRTOS 多任务
(6任务 + 4任务 双节点)
从"能跑通"到"会设计"——掌握任务优先级、消息队列、信号量、互斥量,这正是企业嵌入式岗位的核心技能
节点间通信 HC-05 蓝牙透传
(发什么收什么)
Modbus RTU 工业总线
(寄存器映射 + CRC校验 + 主从轮询)
理解工业现场通信标准——Modbus 是全球PLC/传感器/执行器的事实标准,学会后可直接对接工业设备
上报协议 ESP8266 AT 透传
(raw TCP 发字符串)
MQTT 协议
(Topic 发布/订阅 + JSON 体 + QoS)
接入 IoT 云平台的标准方式——学会 MQTT 即可对接阿里云/华为云/OneNET/自建EMQX等主流 IoT 平台
数据处理 原始传感器数值
(直接读取→直接显示)
CMSIS-DSP 数字信号处理
(FIR/IIR滤波 + 卡尔曼 + 互补滤波 + FFT + PID)
从"采数据"到"用数据"——掌握信号处理算法,这是竞赛中区分三等奖和一等奖的分水岭
控制能力 开环控制
(手动PWM调节)
PID 闭环控制
(温度/光照自动调节 + 参数调优)
控制理论落地实践——PID是90%工业控制场景的核心算法,参数调优能力是电赛控制类题目的必备技能
PC 上位机 matplotlib 脚本
(简单曲线刷新)
PyQt5 工业监控面板
(仪表盘 + 实时曲线 + 3D姿态球 + FFT频谱瀑布图 + 控制面板)
从"看数据"到"控制数据"——PyQt5 是 Python 生态最成熟的桌面GUI框架,可复用到毕业设计、竞赛上位机和实际工业项目
可靠性 基础 IWDG 看门狗 多级异常处理体系
(任务级看门狗 + HardFault 捕获 + 通信超时重连 + 栈溢出检测 + 传感器热插拔恢复)
从"实验室 demo"到"准产品级"——培养工程化思维,理解嵌入式系统的鲁棒性设计
综合复杂度 ★★☆☆☆ ★★★★★ L2 结业后具备独立承担电赛/蓝桥杯/物联网大赛等高水平竞赛嵌入式部分的能力
🎯 L2 实训目的

🧵 掌握实时操作系统(RTOS)

将 L1 裸机代码全部重构为 FreeRTOS 多任务架构,学会任务优先级设计、消息队列通信、信号量同步、互斥量保护共享资源、软件定时器驱动。FreeRTOS 是 STM32 生态最主流的 RTOS,学会后可直接复用至 Infineon/NXP/ESP32 等平台,是嵌入式工程师简历上含金量最高的关键词之一

🔌 精通工业通信协议

实现 Modbus RTU 主机/从机协议栈MQTT 发布/订阅模型,理解工业现场总线和 IoT 云平台的标准通信范式。学会设计带有 CRC 校验、超时重传、地址寻址的健壮通信协议——这项能力在电赛通信类题目、物联网大赛和工业自动化岗位中直接可用

📊 数字信号处理落地

利用 F407 的 FPU + CMSIS-DSP 库实现 FIR/IIR 数字滤波、卡尔曼滤波、互补滤波、1024 点 FFT 频谱分析、PID 闭环控制。将抽象的数学公式变成嵌入式 C 代码,体验算法在单片机上运行的实时效果。DSP 能力是电赛信号处理类题目的核心竞争力。

🎨 构建专业级上位机

Claude Code + PyQt5 搭建工业级监控面板:仪表盘控件、多通道实时曲线、OpenGL 3D 姿态球、频谱瀑布图、PID 调参界面。整个 GUI 由 AI 辅助生成代码,学生聚焦于系统集成和功能验证,体验 "AI 时代嵌入式全栈开发" 的高效工作流。

📅 五阶段总览
阶段天数核心任务关键产出
阶段1:FreeRTOS 内核Day 1—6 多任务消息队列信号量互斥量软件定时器中断管理 L1 裸机代码全部改造为 FreeRTOS 多任务架构
阶段2:工业通信协议Day 7—12 Modbus RTUMQTTCRC校验JSON协议设计 Modbus 寄存器映射表 + MQTT Topic 设计文档
阶段3:DSP 信号处理Day 13—18 CMSIS-DSPFIR/IIR卡尔曼滤波FFTPID互补滤波 每个算法独立 Demo + 可视化对比
阶段4:系统重构Day 19—24 全栈整合PyQt5面板任务联调异常处理 全链路跑通:采集节点→Modbus→网关→MQTT→PC面板
阶段5:性能优化+展示Day 25—30 性能测试量化指标技术答辩 量化指标报告 + 展示PPT + 技术文档
🏗️ L2 系统架构:「工业边缘传感网络」
┌──────────────────────────────────────────────────────────────────┐ │ PC PyQt5 工业监控面板 │ │ 仪表盘 │ 6通道实时曲线 │ PID 控制面板 │ 3D 姿态球 │ FFT 频谱瀑布图 │ 远程控制 │ └───────────────────────┬──────────────────────────────────────────┘ │ WiFi (MQTT over TCP) ┌───────────────────────▼──────────────────────────────────────────┐ │ 汇总节点(边缘网关)STM32F407 ① │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ FreeRTOS 6 任务: │ │ │ │ ① Task_SensorPoll (高) Modbus RTU 主机轮询采集节点 │ │ │ │ ② Task_DataFusion (中) 卡尔曼滤波 + 互补滤波 + 数据融合 │ │ │ │ ③ Task_FFT (中) ADC DMA 双缓冲 → 1024点 FFT 频谱 │ │ │ │ ④ Task_PIDCtrl (高) PID 闭环 → PWM 舵机 + L298N 风扇 │ │ │ │ ⑤ Task_OLEDMenu (低) OLED 显示 + 按键菜单切换 │ │ │ │ ⑥ Task_WiFiReport (中) MQTT 打包上报 → ESP8266 → PC │ │ │ │ ⑦ Task_Watchdog (最高) IWDG + 任务心跳监控 + HardFault捕获 │ │ │ └─────────────────────────────────────────────────────────────┘ │ └───────────────────────┬──────────────────────────────────────────┘ │ Modbus RTU over UART (TX/RX 交叉直连) ┌───────────────────────▼──────────────────────────────────────────┐ │ 采集节点 STM32F407 ② │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ FreeRTOS 4 任务: │ │ │ │ ① Task_SensorAcq (高) BH1750/DS18B20/光敏/MPU6050/HC-SR04 │ │ │ │ ② Task_ADCDMA (高) ADC DMA 双缓冲高速采样 │ │ │ │ ③ Task_ModbusSlave(中) Modbus RTU 从机 → 响应主机查询 │ │ │ │ ④ Task_Alert (低) 蜂鸣器 + LED 本地告警 │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ 传感器:BH1750(I²C) MPU6050(I²C) DS18B20(OneWire) 光敏(ADC) HC-SR04(GPIO) │ └──────────────────────────────────────────────────────────────────┘
💡 与 L1 的关键变化:
① L1 的 HC-05 蓝牙透传 → L2 升级为 Modbus RTU 工业总线(直接用 UART TX/RX 交叉直连两块 F407,不新增硬件)
② L1 的 ESP8266 AT 透传 → L2 升级为 MQTT 协议(Topic 发布/订阅,支持双向通信——PC 可下发控制指令)
③ L1 的裸机大循环 → L2 全部改造为 FreeRTOS 多任务(消息队列+信号量+互斥量+软件定时器)
④ L1 只读原始传感器值 → L2 加入 卡尔曼滤波、互补滤波、FFT、PID 一整条 DSP 处理链
⑤ L1 的 matplotlib 脚本 → L2 升级为 PyQt5 工业监控面板(仪表盘+实时曲线+3D球+频谱图+控制面板)
🧵 FreeRTOS 任务映射关系

汇总节点(边缘网关)— 7 个任务

任务名优先级栈大小触发方式功能从 L1 迁移来源
Task_Watchdog最高(5)256B1s 定时IWDG 喂狗 + 各任务心跳计数 + HardFault 异常捕获与日志L1 基础 IWDG → 升级为多任务监控
Task_SensorPoll高(4)1024B20ms 定时Modbus RTU 主机:轮询采集节点寄存器,CRC16 校验,超时重试L1 蓝牙接收逻辑 → 改为 Modbus 查询
Task_PIDCtrl高(4)1024B消息队列触发PID 计算(温度/光照)→ PWM 输出(SG90 舵机角度 + L298N 风扇转速)新增
Task_DataFusion中(3)2048B消息队列触发卡尔曼滤波(温度) + 互补滤波(MPU6050 欧拉角) + 数据融合打包新增
Task_FFT中(3)4096BDMA 完成信号量ADC DMA 双缓冲 1024 点采集 → CMSIS-DSP arm_rfft_f32 → 提取主频 & 谐波新增
Task_WiFiReport中(2)2048B100ms 定时MQTT 协议打包(JSON)→ ESP8266 AT 命令发送 → 接收 PC 下发指令L1 WiFi 透传 → 升级为 MQTT
Task_OLEDMenu低(1)1024B200ms 定时OLED 多页面显示(主页面 / 传感器详情 / 通信状态 / PID参数) + 按键切换L1 OLED 显示逻辑

采集节点 — 4 个任务

任务名优先级栈大小触发方式功能
Task_SensorAcq高(4)2048B50ms 定时5 传感器轮询:BH1750(I²C) + DS18B20(OneWire) + 光敏(ADC) + MPU6050(I²C) + HC-SR04(GPIO中断+定时器)
Task_ADCDMA高(4)1024BDMA 完成信号量ADC DMA 双缓冲连续采样(光敏电阻振动信号),供 FFT 分析
Task_ModbusSlave中(3)1024BUART 中断触发Modbus RTU 从机:解析主机命令 → 填充寄存器 → CRC16 应答
Task_Alert低(1)512B消息队列触发本地告警:温度超阈值→蜂鸣器响,传感器故障→红灯闪烁,通信超时→蓝灯闪烁

任务间通信机制

通信对象类型流向数据内容
Queue_SensorData消息队列SensorPoll → DataFusion → PIDCtrl传感器原始值结构体(温度/光照/距离/姿态/ADC值)
Queue_FFTResult消息队列FFT → WiFiReport频谱峰值频率 + 幅值 + 时间戳
Sem_DMADone二值信号量ADC DMA ISR → Task_FFTDMA 传输完成信号
Mutex_I2C互斥量BH1750/MPU6050/OLED 共享保护 I²C1 总线互斥访问
Timer_ModbusPoll软件定时器系统 → Task_SensorPoll20ms 周期 Modbus 轮询
Timer_WiFiReport软件定时器系统 → Task_WiFiReport100ms 周期 MQTT 上报
Queue_Alert消息队列各任务 → Task_Alert告警类型 + 告警等级 + 传感器ID
🧵 阶段1:FreeRTOS 内核(Day 1—6)

策略:不重新设计新任务,而是将 L1 裸机代码逐步重构进 FreeRTOS 框架。学生已熟悉 L1 的传感器驱动,精力集中在任务设计、同步和通信上。

Day 1

FreeRTOS 入门 + 第一个多任务程序

  • FreeRTOS 概念:任务、调度器、优先级、时间片
  • PlatformIO 集成 FreeRTOS:在 platformio.ini 中启用 FreeRTOS 中间件
  • 创建两个简单任务:TaskA 闪红灯(1Hz)、TaskB 闪蓝灯(3Hz)
  • 观察两个任务并发运行效果,与裸机顺序执行对比
  • 用 Claude Code 交互学习 FreeRTOS API:xTaskCreate / vTaskDelay / vTaskStartScheduler
Day 2

任务优先级 + 抢占调度实验

  • 理解 FreeRTOS 抢占式调度:高优先级任务就绪立即抢占低优先级
  • 实验:创建3个不同优先级的任务,串口打印切换顺序
  • 任务状态:Running / Ready / Blocked / Suspended
  • 实验:用 vTaskSuspend / vTaskResume 手动控制任务启停
  • 迁移 L1 代码:将 LED 流水灯逻辑从裸机 main() 抽离为独立 Task_LED
Day 3

消息队列(Queue)

  • 消息队列原理:生产者→队列→消费者,FIFO 缓冲
  • 实验:Task_SensorSim 模拟产生温度数据 → 队列 → Task_Display 串口打印
  • 队列满/空的阻塞处理:xQueueSendxQueueReceive 的超时参数
  • 迁移 L1 代码:将 DS18B20 温度读取和 OLED 显示拆分为两个任务,通过队列传递温度值
  • 对比:裸机时代"读完直接显示" vs RTOS 时代"读到→丢队列→显示任务自己去取"
Day 4

信号量(Semaphore)+ 互斥量(Mutex)

  • 二值信号量:中断 → 任务的同步机制(如 DMA 完成中断释放信号量,任务获取后处理数据)
  • 计数信号量:管理多个相同资源(如多个 DMA 缓冲区)
  • 互斥量:保护共享资源——I²C1 总线被 BH1750/MPU6050/OLED 三个任务共享
  • 优先级反转问题 + 互斥量的优先级继承机制
  • 实验:两个任务同时通过同一个 I²C 总线读写不同传感器,不加/加互斥量对比
Day 5

软件定时器 + 中断管理

  • 软件定时器 vs 硬件定时器:FreeRTOS 软件定时器基于 SysTick,精度为 tick 周期(通常1ms)
  • 实验:用软件定时器实现周期性传感器轮询(替代 L1 的 HAL_TIM 定时中断)
  • FreeRTOS 中断管理:FromISR 系列 API(xQueueSendFromISR 等)
  • 中断优先级:FreeRTOS 可管理的中断优先级范围(≤ configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
  • 迁移 L1 代码:将 L1 的 UART 接收中断改为 FreeRTOS 中断安全版本
Day 6

FreeRTOS 综合实战 + 任务栈分析

  • 将 L1 采集节点 5 传感器驱动全部迁入 FreeRTOS 任务框架
  • 使用 uxTaskGetStackHighWaterMark 检查每个任务的剩余栈空间
  • 使用 vTaskList 打印任务运行状态表(名称/状态/优先级/剩余栈/任务号)
  • 实验:人为制造栈溢出(分配过小栈空间),观察 FreeRTOS 栈溢出 Hook 回调
  • 阶段1 验收标准:采集节点 4 任务 + 汇总节点 6 任务框架搭建完毕,串口打印任务运行状态正常
🔌 阶段2:工业通信协议(Day 7—12)

此阶段将 L1 的蓝牙透传和 WiFi AT 透传升级为工业标准协议栈。所有通信走 UART 直连(不新增 RS-485/CAN 硬件),但协议层面完全模拟工业总线行为。

Day 7

Modbus RTU 协议原理 + 帧结构实现

  • Modbus 协议体系:RTU / ASCII / TCP 三种变体,本课程学 RTU
  • 帧结构:地址码(1B) + 功能码(1B) + 数据区(N B) + CRC16(2B)
  • 功能码:03(读保持寄存器)、06(写单个寄存器)、10(写多个寄存器)
  • CRC16 查表法实现:用 Claude Code 生成 CRC16-Modbus 校验函数
  • 实验:PC 串口助手发 Modbus RTU 帧 → STM32 解析 → LED 响应
Day 8

Modbus 从机实现(采集节点)

  • 在采集节点 FreeRTOS 框架中实现 Task_ModbusSlave
  • 传感器数据寄存器映射:温度(0x0000)、光照(0x0002)、ADC电压(0x0004)、加速度XYZ(0x0006-0x000B)、欧拉角(0x000C-0x0011)、超声波距离(0x0012)、心跳(0x0014)
  • 错误处理:非法功能码(0x01)、非法数据地址(0x02)异常码响应
  • UART 空闲中断 + 定时器实现帧间隔检测(Modbus RTU 要求 ≥3.5字符间隔)
  • 验证:汇总节点通过 UART 发 Modbus 查询 → 采集节点回寄存器数据 → 串口打印验证
Day 9

MQTT 协议原理 + ESP8266 AT 固件升级

  • MQTT 协议核心概念:Broker(服务器)、Topic(主题)、Publish/Subscribe(发布/订阅)、QoS(0/1/2)
  • 免费 MQTT Broker:EMQX Public Broker(broker.emqx.io:1883)或本地 Mosquitto
  • ESP8266 AT 固件确认:检查 AT 版本 ≥1.7(支持 MQTT AT 指令)
  • MQTT AT 指令:AT+MQTTUSERCFG / AT+MQTTCONN / AT+MQTTPUB / AT+MQTTSUB
  • 实验:STM32 发 AT 命令让 ESP8266 连接 WiFi + 连接 MQTT Broker + 发布一条消息
Day 10

MQTT 数据上报 + PC 端接收

  • 汇总节点 Task_WiFiReport:传感器数据 → JSON 序列化 → MQTT Publish
  • Topic 设计:sensor/temp / sensor/light / sensor/imu / sensor/distance / sensor/status
  • PC 端用 Python paho-mqtt 库订阅所有 Topic,验证数据接收
  • 下行控制:cmd/pid(PID 设定值)/ cmd/led(远程控制LED)
  • 实验:PC 通过 MQTT 发布 cmd/led → 汇总节点接收 → LED 亮灭响应
Day 11

自定义应用层协议设计

  • 学会从零设计一个健壮的二进制帧协议:
  • 帧头(2B: 0xA5 0x5A) + 数据长度(2B) + 帧类型(1B) + 源地址(1B) + 目标地址(1B) + 序列号(2B) + 数据载荷(N B) + CRC16(2B) + 帧尾(1B: 0x0D)
  • 帧类型定义:0x01=传感器数据 / 0x02=控制指令 / 0x03=心跳 / 0x04=ACK应答 / 0x05=NACK否定应答
  • 状态机实现:WAIT_HEADER1 → WAIT_HEADER2 → WAIT_LENGTH → WAIT_DATA → CHECK_CRC → WAIT_TAIL
  • 对比:Modbus RTU vs MQTT vs 自定义协议,各适合什么场景
Day 12

协议联调 + 通信性能测试

  • 全协议栈联调:采集节点(Modbus从机) → 汇总节点(Modbus主机+MQTT客户端) → PC(MQTT订阅)
  • 测试 Modbus 轮询周期稳定性(目标 20ms ±2ms)
  • 测试 MQTT 端到端延迟(传感器读数变化 → PC 收到主题消息)
  • 通信异常测试:UART 断开重连、WiFi 断网重连、MQTT Broker 掉线重连
  • 阶段2验收标准:Modbus + MQTT 双协议全链路稳定运行 ≥ 30分钟无丢帧

📋 Modbus RTU 寄存器映射表(采集节点从机,地址=0x01)

寄存器地址内容数据类型单位 / 分辨率访问
0x0000-0x0001温度(DS18B20)int16(×100)0.01°C只读(03)
0x0002-0x0003光照度(BH1750)uint161 lux只读(03)
0x0004-0x0005光敏 ADC 电压uint16(×1000)1 mV只读(03)
0x0006-0x0007加速度 X 轴(MPU6050)int16(×100)0.01 g只读(03)
0x0008-0x0009加速度 Y 轴int16(×100)0.01 g只读(03)
0x000A-0x000B加速度 Z 轴int16(×100)0.01 g只读(03)
0x000C-0x000D欧拉角 Rollint16(×100)0.01°只读(03)
0x000E-0x000F欧拉角 Pitchint16(×100)0.01°只读(03)
0x0010-0x0011欧拉角 Yawint16(×100)0.01°只读(03)
0x0012-0x0013超声波距离uint161 mm只读(03)
0x0014-0x0015ADC DMA 采样值(供 FFT)uint16原始 ADC 值只读(03)
0x0016心跳/状态字uint16(bit0-15)bit0=运行 bit1=传感器故障 bit2=通信超时只读(03)
0x0017PID 设定值(温度)uint16(×100)0.01°C读写(03/06)

📡 MQTT Topic 设计

Topic方向QoS内容示例
sensor/temp汇总→PC1{"value":25.68,"unit":"C","ts":1623456789}
sensor/light汇总→PC1{"value":325,"unit":"lux","ts":1623456790}
sensor/imu汇总→PC1{"roll":12.5,"pitch":-3.2,"yaw":178.1,"ts":1623456791}
sensor/distance汇总→PC0{"value":150,"unit":"mm","ts":1623456792}
sensor/fft汇总→PC1{"peak_freq":123.5,"amplitude":0.87,"ts":1623456793}
sensor/pid汇总→PC1{"setpoint":30.0,"actual":29.6,"output":0.45,"ts":1623456794}
sensor/status汇总→PC0{"uptime":3600,"free_heap":32768,"err_cnt":0,"ts":1623456795}
cmd/pidPC→汇总1{"target_temp":30.0,"kp":2.5,"ki":0.3,"kd":0.1}
cmd/ledPC→汇总1{"led":1,"state":true}
cmd/servoPC→汇总1{"angle":90}
MQTT Broker 选择:实训期间推荐使用 EMQX Public Broker(broker.emqx.io,免费公网测试服务),TCP 端口 1883,WebSocket 端口 8083。如果实验室网络不稳定,可在教师电脑上用 Docker 一键部署本地 Mosquitto:
docker run -d --name mosquitto -p 1883:1883 -p 9001:9001 eclipse-mosquitto
📊 阶段3:DSP 信号处理(Day 13—18)

L2 技术含量最高的阶段。利用 F407 的 FPU(单精度浮点运算单元)CMSIS-DSP 库,将数字信号处理算法落地到嵌入式平台。每个算法先用官方库跑通,再对比手写版本性能差异。

Day 13

FPU 使能 + CMSIS-DSP 库集成

  • 确认 F407 FPU 已使能:PlatformIO 中 build_flags = -mfloat-abi=hard -mfpu=fpv4-sp-d16
  • CMSIS-DSP 库导入:从 STM32CubeF4 固件包中提取或 PlatformIO 直接添加依赖
  • 基础运算验证:arm_add_f32 / arm_mult_f32 / arm_mat_mult_f32(3×3矩阵乘法)
  • FPU 性能对比实验:1000 次浮点乘法——硬件 FPU vs 软件浮点(关闭 FPU),测量执行时间差异(预期 FPU 快 5—10 倍)
  • 用 Systick 微秒级计时函数测量算法耗时
Day 14

数字滤波器 — FIR / IIR

  • 滑动平均滤波(最简单的低通滤波,用 Claude Code 手写)
  • 一阶 IIR 低通滤波器:y[n] = α·x[n] + (1-α)·y[n-1],用手写实现
  • CMSIS-DSP FIR 滤波器:arm_fir_init_f32 + arm_fir_f32,设计一个 32 阶低通 FIR
  • 对比实验:ADC 采集电位器信号(叠加手抖动噪声),分别用滑动滤波 / 手写 IIR / CMSIS-DSP FIR 处理,对比滤波前后波形
  • PC 端验证:串口将原始+滤波后数据同时发 PC,用 Python 画三条曲线叠加显示
Day 15

卡尔曼滤波

  • 一维卡尔曼滤波原理(用 Claude Code 学习):预测→更新→迭代
  • 手写一维卡尔曼滤波对 DS18B20 温度数据进行实时滤波
  • 对比实验:同一杯热水冷却过程,原始温度值 vs 滑动滤波 vs 卡尔曼滤波,三条曲线 PC 端叠加显示
  • 调参体验:改变过程噪声协方差 Q 和测量噪声协方差 R,观察滤波效果变化(R 越小越相信测量值,R 越大越平滑但响应慢)
  • 扩展到 MPU6050 加速度数据去噪:单轴一维卡尔曼
  • 理解核心:卡尔曼滤波不是简单的"平滑",而是融合了"系统模型预测"和"传感器测量"的最优估计
Day 16

互补滤波 + 姿态解算

  • 姿态解算问题:加速度计(长期稳定但短时噪声大)+ 陀螺仪(短时精确但长期漂移)→ 两者融合
  • 互补滤波原理:angle = 0.98×(angle + gyro·dt) + 0.02×acc_angle(高通+低通互补)
  • 用加速度计原始数据算 Roll/Pitch:roll = atan2(ay, az) / pitch = atan2(-ax, sqrt(ay²+az²))
  • 陀螺仪积分:angle += gyro_rate × dt
  • 对比实验:加速度计直接算的角度(抖动大)vs 互补滤波后角度(平滑稳定),PC 端双曲线叠加
  • 手持 MPU6050 模块在空中翻转,观察 PC 端欧拉角曲线实时跟踪
Day 17

FFT 频谱分析

  • FFT 原理直觉(Claude Code 解释):时域信号 → 频域分解,看到"有哪些频率成分"
  • ADC DMA 双缓冲高速采集:BufferA 采满 → DMA 自动切到 BufferB → 信号量通知 Task_FFT 处理 BufferA(乒乓缓冲,连续不丢点)
  • 采样率设置:Timer 触发 ADC 在 1kHz 采样,1024 点 → FFT 频率分辨率 = 1kHz / 1024 ≈ 1Hz
  • CMSIS-DSP arm_rfft_fast_f32 做 1024 点实数 FFT,计算各频率幅值 arm_cmplx_mag_f32
  • 提取峰值频率:在频谱中搜索幅值最大的 bin,输出主频 + 二次/三次谐波
  • 核心实验:用手指敲击桌面(连光敏电阻模块 AO 到 ADC)→ FFT 识别敲击主频;不同力度/频率敲击 → 观察频谱峰值移动
  • 验证:用函数信号发生器或手机 App 产生已知频率声音/振动 → FFT 测量值与已知值对比,误差应 < 2Hz
Day 18

PID 闭环控制

  • PID 控制原理:P(比例)快速响应 + I(积分)消除静差 + D(微分)抑制超调
  • 位置式 PID vs 增量式 PID 对比
  • 实验1 — 温度闭环控制:DS18B20 测温 → PID 计算 → PWM 控制 L298N 驱动风扇(模拟加热/制冷)
  • 实验2 — 光照闭环控制:BH1750 测光 → PID 计算 → PWM 控制 LED 亮度
  • PID 参数手动调优实验(经典的 Ziegler-Nichols 方法):
  • ① 先设 Ki=Kd=0,逐步增大 Kp 直到系统出现等幅振荡 → 记下临界增益 Ku 和振荡周期 Tu
  • ② 查表计算 Kp/Ki/Kd → 微调观察超调、调节时间、稳态误差变化
  • PC 端实时显示设定值 vs 实际值双曲线(红色=设定/蓝色=实际),PID 收敛过程可视化
  • 阶段3验收标准:每个算法独立 Demo 可运行,PC 端可视化对比验证效果
🔗 阶段4:系统重构 — 全栈整合(Day 19—24)

前三个阶段各自独立验证后,此阶段将 FreeRTOS + Modbus + DSP + MQTT + PyQt5 全部整合为一个完整系统。

Day 19

采集节点全功能重构

  • 整合 FreeRTOS 4 任务框架 + Modbus 从机 + 数字滤波(FIR/IIR 对 ADC 数据实时滤波)
  • 传感器数据先滤波再存入 Modbus 寄存器(滤波在 Task_SensorAcq 中完成)
  • ADC DMA 双缓冲:BufferA/BufferB 乒乓切换,供远端 FFT(通过 Modbus 寄存器 0x0014 读取原始 ADC)
  • Modbus 从机通信鲁棒性:CRC 错误 → 不响应;地址不匹配 → 静默忽略;功能码不支持 → 返回异常码
  • 测试:汇总节点连续轮询 1000 次,记录应答率 ≥ 99.9%
Day 20

汇总节点重构(数据链路)

  • 整合 FreeRTOS 7 任务框架 + Modbus 主机 + 数据融合通道
  • 数据流:Modbus 轮询 → Queue_SensorData → Task_DataFusion(卡尔曼+互补滤波)→ Queue_SensorData → Task_WiFiReport(MQTT 上报)
  • OLED 多页面:Page1=传感器数值 / Page2=通信状态(轮询周期/丢包) / Page3=PID参数 / 按键短按切换页面,长按进入设置
  • 先不接入 FFT 和 PID,确保数据链路(采集→Modbus→融合→MQTT→PC)畅通
Day 21

汇总节点重构(DSP + 控制链路)

  • 加入 Task_FFT:ADC DMA 双缓冲 → 1024 点 FFT → 峰值频率提取 → 结果入队
  • 加入 Task_PIDCtrl:从消息队列获取传感器数据 → PID 计算 → PWM 输出(舵机角度 + 风扇占空比)
  • 所有 7 个任务同时运行,重点检查:
  • uxTaskGetStackHighWaterMark 检查每个任务栈余量 ≥ 20%
  • ② 优先级反转检查:低优先级任务持有互斥量时,高优先级任务是否被阻塞
  • ③ 消息队列是否溢出(生产快于消费)→ 增大队列深度或降低生产者频率
  • 使用 vTaskGetRunTimeStats 查看每个任务的 CPU 占用率
Day 22

PC PyQt5 工业监控面板开发

  • 用 Claude Code 生成完整的 PyQt5 工业监控面板代码(6 大模块)
  • 模块1:实时数据仪表盘 — 圆形温度表盘 + 光照进度条 + 距离数字 + 姿态角数字显示
  • 模块2:6 通道实时曲线 — pyqtgraph 实现高性能滚动波形(温度/光照/ADC电压/距离/Roll/Pitch),支持鼠标缩放和暂停
  • 模块3:PID 控制面板 — 设定值滑条 + P/I/D 参数输入框 + 设定值 vs 实际值双曲线(红vs蓝)
  • 模块4:3D 姿态球 — PyOpenGL 渲染,MPU6050 欧拉角驱动球体实时旋转
  • 模块5:FFT 频谱瀑布图 — 横轴频率/纵轴时间/颜色幅值(类似专业频谱仪),最新频谱显示在底部
  • 模块6:控制与报警 — LED/舵机远程控制按钮 + 温度超阈值红色闪烁 + 事件日志列表
  • 数据源:paho-mqtt 订阅 MQTT Topic(主通道)+ pyserial 串口(备用通道)
Day 23

全链路联调

  • 端到端打通:采集节点(传感器) → Modbus RTU(UART) → 汇总节点(FreeRTOS 7任务) → MQTT(WiFi) → PC PyQt5 面板
  • 验证 6 大面板模块全部接收实时数据
  • 测试双向通信:PC PyQt5 下发 PID 设定值 → MQTT → 汇总节点 → PID 执行 → 实际值变化反馈到 PC 面板
  • 测试闭环控制回路:PC 拖动设定值滑条 → 5 秒内观察实际值曲线追踪设定值
  • 记录端到端延迟:传感器值变化 → PC 面板刷新(目标 < 200ms)
  • 记录发现的所有问题(为 Day 25 性能优化做准备)
Day 24

异常处理 + 鲁棒性加固

  • 通信超时重连:Modbus 轮询连续 3 次无应答 → 复位通信状态机 → 重新建连
  • WiFi/MQTT 断线恢复:Task_WiFiReport 检测 MQTT 连接状态 → 断线自动重连 Broker + 重新订阅 Topic
  • 传感器热插拔:I²C 设备无应答(HAL_I2C_IsDeviceReady 返回错误)→ 标记故障 → Task_Alert 告警 → 定期尝试恢复
  • 栈溢出 Hook:实现 vApplicationStackOverflowHook,栈溢出时记录出问题的任务名和栈地址到备份寄存器(复位后仍可读取)
  • HardFault 异常捕获:实现 HardFault_Handler,读取 stacked PC/LR/SP 寄存器值,通过串口打印崩溃现场(类似 Linux kernel panic 信息),用 Claude Code 辅助分析崩溃原因
  • 阶段4验收标准:全链路运行正常,PyQt5 面板 6 模块全部有数据,双向控制可工作
🎯 阶段5:性能优化 + 成果展示(Day 25—30)

最后阶段聚焦于量化指标的测量与优化,以及可观赏性强的展示内容准备

Day 25

性能基准测试 + 优化

  • Modbus 轮询效率:测量 3 次连续轮询总时间 → 目标 < 20ms(修改波特率或减少寄存器读取量优化)
  • MQTT 上报频率:测量从数据入队到 ESP8266 发出 MQTT Publish 的延迟 → 目标 < 50ms
  • FFT 运算速度:测量 arm_rfft_fast_f32(1024点)的耗时 → 目标 < 3ms(FPU 加速下应 < 1ms)
  • PID 控制周期:测量从传感器读数到 PWM 输出的闭环延迟 → 目标 < 10ms
  • 记录所有指标到基准测试表,分析瓶颈(CPU/内存/通信带宽)
Day 26

长期稳定性测试

  • 连续运行 2—4 小时,记录:
  • ① 数据刷新率稳定性(每 10 分钟采样一次刷新率,标准差 < 5%)
  • ② 通信丢包率(Modbus 总查询次数 / 无应答次数)
  • ③ 内存泄漏检查:每 30 分钟读取 xPortGetFreeHeapSize,绘制剩余堆内存曲线
  • ④ 任务栈余量变化(uxTaskGetStackHighWaterMark 的谷值)
  • ⑤ 传感器读数漂移(MPU6050 陀螺仪零偏在 2 小时内的变化)
  • 人为注入故障:拔掉传感器 I²C 线 → 观察系统恢复时间 → 优化恢复逻辑
Day 27

展示效果打磨

  • PID 收敛演示:在 PC 面板上展示"改变设定值→实际值追踪"的完整过程,确保双曲线动态效果好
  • 3D 姿态球演示:手持 MPU6050 翻转,确认姿态球丝滑跟随无卡顿
  • FFT 频谱演示:连续敲击桌面不同频率,观察频谱瀑布图变化,确保峰值清晰可见
  • Modbus 通信演示:在 OLED 上实时显示轮询周期和丢包率,展示通信质量
  • 报警演示:遮挡光敏电阻或将 DS18B20 靠近热源 → PC 面板红色闪烁 + 蜂鸣器报警
  • 整体演示流畅度编排:按照"数据展示→PID控制→3D姿态→FFT分析→报警"自然流程串联
Day 28

代码审查 + 文档撰写

  • 用 Claude Code 对全部代码做审查:指出潜在 bug、内存泄漏风险、未初始化变量、中断安全违规
  • Git 整理:合并临时 commit → 打 tag v2.0-rc1 → 冻结展示版本
  • 撰写技术文档(不少于 2000 字):
    系统架构设计 / FreeRTOS 任务设计理由 / Modbus 寄存器映射表 / MQTT Topic 设计说明 / DSP 算法选型与对比 / PID 调参过程记录 / 性能基准测试结果 / 已知问题和改进方向
  • 代码注释补全,确保后人能看懂
Day 29

展示准备 — PPT + 演示脚本

  • 制作展示 PPT(15—20 页):
    ① 封面(项目名/姓名/日期) ② 项目背景与目标 ③ L1→L2提升对比 ④ 系统架构总图 ⑤ FreeRTOS 任务设计 ⑥ Modbus 寄存器映射 ⑦ MQTT Topic 设计 ⑧ DSP 算法链(滤波→卡尔曼→FFT→PID) ⑨ PyQt5 面板截图 ⑩ PID调参过程实验数据 ⑪ 性能基准测试结果 ⑫ 稳定性测试数据 ⑬ 实物照片 ⑭ 技术难点与解决方案 ⑮ 个人收获与总结 ⑯ 致谢
  • 演示脚本编排(8 分钟流畅演示):
  • 第1分钟:系统整体介绍 + 实物展示
  • 第2-3分钟:PC PyQt5 面板 6 模块逐一展示(数据仪表盘→实时曲线→3D姿态球→FFT频谱→PID面板→控制与报警)
  • 第4-5分钟:PID 闭环控制演示(拖动设定值滑条,观察实际值追踪过程)
  • 第6-7分钟:FFT 频谱分析演示(敲击桌面不同频率,观察频谱峰值变化)
  • 第8分钟:性能数据展示(量化指标汇总表)+ 技术问答
Day 30

最终展示 + 成果提交

  • 上午:正式作品展示 + 技术答辩
  • 下午:提交最终交付物
  • ① 完整源码(Git 仓库,含清晰的 commit 历史)
  • ② 技术文档(PDF,≥2000 字)
  • ③ 展示 PPT(15—20 页)
  • ④ 演示录屏视频(8 分钟,含语音解说)
  • ⑤ 量化指标报告(系统各项性能数据汇总)
  • ⑥ PC PyQt5 面板可执行文件(pyinstaller 打包成 .exe)
  • 打 tag v2.0-release
  • 训练营结业
📏 结题量化指标(验收标准)

以下指标在 Day 25 性能测试阶段逐项测量,Day 30 展示答辩时向评委公开。所有指标均有明确的目标值测量方法,不可模糊评价。

编号指标目标值测量方法展示方式
Q1 Modbus RTU 轮询周期 ≤ 20ms(3 从机数据) OS 定时器打时间戳,计算两次 Modbus 查询间隔 OLED 实时显示 + PC 面板
Q2 Modbus 通信丢包率 ≤ 0.1%(1000 次查询) 主机计数:发送次数 vs 收到有效应答次数 量化指标报告
Q3 MQTT 端到端延迟 ≤ 200ms(传感器变化→PC显示) STM32 发送时间戳 → PC 接收时间戳差值 PC 面板状态栏
Q4 1024 点 FFT 运算耗时 ≤ 3ms(FPU 加速) SysTick 微秒计时:arm_rfft_f32 前后时间戳差 串口打印 + PC 面板
Q5 FFT 频率分辨率 ≤ 1Hz(@ 1kHz 采样率) 已知频率输入(如手机 App 产生 440Hz 正弦波)→ FFT 测量值与真实值对比 FFT 频谱瀑布图 + 报告
Q6 PID 温度控制稳态误差 ≤ ±0.3°C 设定值 30°C → 系统稳定后,2 分钟内实际值偏差范围 PID 面板双曲线(设定值 vs 实际值)
Q7 PID 阶跃响应调节时间 ≤ 15 秒(设定值 25→30°C) 从拖动滑条改变设定值开始,到实际值首次进入 ±0.5°C 范围的时间 PID 面板双曲线 + 调节时间标注
Q8 MPU6050 姿态角精度 Roll/Pitch 误差 ≤ 1°(静态) 互补滤波后角度 vs 手机水平仪 App 读数对比 3D 姿态球 + 数字显示
Q9 姿态解算刷新率 ≥ 100Hz Task_DataFusion 中姿态计算循环计数,每秒统计 PC 面板 3D 球更新频率
Q10 系统连续稳定运行 ≥ 4 小时不死机/不重启 IWDG 未触发复位 + 任务心跳计数递增正常 PC 面板运行时长显示
Q11 FreeRTOS CPU 占用率 ≤ 70%(所有任务总和) vTaskGetRunTimeStats 统计各任务 CPU 时间占比 量化指标报告
Q12 内存剩余(Free Heap) ≥ 20KB(总 192KB SRAM) xPortGetFreeHeapSize 在运行 30 分钟后读取 OLED 显示 + PC 面板
⚠️ 量化指标的重要性:竞赛评分和答辩中,有数据支撑的结论远比主观描述有说服力。例如 "我们的系统很稳定" vs "我们的系统连续运行 4 小时零死机,通信丢包率 0.05%",后者是评委希望看到的工程化表达方式。
🖥️ PC PyQt5 工业监控面板 — 技术规格
模块使用库功能观赏性
1. 实时数据仪表盘 PyQt5 QPainter 自绘或 qwt 圆形温度表盘(0—50°C,指针+数字)
光照进度条(0—1000 lux,颜色渐变)
距离数字显示(mm)
姿态角 Roll/Pitch/Yaw 数字(°)
★★★
2. 6 通道实时曲线 pyqtgraph 6 条曲线同屏滚动显示(温度/光照/ADC/距离/Roll/Pitch)
支持鼠标框选缩放、右键复位、空格暂停
Y 轴自适应范围
X 轴显示最近 30 秒数据(滚动窗口)
★★★★
3. PID 控制面板 PyQt5 + pyqtgraph 设定值横向滑条(温度 0—50°C)
P/I/D 参数输入框(带 SpinBox 微调)
设定值(红色)vs 实际值(蓝色)双曲线
调节时间/超调量/稳态误差 实时计算并显示
"参数下发"按钮 → MQTT 发送 PID 参数到汇总节点
★★★★★
4. 3D 姿态球 PyOpenGL 球体 + 经纬线 + 坐标系箭头(RGB = XYZ)
MPU6050 欧拉角驱动球体实时旋转
下方显示 Roll/Pitch/Yaw 数值
★★★★★
5. FFT 频谱瀑布图 pyqtgraph ImageView 或 matplotlib 横轴 = 频率(0—500Hz)
纵轴 = 时间(从上到下,最新在底部)
颜色 = 幅值(蓝=低→红=高,热力图色阶)
右侧显示当前帧峰值频率 + 幅值
★★★★★
6. 控制与报警 PyQt5 LED1/LED2 远程开关按钮
舵机角度滑条(0—180°)
温度超阈值报警:红色闪烁 + 蜂鸣
事件日志列表(时间戳 + 事件类型 + 内容)
系统运行时长显示
★★★
💡 开发方式:全部 6 个模块的 PyQt5 代码由 Claude Code 生成。学生在 VS Code 终端中描述需求 → Claude Code 输出完整 Python 代码 → 复制到本地 .py 文件 → 运行验证 → 根据效果再让 AI 调整。整个过程学生关注的是"我要什么效果""如何集成到系统中",而非手动编写 Qt 代码。最终面板用 pyinstaller 打包为独立 .exe 文件,方便展示时在任何 Windows 电脑上运行。
📋 附录一:L2 学生每日工作流(SOP)
时间任务
8:30—9:00开 VS Code,回顾昨天代码和笔记。在终端输入当日目标给 Claude Code,获取今日开发建议
9:00—11:30新知识学习 + 代码编写。L2 阶段更依赖 Claude Code 做深度技术问答(如 "请解释 FreeRTOS 的优先级反转问题" / "帮我分析这段卡尔曼滤波的 Q 和 R 矩阵设置是否合理")
11:30—12:00开发笔记更新:记录今日理解的核心概念、踩坑记录、性能数据
13:30—16:30动手实验 + 系统联调。L2 的重心在软件调试(FreeRTOS 任务堆栈分析、DSP 算法精度验证、通信协议状态机排查)
16:30—17:00Git 提交当日代码,写有意义的 commit message(如 "feat: 完成 Modbus 从机 CRC16 校验和异常码响应")
17:00—17:30回顾当日成果,记录未解决的问题。用 Claude Code 做代码审查("请审查今天的代码改动,指出潜在问题")
📋 附录二:Claude Code L2 进阶提问模板

FreeRTOS 相关

claude "我的 FreeRTOS 任务栈溢出了,uxTaskGetStackHighWaterMark 返回 0。请帮我分析可能的原因并给出解决方案"

claude "我有 6 个 FreeRTOS 任务,请帮我设计合理的优先级分配方案,避免优先级反转"

claude "请审查我的 FreeRTOS 中断服务函数,检查是否有不符合 FromISR API 规范的地方"

通信协议相关

claude "请帮我写一个 Modbus RTU CRC16 查表法的 C 语言实现,用于 STM32F407"

claude "我的 Modbus 从机偶尔不响应主机查询,可能是什么原因?如何加入调试日志定位问题?"

claude "请解释 MQTT QoS 0/1/2 的区别,并帮我在 ESP8266 AT 固件上实现 QoS 1 的消息发布"

DSP / 算法相关

claude "请用 C 语言实现一维卡尔曼滤波,用于温度传感器数据去噪,并解释每个参数的含义"

claude "我在 STM32F407 上用 arm_rfft_fast_f32 做 1024 点 FFT,但频谱结果不对。请帮我检查代码"

claude "我的 PID 温度控制出现明显的超调和震荡,请帮我分析是 P/I/D 哪个参数的问题,并指导如何调优"

PyQt5 相关

claude "请帮我用 PyQt5 和 pyqtgraph 创建一个 6 通道实时曲线显示窗口,数据通过 MQTT 接收"

claude "请用 PyOpenGL 在 PyQt5 窗口中创建一个 3D 球体,根据实时欧拉角旋转,球体上要画经纬线和坐标系箭头"

claude "请用 pyinstaller 把我的 PyQt5 工程打包成一个独立的 Windows .exe 文件"
📋 附录三:L2 新增软件库与工具
库/工具用途安装方式
FreeRTOS实时操作系统内核PlatformIO 内置,platformio.ini 中启用
CMSIS-DSP数字信号处理库(FIR/IIR/FFT/矩阵/数学)从 STM32CubeF4 固件包提取,或 PlatformIO 添加依赖
paho-mqttPython MQTT 客户端库pip install paho-mqtt
PyQt5Python GUI 框架pip install PyQt5
pyqtgraph高性能实时图表库pip install pyqtgraph
PyOpenGLPython OpenGL 绑定(3D 姿态球)pip install PyOpenGL PyOpenGL_accelerate
pyinstallerPython 打包为 .exepip install pyinstaller
EMQX Public Broker免费公网 MQTT 测试服务器无需安装,连接 broker.emqx.io:1883
MQTTXMQTT 桌面调试客户端mqttx.app 下载(调试 MQTT 通信时使用)
Modbus PollModbus 主机调试工具modbustools.com(免费试用版,调试 Modbus 通信)
Serial Oscilloscope串口数据可视化(波形查看)github.com/xioTechnologies/Serial-Oscilloscope(调试 ADC/DSP 算法)