一、项目背景
我参加了 DigiKey 与 EEPW 联合举办的 2026 年第 3 期活动。本期活动主题为“基于边缘 AI 的电机状态检测”。
本帖记录的是NanoEdgeAI电机状态识别数据采集与模型训练。
二、硬件与软件环境
硬件
主控板NUCLEO-C562RE
步进电机Gear Stepper Motor Driver Pack,5 V、四相八拍、1/64
减速加速度计Grove LIS3DHTR 三轴数字加速度计
调试器板载 ST-LINK
电机电源外部 5 V/1 A 以上电源
软件
STM32CubeMX2:配置芯片、时钟及外设
VScode+STM32CubeIDE组件:编译、下载和调试
串口调试助手:查看串口输出
NanoEdge AI Studio:数据采集和模型训练
三、数据采集硬件与参数
三轴加速度传感器通过 I2C1 与 NUCLEO-C562RE 连接。传感器 VCC 接 3.3 V,GND 与开发板共地,SCL 接 PB6,SDA 接 PB7。程序优先使用 I2C 地址 0x19,检测失败时回退到 0x18。初始化时读取 WHO_AM_I 寄存器,只有返回 0x33 才继续配置。
传感器配置为 1.344 kHz 高分辨率模式,启用 X、Y、Z 三轴,启用 BDU,量程设置为 ±2 g。程序从 OUT_X_L 开始连续读取 6 个字节,再按照小端格式解析为 X、Y、Z 三个 int16_t 原始值。
步进电机采用八拍换相。四种状态对应的换相间隔为 STOP 停止输出、SLOW 8 ms、MEDIUM 4 ms、FAST 1 ms,近似步进频率分别为 0、125 步/秒、250 步/秒和 1000 步/秒。上电后默认进入 SLOW,按一次 B1 后状态按照 SLOW、MEDIUM、FAST、STOP、SLOW 的顺序循环。
数据采集使用 USART2 对应的板载 ST-LINK Virtual COM Port。实际设备在 Windows 中显示为 COM3,串口参数为 921600 波特率、8 位数据、无校验、1 位停止位。由于数据量较大,不能使用过低的波特率。
四、NanoEdge 信号格式
NanoEdge 项目中设置:
项目类型:Classification 输入轴数:3 Buffer size:3 × 256 Values separator:space 每个类别行数:200
每条数据包含 256 个采样点和 3 个轴,因此一行必须包含:
256 × 3 = 768 个数值
数值按照采样顺序交错排列:
x1 y1 z1 x2 y2 z2 ... x256 y256 z256
每一行对应一个完整信号窗口,行内使用空格分隔,行末使用 CRLF 换行,文件中不能包含表头、时间戳、类别文字或启动信息。正确的数据形式类似:
160 352 16272 80 320 16080 144 320 16368 ... 208 304 16192
每个状态单独保存为一个文件,文件中只包含该状态的信号窗口。

五、数据采集操作步骤
开始采集前,应先关闭 XCOM、NanoEdge Serial Emulator 等已经占用 COM3 的软件。随后打开 NanoEdge AI Studio,进入 Log signal from serial USB,选择 COM3 和 921600 波特率,勾选 Maximum number of lines,将数量设置为 200。
点击 NanoEdge 的 START 后,再通过开发板 B1 手动选择需要采集的电机状态。采集期间保持电机状态不变,等待 NanoEdge 接收完整的 200 行数据后停止采集并保存文件。完成一个状态后,切换到下一个状态,再重复上述过程。
实际操作顺序为:先连接并上电,确认电机和传感器正常;然后关闭其他串口工具,启动 NanoEdge 串口采集;接着保持 SLOW 状态,采集 200 行并保存;再按 B1 切换到 MEDIUM、FAST 和 STOP,分别采集并保存。四个文件必须是相互独立的类别文件,不能把多个状态混合在同一个文件中。
六、采集结果与数据分析
四个类别最终均采集到 200 行数据,每行 768 列。检查结果如下:
SLOW: 200 行 × 768 列 MEDIUM: 200 行 × 768 列 FAST: 200 行 × 768 列 STOP: 200 行 × 768 列
数据中没有发现 NaN、Inf、全零行或常量行,四类样本数量也保持平衡。各状态 X 轴振动标准差中位数约为:
SLOW: 1786 MEDIUM: 1190 FAST: 1062 STOP: 66
从数据可以看出,电机转动和停止之间存在非常明显的振动差异,三种转速的振动强度也随着速度提高而发生变化。Z 轴数据中包含约 16000 的重力直流分量,这是加速度传感器正常测量到的重力偏置,不需要手动删除。NanoEdge 训练中的 Detrend 和 Normalize 可以处理这种直流偏置和不同轴之间的量纲差异。

