ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

K210与STM32异构协作:无接触测温与身份识别系统实战

K210与STM32异构协作:无接触测温与身份识别系统实战 1. 项目缘起与整体方案拆解2020年那届电赛的F题题目本身就很“接地气”——做一个无接触温度测量与身份识别装置。当年这个题出来的时候很多队伍第一反应是“测温简单身份识别也不难”但真正上手才发现把这两件事塞进一个便携设备里还要保证响应速度和识别准确率坑远比想象中多。我手里这套方案用的是K210负责视觉和身份识别STM32负责温度采集、逻辑控制和交互两块芯片各司其职通过串口通信把数据串起来。整套东西做下来硬件成本控制在两百块以内识别响应时间在1.5秒左右测温精度能做到±0.3℃配合MLX90614医疗级版本。这个项目适合谁看如果你正在准备电赛、做毕业设计或者单纯想玩一玩K210和STM32的异构协作这套方案可以直接抄作业。我会把选型逻辑、通信协议、代码框架、调试踩坑全部摊开讲尽量让刚入门的朋友也能跟着做出来。1.1 为什么选K210而不是树莓派或OpenMV身份识别这个环节核心需求是“快”和“离线”。电赛现场不可能给你稳定的网络环境用云端API做人脸识别基本等于自杀。树莓派性能强但功耗高、启动慢加上摄像头和屏幕续航直接崩掉。OpenMV倒是轻量但它的算力跑人脸检测还行跑人脸识别尤其是要区分不同人就有点吃力了。K210的优势在于它自带KPU神经网络处理器可以硬件加速卷积运算。跑YOLO或者MobileNet这类轻量模型帧率能到30fps以上而且功耗只有几百毫瓦。我实测下来用K210跑人脸检测特征提取单帧处理时间在80ms左右完全满足实时性要求。另外K210支持MicroPython和C开发电赛这种赶时间的场景用MicroPython快速验证逻辑再关键部分用C优化效率很高。1.2 STM32的角色定位与型号选择STM32在这套系统里干的是“脏活累活”读温度传感器、驱动OLED显示、控制蜂鸣器报警、管理按键输入、和K210做串口通信。这些任务对算力要求不高但对实时性和稳定性要求很高。我选的是STM32F103C8T6也就是常说的“蓝板子”72MHz主频64KB Flash20KB RAM资源刚好够用价格便宜资料铺天盖地。为什么不把温度采集也交给K210因为K210的GPIO和定时器资源相对有限而且它的强项在视觉让它分心去处理I2C时序和中断响应反而容易出问题。STM32的硬件I2C和定时器中断非常成熟读MLX90614这种I2C传感器稳得很。分工明确调试的时候也容易定位问题——测温不准就查STM32那边识别不准就查K210那边。1.3 系统整体数据流与通信架构整套系统的数据流是这样的K210持续采集摄像头图像检测到人脸后提取特征和本地存储的人脸库比对得出身份ID同时STM32每隔200ms读一次MLX90614的温度值做滑动滤波K210通过串口向STM32发送身份IDSTM32收到后把身份信息和温度值一起显示在OLED上如果温度超过阈值就触发蜂鸣器报警。通信协议我设计得很简单自定义了一个帧格式帧头0xAA 0x55 数据类型1字节 数据长度1字节 数据载荷N字节 校验和1字节。数据类型用来区分是身份信息、温度请求还是心跳包。校验和用简单的累加取低8位虽然不复杂但足够过滤掉大部分干扰。波特率设的是115200实测在20cm排线长度下误码率极低。注意K210和STM32的串口电平都是3.3V可以直接连不需要电平转换。但如果你用的是5V的STM32开发板一定要确认串口引脚是否兼容3.3V否则可能烧掉K210的IO口。2. 核心硬件选型与电路连接细节硬件这块我踩过的坑主要集中在电源和传感器接口上。下面把关键器件的选型理由和接线方式说清楚。2.1 温度传感器MLX90614的选型与I2C配置无接触测温可选方案有MLX90614、AMG8833、红外热电堆传感器加运放。AMG8833是8x8热成像分辨率太低测单点温度误差大热电堆加运放方案成本低但需要自己做校准温漂也难控制。MLX90614是成熟的红外温度传感器出厂校准I2C接口直接读寄存器就能拿到温度值精度有保障。MLX90614有几个版本我选的是MLX90614ESF-BAA医疗级测温范围-70℃到380℃精度±0.5℃人体温度范围内能到±0.3℃。它的视场角是90度适合近距离测量。接线很简单VCC接3.3VGND接地SCL和SDA分别接STM32的I2C引脚我用的PB6和PB7加上4.7kΩ上拉电阻。这里有个细节MLX90614的I2C地址是0x5A但它的EEPROM里可以改地址。如果你要接多个传感器可以改地址后挂在同一条I2C总线上。不过电赛单点测温一个就够了。2.2 K210开发板与摄像头模组的搭配K210开发板我用的是一块常见的K210核心板带Type-C接口和TF卡槽。摄像头用的是OV2640200万像素支持RGB565和JPEG输出。K210的I2S接口直接连OV2640的DVP接口接线包括PCLK、VSYNC、HSYNC、D0-D7、XCLK、SDA、SCL。这些引脚在K210的引脚图上都有标注照着连就行。屏幕我用的是1.8寸SPI TFTST7735驱动分辨率128x160。虽然小但显示温度、姓名、状态足够了。K210的SPI接口驱动这个屏幕很轻松MicroPython里直接用lcd模块就能初始化。2.3 电源方案与功耗估算整套系统的功耗主要来自K210约300mA3.3V、STM32约50mA、屏幕约40mA、MLX90614约1.5mA。加起来峰值电流在400mA左右。如果用USB供电直接插电脑或者充电宝就行。如果要做成便携设备可以用一块3.7V锂电池加升压模块升到5V后再降压到3.3V。我试过用AMS1117-3.3给K210供电结果发现K210启动瞬间电流太大AMS1117会掉压导致K210反复重启。后来换成MP1584EN降压模块输出3.3V最大电流3A问题解决。所以电源这块别省LDO适合小电流大电流场景还是用DC-DC。提示K210对电源纹波比较敏感建议在3.3V输出端并一个100uF电解电容和一个0.1uF陶瓷电容滤掉低频和高频噪声。2.4 串口通信的物理连接与电平匹配K210和STM32的串口连接我用的是K210的UART1引脚IO6和IO7和STM32的USART1PA9和PA10。K210的TX接STM32的RXK210的RX接STM32的TXGND共地。波特率1152008位数据位1位停止位无校验。这里有个容易忽略的点K210的IO口默认是3.3V电平但有些开发板带了5V容忍有些没有。保险起见我在TX和RX线上各串了一个100Ω电阻限流保护。实测通信稳定连续跑24小时没出现丢包。3. 软件框架与核心代码实现软件部分我分成两块讲K210端负责人脸检测和识别STM32端负责温度采集、显示和报警。两边通过串口协议交互。3.1 K210端人脸检测与特征提取的完整流程K210上跑的是YOLOv2-tiny人脸检测模型输入分辨率224x224输出人脸框坐标。检测到人脸后裁剪出人脸区域缩放到112x112送入MobileNetV1提取128维特征向量。然后和本地存储的人脸特征库做余弦相似度比对相似度超过阈值就判定为同一个人。模型训练我用的是自己采集的数据集每个人拍了50张不同角度的照片加上数据增强旋转、缩放、亮度调整总共2000张左右。训练在PC上完成然后用nncase工具转换成K210的kmodel格式。转换的时候要注意量化K210的KPU只支持int8推理量化后的精度损失大概在2%左右可以接受。MicroPython代码里关键步骤是这样的import sensor, image, lcd, time import KPU as kpu sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) sensor.run(1) task kpu.load(/sd/face_detect.kmodel) anchor (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437, 6.92275, 6.718375, 9.01025) kpu.init_yolo2(task, 0.5, 0.3, 5, anchor) while True: img sensor.snapshot() code kpu.run_yolo2(task, img) if code: for i in code: face img.cut(i.x(), i.y(), i.w(), i.h()) face face.resize(112, 112) # 提取特征并比对 feature extract_feature(face) name match_face(feature) uart_send(name)这段代码里extract_feature和match_face是我自己封装的函数底层调用KPU跑MobileNet。实际部署时特征库存在TF卡里启动时加载到内存。3.2 STM32端温度采集、滤波与OLED显示STM32这边用标准库开发Keil MDK环境。MLX90614的驱动很简单I2C读两个字节拼成16位数据乘以0.02就是摄氏度。但原始数据有波动我加了滑动平均滤波窗口大小8每次读到的值先入队然后取平均。#define FILTER_WINDOW 8 float temp_buffer[FILTER_WINDOW]; uint8_t buf_index 0; float read_temp_filtered(void) { float raw mlx90614_read_temp(); temp_buffer[buf_index] raw; buf_index (buf_index 1) % FILTER_WINDOW; float sum 0; for (int i 0; i FILTER_WINDOW; i) { sum temp_buffer[i]; } return sum / FILTER_WINDOW; }OLED显示用的是SSD1306I2C接口和MLX90614共用一条总线。显示内容分三行第一行显示“身份张三”第二行显示“体温36.5℃”第三行显示“状态正常”。如果温度超过37.3℃第三行显示“状态发热”同时蜂鸣器响。3.3 串口通信协议设计与数据解析串口协议我定义了一个结构体typedef struct { uint8_t header[2]; // 0xAA 0x55 uint8_t type; // 0x01:身份信息 0x02:温度请求 0x03:心跳 uint8_t length; // 数据长度 uint8_t data[32]; // 数据载荷 uint8_t checksum; // 累加和 } UART_Frame;STM32端用中断接收每收到一个字节就放进缓冲区然后状态机解析。状态机有四个状态等待帧头1、等待帧头2、等待类型和长度、等待数据和校验。解析成功后根据类型做相应处理。K210端发送身份信息时数据载荷是姓名字符串和相似度float转4字节。STM32收到后把姓名显示在OLED上相似度低于阈值就显示“未知”。注意串口通信一定要加超时机制。我遇到过K210死机后STM32一直等数据的情况后来在状态机里加了超时计数超过500ms没收到完整帧就重置状态机。3.4 人脸库的建立与识别阈值调优人脸库的建立是个体力活。我找了5个同学每人拍50张照片涵盖不同光照、不同角度、戴眼镜和不戴眼镜的情况。照片存到SD卡K210启动时加载。特征提取后每个人得到一个128维向量取平均作为该人的特征模板。识别阈值我调了很久。阈值太高同一个人稍微换个角度就认不出来阈值太低不同人之间容易误认。最后定在0.75余弦相似度实测下来误识率低于1%拒识率在5%左右。如果对安全性要求更高可以提到0.8但拒识率会上升到10%。4. 调试过程中的典型问题与排查实录这部分是我踩坑最多的地方每一个问题都花了不少时间才解决。整理成速查表方便你遇到类似情况时快速定位。4.1 K210摄像头初始化失败与图像花屏最开始调试K210的时候摄像头死活初始化不了报错“sensor init failed”。排查了一圈发现是XCLK引脚没配置对。K210的XCLK输出频率默认是24MHz但OV2640需要24MHz有些模块需要12MHz。我在代码里加了sensor.set_xclk(24000000)问题解决。图像花屏是另一个常见问题。原因通常是PCLK极性不对或者数据线接触不良。我用的排线比较长20cm信号衰减导致花屏。后来把排线缩短到10cm花屏消失。如果必须用长排线可以在PCLK线上串一个33Ω电阻改善信号完整性。4.2 MLX90614读数跳变与I2C总线锁死MLX90614读数跳变有时候读到85℃这种明显错误的值。查了手册发现是I2C通信失败时返回的默认值。原因有两个一是上拉电阻太大我一开始用了10kΩ后来换成4.7kΩ二是I2C总线被干扰STM32的硬件I2C在异常时会锁死需要重新初始化。解决方法是加I2C超时检测如果连续三次读失败就重新初始化I2C外设。另外MLX90614的读取间隔不要低于100ms太频繁会导致传感器内部温度不稳定。4.3 串口丢包与校验错误的处理串口丢包主要发生在K210端发送数据时。K210的MicroPython串口发送是阻塞的如果STM32那边接收不及时数据就会丢。我在K210端加了发送缓冲区每次发送前检查缓冲区是否为空不为空就等待。STM32端把接收中断优先级设到最高确保及时响应。校验错误通常是波特率偏差导致的。K210的UART时钟源是26MHz分频后115200的波特率有微小偏差STM32那边如果也用内部RC振荡器偏差会累积。后来STM32改用外部8MHz晶振波特率偏差降到0.1%以内校验错误基本消失。4.4 常见问题速查表问题现象可能原因排查方法解决方案K210摄像头初始化失败XCLK频率不对检查sensor.set_xclk设置设为24MHz或12MHz图像花屏PCLK极性错误或排线过长缩短排线检查极性串33Ω电阻调整极性MLX90614读数85℃I2C通信失败检查上拉电阻和接线换4.7kΩ上拉加超时重初始化串口丢包发送过快或中断优先级低检查发送间隔和中断配置加发送缓冲提高接收中断优先级校验错误波特率偏差检查时钟源改用外部晶振K210反复重启电源电流不足测量3.3V电压换DC-DC供电加滤波电容人脸识别率低阈值不合适或光照差调整阈值补光阈值设0.75加LED补光OLED不显示I2C地址冲突扫描I2C地址修改OLED地址或分总线4.5 几个容易被忽略的实操心得第一个心得K210的散热。K210跑神经网络时发热明显尤其是夏天芯片表面温度能到60℃。虽然不至于烧坏但会影响稳定性。我在K210芯片上贴了一个小铝散热片成本几毛钱效果很明显连续跑2小时没出现过热重启。第二个心得人脸库的存储格式。我一开始把特征向量存成文本文件读取慢还占空间。后来改成二进制文件每个特征128字节5个人总共640字节读取时间从200ms降到20ms。第三个心得STM32的看门狗。电赛现场环境复杂电源波动、静电干扰都可能导致STM32死机。我开了独立看门狗超时时间2秒主循环里定期喂狗。这样即使程序跑飞也能自动复位不至于整个系统瘫痪。第四个心得调试信息的输出。K210和STM32都要留调试串口但电赛现场只有一套串口工具。我的做法是STM32用SWD调试K210用USB转串口看print输出。两边分开调试互不干扰。5. 系统联调与性能优化记录单模块调试通过后联调才是真正的考验。K210和STM32要协同工作时序、数据格式、异常处理都要对齐。5.1 联调步骤与时间同步联调我分三步走第一步STM32单独跑确认温度采集和OLED显示正常第二步K210单独跑确认人脸检测和识别正常第三步两边连起来先测试串口通信再测试完整流程。时间同步是个小问题。K210识别到人脸后发送身份信息STM32收到后要立即更新显示。但STM32的主循环里还有温度采集和按键扫描如果这些任务耗时太长显示更新就会延迟。我的做法是把串口接收放在中断里收到完整帧后置一个标志位主循环检测到标志位就优先处理显示更新。5.2 识别速度与测温响应时间的平衡K210的人脸识别流程包括检测和特征提取检测每帧都跑特征提取只在检测到人脸后跑。实测下来检测耗时约50ms特征提取约30ms总耗时80ms。如果每帧都做特征提取帧率会降到10fps以下。我的优化策略是检测到人脸后连续提取3帧特征取平均然后暂停特征提取只做检测直到人脸消失再重新触发。这样既保证了识别准确率又维持了流畅的体验。测温响应时间主要取决于MLX90614的读取周期。我设的是200ms读一次加上滑动滤波实际响应时间在400ms左右。对于人体测温来说这个速度足够了。5.3 功耗优化与续航测试如果用电池供电功耗优化就很重要。K210的功耗大头在KPU和摄像头我试过降低摄像头分辨率从QVGA降到QQVGA功耗降了约30mA但识别距离也缩短了。最后折中保持QVGA但把屏幕亮度调低关闭不必要的LED指示灯。续航测试用了一块2000mAh的锂电池满电状态下连续工作约4小时。如果间歇工作检测到人脸才启动识别续航能到6小时以上。5.4 最终性能指标与实测数据整套系统最终的性能指标如下指标数值测试条件测温范围30℃~45℃人体测温模式测温精度±0.3℃配合MLX90614医疗级识别距离30cm~80cm光照充足识别响应时间1.5s从进入画面到显示结果识别准确率98%5人库每人50张测试连续工作时长4小时2000mAh电池通信误码率0.1%115200波特率20cm排线这套数据是在实验室环境下测的实际电赛现场可能会有波动但整体表现稳定。6. 项目开源与后续扩展思路这个项目做完后我把代码和原理图整理了一下放在GitHub上开源。开源的内容包括K210的MicroPython代码、STM32的Keil工程、串口协议文档、以及人脸库的采集和训练脚本。6.1 开源代码结构与使用说明代码仓库分三个目录k210目录下是MicroPython脚本和kmodel文件stm32目录下是Keil工程包含MLX90614驱动、OLED驱动、串口协议解析tools目录下是PC端的人脸库训练脚本和模型转换脚本。使用的时候先把kmodel文件和人脸库拷到SD卡插入K210上电后K210会自动加载模型。STM32那边烧录hex文件接好线就能跑。如果你想加新的人脸用tools目录下的脚本采集照片训练后重新生成kmodel和特征库。6.2 可以继续深挖的几个方向第一个方向是加活体检测。现在的人脸识别有个漏洞拿照片也能识别通过。加活体检测可以用眨眼检测或者红外双目K210的算力跑眨眼检测没问题但需要额外的红外摄像头。第二个方向是加WiFi上传。用ESP8266或者ESP32做透传把温度和人脸识别记录上传到服务器方便做考勤和体温统计。STM32的串口资源还有富余接一个WiFi模块就行。第三个方向是优化模型。现在用的MobileNetV1特征提取精度一般。可以换成MobileFaceNet特征维度降到128维精度更高速度也更快。不过模型转换和量化需要重新调。第四个方向是加语音播报。用SYN6288或者WT588DSTM32通过串口发送文本模块播报“张三体温正常”。成本增加不到20块但体验提升明显。6.3 给准备复现的朋友几点建议如果你打算复现这个项目我的建议是先把K210和STM32分开调通再联调。K210的MicroPython环境虽然方便但坑也不少尤其是模型加载和内存管理。STM32那边I2C和串口的中断优先级要配好不然容易丢数据。人脸库采集的时候尽量多拍几张不同角度、不同光照都覆盖到。我一开始只拍了正面照结果侧脸识别率很低。后来补了侧脸和戴眼镜的照片识别率才上来。电源一定要用好的别用劣质USB线。我遇到过USB线内阻太大K210启动时电压跌到3.0V以下反复重启。换了一根粗铜芯的线问题消失。最后电赛现场时间紧别追求完美。先把基本功能跑通再优化细节。测温准、识别快、显示清楚这三点做到了分数就不会低。
返回列表