工序自动识别与匹配模式

1. 缘起:从“人工配置”到“智能感知”

在传统的工业物联网(IIoT)设备开发中,最头疼的往往不是通信协议,而是现场适配
一台数据采集终端,接在平缝机上是一种信号逻辑(压脚->剪线),接在包缝机上又是另一种逻辑。以往我们需要技术人员拿着说明书,现场拨码开关或者进入后台配置页面手动选择“工作模式”。

有没有一种可能,让 MCU 自己去“看”一眼传感器的数据,就自动明白自己处在什么工序中?

这就是我在工程中引入工序数据采集匹配模式的初衷。


2. 数据的基石:结构化事件流

要识别模式,首先要定义什么是“数据”。对于缝纫机等自动化设备,核心动作无非是 GPIO 的电平跳变和电机转速的变化。
我定义了一个能够描述最小动作单元的结构体 port_change_event_t

1
2
3
4
5
6
7
typedef struct {
uint8_t port_num; // 端口号 (1-10)
uint8_t change_type; // 1=电平变化(IO), 2=脉冲变化(Speed)
uint8_t edge_type; // 0=下降沿(按下), 1=上升沿(抬起)
uint32_t timestamp; // 时间戳(ms),用于计算动作间隔
uint16_t pulse_count; // 累计脉冲数(用于辅助判断行程)
} port_change_event_t;

设计哲学:不要记录所有的 ADC 采样或高频电平,只记录状态的改变(Event)。这种“事件驱动”的数据流,极大降低了存储和处理的压力。


3. 核心算法:滑动窗口模式识别

收集到一串数据流(如:P3↓ -> P3↑ -> P5↓ -> P5↑ -> P3↓ -> P3↑ ...)后,如何从中提取出规律?
我采用了一种自适应滑动窗口(Adaptive Sliding Window)算法。

3.1 算法原理

  1. 窗口定义:假设一个工序周期的动作数量(窗口大小 $N$)未知,我们从 $N=2$ 开始尝试,最大尝试到 $N=8$。
  2. 滑动匹配
    • 取数据流的前 $N$ 个事件作为“候选模板”。
    • 像滑块一样向后移动,检查后续的数据是否与“候选模板”高度重合。
  3. 置信度评估
    • 如果一个模板连续重复了 $\ge 3$ 次,我们认为捕捉到了规律。
    • 计算**置信度 (Confidence)**:重复次数越多,置信度越高;动作序列越复杂,误判率越低。

3.2 举个栗子

假设采集到的原始序列是:
A B C A B C A B C D

  • 尝试 N=2:模板 [A, B]。后续是 C, A -> ❌ 不匹配。
  • 尝试 N=3:模板 [A, B, C]
    • 第1次重复:[A, B, C] -> ✅ 匹配。
    • 第2次重复:[A, B, C] -> ✅ 匹配。
  • 结论:发现周期为 3 的模式 [A, B, C],重复 3 次。

4. 智能匹配:从“模式”到“业务”

识别出 [P3, P5] 交替动作这个物理规律后,MCU 还需要把它翻译成业务语言。这里就需要通过 特征模板 (Feature Template) 进行映射。

我们在代码中预置了常见机型的特征:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* 工序特征模板 */
static const process_template_t templates[] = {
// 模式1:平缝机 (压脚P3 + 剪线P5,逻辑分离)
{
.work_mode = MODE_SEWING_NORMAL,
.active_ports_count = 2,
.contains_ports = {3, 5},
.sequence_logic = SEPARATE
},
// 模式2:包缝机 (压脚剪线联动,或单剪线)
{
.work_mode = MODE_OVERLOCK,
.active_ports_count = 1,
.contains_ports = {5}, // 只有剪线信号
.sequence_logic = SINGLE
}
};

匹配流程

  1. 自动采集 30秒 或 20条 动作数据。
  2. 运行滑动窗口算法,提取出最可能的周期性模式。
  3. 将提取的模式(如“涉及端口3和5,周期1.2秒”)与预置模板库比对。
  4. 若匹配成功且置信度 $>80%$,则自动切换系统的 work_mode

5. FreeRTOS 任务调度实现

这一切都在后台静默发生,不影响主业务运行。在 AutoDetectTask 任务中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void AutoDetectTask(void *arg) {
// 1. 采集阶段:通过队列接收来自 ISR 的事件
// ... 等待队列满或超时 ...

// 2. 分析阶段:CPU 算力集中爆发
if (queue_count >= SAMPLE_DEPTH) {
pattern_t pat = analyze_sliding_window(event_buffer);

// 3. 决策阶段
if (pat.confidence > 80) {
uint8_t mode = match_template(pat);
if (mode != current_mode) {
printf("Auto-Switch to Mode: %d\n", mode);
apply_work_mode(mode); // 动态切换并保存
}
}

// 4. 重置:清空缓冲区,进入下一轮低功耗监听
clear_buffer();
}
}

6. 总结

这套机制的价值在于“去技能化”

  • 对工厂:产线工人换设备时,不需要找技术员调配置,插上电,踩几脚踏板,设备自动适配。
  • 对开发:将复杂的信号处理逻辑封装在底层算法中,业务层只需要拿那个推导出来的 work_mode 结果。

这是嵌入式 AI 的一种雏形——不需要神经网络,仅用统计学和逻辑算法,就能让 MCU 表现出某种程度的“智能”。