七、NanoEdge 模型训练
在 NanoEdge 中新建 Classification 项目,目标板选择 NUCLEO-C562RE,系统会自动识别出 Cortex-M33、128 KB RAM 和 512 KB Flash。输入轴数设置为 3,四个类别分别导入 SLOW、MEDIUM、FAST 和 STOP 数据。

初次 Benchmark 中,Library 45 的结果为:
模型:SVM Quality Index:99.0 pts Balanced Accuracy:100% RAM:0.9 KB Flash:2.6 KB Execution Time:0.1 ms
仅从资源占用来看,这个模型非常适合 STM32C562RE。但 Benchmark 的 100% 准确率只能说明模型能够区分当前训练数据,不能代替实机验证。模型最终能否稳定工作,还取决于窗口划分、采样时序、安装位置和训练数据覆盖范围。

八、模型部署与工程集成
NanoEdge Deployment 页面选择 GNU Arm Embedded GCC,并要求浮点 ABI 和应用工程保持一致。工程实际使用:
-mcpu=cortex-m33 -mfpu=fpv5-sp-d16 -mfloat-abi=hard -fshort-enums
因此 NanoEdge 编译时需要使用 hard-float,并勾选 fshort-enums,不能保持默认的 soft-float 或关闭 short-enums。否则工程和模型库可能因为 ABI 不一致而出现链接异常或运行异常。
生成的 NanoEdgeAI.h 和 libneai.a 放入工程的 nanoedge 目录。CMake 中加入头文件路径、编译选项和静态库:
target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC
${CMAKE_SOURCE_DIR}/nanoedge
)
target_compile_options(${CMAKE_PROJECT_NAME} PUBLIC
-fshort-enums
)
target_link_libraries(${CMAKE_PROJECT_NAME}
${CMAKE_SOURCE_DIR}/nanoedge/libneai.a
)应用代码每采集满 256 个三轴采样点,就把 768 个 int16_t 数据转换为 float,并调用 NanoEdge 分类函数:
for (i = 0U; i < NANOEDGE_VALUES_PER_SIGNAL; i++)
{
nanoedge_input[i] = (float)sensor_window[i];
}
state = neai_classification(
nanoedge_input,
nanoedge_probabilities,
&class_id
);
class_name = neai_get_class_name(class_id);输入数据的顺序必须保持为:
x0 y0 z0 x1 y1 z1 ... x255 y255 z255
分类完成后通过 neai_get_class_name() 获取类别名称,并将串口输出格式设置为:
[AI] state=slow [AI] state=medium [AI] state=fast [AI] state=stop
分类频率约为每 256 ms 输出一次,即约 4 Hz。
九、效果演示
系统上电后默认进入 SLOW,STM32 开始读取三轴加速度数据并缓存窗口。每完成一个窗口,NanoEdge 模型执行一次分类,串口连续输出类别结果。按 B1 后电机状态发生变化,窗口重新开始采集,避免一个窗口内混合两个状态。
当前系统已经完成从加速度采集、768 列窗口生成、模型调用到串口输出的完整链路。使用 NanoEdge 生成库中的本地模拟器,可以加载 libneai.dll 或 libneai.so,对采集文件进行离线回放,验证模型输出与类别名称是否对应。



十、总结
本项目完成了从三轴加速度采集、NanoEdge 数据格式设计、四分类数据采集、Benchmark、模型部署到 STM32 串口输出的完整流程。工程中使用的模型资源很小,能够满足 STM32C562RE 的实时运行要求。
实机调试也说明,边缘 AI 不能只关注 Benchmark 的 100% 准确率。训练窗口是否覆盖不同相位、采样和电机换相是否同步、训练数据是否来自单次连续采集,都会影响最终效果。通过相位增强数据、频谱和统计特征以及独立验证集,可以进一步提高模型在不同启动时刻和不同窗口相位下的稳定性。


我要赚赏金
