☰
基于STM32与OpenMV的非接触式人脸识别测温系统设计与实现
2026/10/12 4:54:06 网站建设 项目流程

简介:本资源是一套面向嵌入式AI初学者与课程设计者的完整无接触式健康监测系统实现方案,聚焦公共卫生场景下的体温筛查、身份核验与防疫合规性判断三大刚需。系统以STM32F103为主控,OpenMV模组为视觉处理单元,集成GY-906DCI红外测温、Adaboost口罩检测、轻量级神经网络人脸识别及OLE跨平台数据对接能力,适用于校园闸机、办公入口、社区哨点等部署场景。压缩包共198个文件,含41个C语言驱动与算法源码(.c/.h)、30个编译中间文件(.o/.d)、29个Keil工程依赖项(.crf),以及Python训练脚本、TFLite模型、Keil工程(uvprojx)、Hex固件和详细文档(docx/htm/md),总大小8.03MB,结构清晰,模块解耦明确。目前已有60人学习下载,提供可直接烧录运行的完整固件、多级调试日志支持、传感器标定说明及算法移植注释,助读者快速掌握嵌入式端AI部署全流程。

1. 项目概述与核心价值

最近几年,大家对公共卫生和个人健康监测的关注度越来越高,尤其是在一些需要快速筛查的公共或半公共场合。传统的体温测量方式,比如额温枪,虽然方便,但需要近距离接触,存在交叉感染风险,而且无法与身份信息自动关联,数据记录和管理效率低下。我手头正好有STM32F103和OpenMV这两块开发板,琢磨着能不能把它们结合起来,做一个既能无接触测温,又能识别人脸、判断是否佩戴口罩的“三合一”小系统。这个想法听起来有点复杂,但拆解开来,其实就是几个成熟模块和算法的组合应用。

这个系统的核心目标很明确:非接触、自动化、可记录。用户走到设备前,系统通过摄像头捕捉人脸,在识别身份的同时,用红外测温模块测量额温,并检查是否规范佩戴口罩。所有数据可以实时显示,并上传到后台或本地存储,形成一个简单的健康通行记录。这对于小型办公室、社区入口、实验室签到等场景,是一个成本可控且实用性很强的解决方案。整个系统的硬件核心是STM32F103C8T6最小系统板作为主控,负责逻辑调度、数据汇总和通信;OpenMV Cam H7 Plus作为视觉处理单元,负责人脸检测、识别和口罩判断;测温则交给了GY-906 DCI非接触式红外测温模块。软件层面,OpenMV上运行基于Haar Cascade或LBP Cascade的Adaboost算法进行人脸和口罩的快速初筛,并结合轻量级神经网络模型进行更精确的人脸识别。STM32则通过串口与两者通信,整合信息,驱动显示和报警模块。

2. 系统整体设计与硬件选型思路

做一个项目,第一步永远是整体设计。你不能拿到芯片和模块就开始焊线,得先想清楚数据流和控制流怎么走。这个系统的设计思路是“视觉主导,主控调度”。

2.1 核心架构与数据流设计

整个系统的工作流程可以概括为一个状态机:等待 -> 检测到人脸 -> 进行人脸识别与口罩检测 -> 启动测温 -> 数据显示/上传。OpenMV作为“眼睛”和“初级大脑”,它持续拍摄图像,运行人脸检测算法。一旦在画面中锁定人脸区域,它会立刻做两件事:第一,截取该区域图像,送入预先训练好的人脸识别模型(例如使用OpenMV自带的nn模块加载TensorFlow Lite转换后的模型)进行特征比对,识别出这是“张三”还是“李四”;第二,在同一区域运行口罩检测算法,判断是否佩戴规范。这两个识别结果会通过串口(UART)实时发送给STM32。

与此同时,STM32在收到OpenMV的“发现目标”信号后,会通过I2C总线向GY-906模块发送读取指令,获取当前测量到的物体温度值。这里有一个关键点:测温的时机和对象必须与视觉识别同步。你不能对着空气测温,也不能在人脸识别完成前乱测。因此,STM32需要协调好这个时序。通常,我会让OpenMV在识别到人脸后,发送一个包含人脸框坐标的指令给STM32,STM32可以据此(虽然GY-906是固定视场角,但可以辅助判断)或者简单地延时一小段时间后,再读取温度,以确保测的是人额头的温度。

最后,STM32将收到的“人员ID”、“口罩状态(是/否)”、“体温数值”这三类信息整合,通过SPI接口驱动一块OLED显示屏进行本地显示,同时也可以通过串口、蓝牙模块或Wi-Fi模块将数据打包上传到上位机或云平台。整个架构清晰,模块各司其职,STM32作为“总指挥”负责协调和通信。

2.2 关键硬件选型与接口定义

硬件是项目的骨架,选型决定了系统的稳定性、成本和开发难度。

  1. 主控制器:STM32F103C8T6选择这款芯片的原因很简单:性价比极高,资源足够,生态成熟。它基于ARM Cortex-M3内核,72MHz主频,对于处理串口数据、驱动OLED、管理I2C通信绰绰有余。64KB的Flash和20KB的RAM也足够存放程序和一些临时数据。它的外设资源正好匹配我们的需求:多个USART(用于与OpenMV、调试、无线模块通信)、I2C(连接GY-906和OLED)、SPI(驱动OLED,如果选用SPI接口的屏)以及足够的GPIO。市面上各种最小系统板价格低廉,降低了入门门槛。

  2. 视觉处理单元:OpenMV Cam H7 Plus这是本项目的“智慧之眼”。为什么不直接用STM32跑OpenCV?因为STM32F103的计算能力和内存根本无法胜任实时图像处理。OpenMV内置了强大的MicroPython解释器和专用的图像传感器处理器,可以非常方便地调用写好的图像处理函数和机器学习模型。H7 Plus版本使用了更强大的STM32H7芯片,处理速度更快,能更流畅地运行人脸检测和识别算法。我们通过其主串口(UART3)与STM32通信,发送识别结果和指令。

  3. 红外测温模块:GY-906 (MLX90614ESF-DCI)测温模块的选型是精度和成本平衡的结果。MLX90614是一款工业级红外测温芯片,DCI版本测量距离约2-5cm,视场角窄,适合测量小目标(如额头),精度可达±0.5℃。它通过I2C接口通信,使用非常简单,只需发送设备地址和读取命令即可获取物体温度和 ambient温度。这里有个重要细节:务必选择DCI(远距离窄视场角)版本,而不是DAA(宽视场角)版本。DAA版本适合测大面积区域平均温度,测人体额头会因为环境干扰导致误差很大。

  4. 显示模块:0.96寸OLED (SSD1306)选择I2C接口的OLED屏,接线简单(仅需4根线),显示清晰,功耗低。STM32有成熟的驱动库(如OLED_ShowString,OLED_ShowNum),可以方便地显示体温、姓名、口罩状态和简单的提示图标。

  5. 电源与结构整个系统可以用一个5V/2A的USB电源供电,通过降压模块(如AMS1117-3.3)为各模块提供稳定的3.3V。结构上,需要将OpenMV的摄像头、GY-906传感器和OLED屏幕固定在一个朝向一致的面板上,确保摄像头和测温探头对准同一个区域(即人的面部区域)。可以设计一个简单的3D打印外壳来整合它们。

注意:硬件连接时,务必注意电平匹配。STM32F103和OpenMV的IO口大多是3.3V电平,而GY-906和OLED(SSD1306)通常也支持3.3V。直接连接即可。如果使用5V电平的模块,需要加电平转换电路。

3. 软件实现:从算法到代码的细节拆解

软件部分是项目的灵魂,也是最体现功力的地方。我们将分STM32端和OpenMV端来讲解。

3.1 OpenMV端:人脸识别与口罩检测算法实现

OpenMV的编程基于MicroPython,代码非常简洁。核心任务有三个:人脸检测、人脸识别、口罩检测。

1. 人脸检测(快速定位)这是第一步,我们使用经典的Haar Cascade或LBP Cascade分类器,它们基于Adaboost算法训练,在OpenMV上速度极快。

import sensor, image, time from pyb import UART # 初始化摄像头 sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) # 320x240, 速度和精度的平衡 sensor.skip_frames(time = 2000) # 加载人脸检测分类器文件(需要提前放入OpenMV的存储中) face_cascade = image.HaarCascade("frontalface", stages=25) # 或使用LBP: image.LBPFrontalFaceCascade() uart = UART(3, 115200) # 使用UART3与STM32通信 while(True): img = sensor.snapshot() # 进行人脸检测 objects = img.find_features(face_cascade, threshold=0.75, scale_factor=1.25) if objects: # 通常取最大的那个人脸框 max_face = max(objects, key=lambda r: r[2]*r[3]) (x, y, w, h) = max_face # 在图像上框出人脸,用于调试 img.draw_rectangle(max_face) # 截取人脸区域图像,用于后续识别和口罩检测 face_img = img.copy(roi=max_face) # 接下来进行识别和口罩判断... # 将结果通过串口发送出去,例如格式:“ID, Mask_Flag, x, y” # uart.write("1,1,{},{}\n".format(x, y)) # 示例:ID=1, 戴口罩=1

为什么选择Cascade而不是直接上神经网络做检测?因为检测任务需要遍历图像不同位置和尺度,计算量大。Cascade分类器速度极快,能保证实时性,先快速框出可能的人脸区域,再对这个小区域进行更耗资源的识别和口罩判断,这是经典的“检测+识别”两级流水线,效率最高。

2. 人脸识别(确认身份)对于截取出来的face_img,我们需要识别出他是谁。这里可以使用OpenMV的nn模块加载一个轻量级神经网络模型。这个模型需要预先在PC上训练好(例如使用TensorFlow/Keras搭建一个简单的卷积神经网络,在自制的人脸数据集上训练),然后转换成TensorFlow Lite格式,最后用OpenMV的tflite_converter工具转换成.tflite模型文件,放入OpenMV中。

# 假设已经转换好模型文件`face_model.tflite`和标签文件`labels.txt` import tf net = tf.load('face_model.tflite', load_to_fb=True) # 加载模型到帧缓存,加速 labels = [line.rstrip('\n') for line in open('labels.txt')] # 在循环中,截取face_img后 face_img = face_img.resize(96, 96) # 缩放到模型输入尺寸 face_img = face_img.to_grayscale() # 如果模型是灰度输入 # 将图像数据转换为模型输入格式 tensor = tf.convert_image(face_img, ...) # 根据模型要求进行转换 out = net.predict(tensor) # 执行推理 idx = out.index(max(out)) # 获取最大概率的索引 person_id = labels[idx] # 得到对应人名或ID confidence = max(out) # 置信度 if confidence < 0.7: # 设置一个置信度阈值,过低则视为“未知人员” person_id = "Unknown"

实操心得:训练自己的人脸模型时,数据集的质量至关重要。每个人脸需要多角度、不同光照条件的图片。建议使用face_recognition库在PC端先进行人脸对齐和裁剪,确保输入模型的都是归一化的人脸区域,这样能极大提升识别准确率。

3. 口罩检测口罩检测可以作为一个二分类问题(戴口罩/不戴口罩)来处理。有两种实现思路:

  • 思路A:独立口罩检测模型。再训练一个专门的轻量级CNN模型,输入是人脸区域图像,输出是“戴口罩”或“不戴口罩”。这种方式准确率高,但需要额外的模型加载和推理时间。
  • 思路B:在人脸识别模型中扩展。更高效的方法是在训练人脸识别模型时,就将“戴口罩的人脸”作为同一个人的另一类数据加入训练集。模型在识别出“张三”的同时,其倒数第二层(特征层)的特征向量,可以训练一个简单的线性分类器(SVM或逻辑回归)来判断是否戴口罩。在OpenMV上,可以把这个线性分类器的权重集成进去,在推理后多做一个计算。对于资源紧张的场景,甚至可以直接用人脸检测框的宽高比和下巴区域像素统计做一个非常粗略的估计:戴口罩时,检测框的下半部分(嘴部区域)颜色和纹理相对均匀。

在实际项目中,我采用了思路A,因为它的职责更单一,效果更稳定。我训练了一个简单的4层卷积神经网络,输入是48x48的灰度人脸图,输出是2个节点。在OpenMV上运行速度很快。

mask_net = tf.load('mask_model.tflite', load_to_fb=True) # ... 对同一个face_img进行预处理,缩放到48x48... mask_tensor = tf.convert_image(face_img, ...) mask_out = mask_net.predict(mask_tensor) is_masked = 1 if mask_out[0] > mask_out[1] else 0 # 假设输出为[戴口罩概率, 不戴概率]

最后,OpenMV将person_id,is_masked,以及人脸框中心坐标(用于辅助STM32判断测温时机)打包成一个字符串,通过串口发送给STM32。格式可以自定义,例如:“ID:001,MSK:1,X:120,Y:100\n”。

3.2 STM32端:主控逻辑与多模块通信协调

STM32端的程序使用Keil MDK或STM32CubeIDE开发,主要逻辑集中在主循环中,通过中断和状态标志来协调。

1. 外设初始化这是标准步骤,包括系统时钟、GPIO、USART(用于与OpenMV和调试)、I2C(用于GY-906和OLED)、SPI(如果OLED用SPI)等的初始化。使用STM32CubeMX工具可以图形化配置,生成初始化代码,非常方便。

2. 与OpenMV的串口通信协议定义一个简单可靠的通信协议至关重要。例如:

  • OpenMV -> STM32:“ID,MSK,X,Y\n”(例如:“2,1,150,110\n”)
  • STM32 -> OpenMV:“CMD:TEMP_START\n”(当STM32准备好测温时,可以发送指令通知OpenMV, OpenMV可以反馈一个特定姿势或亮灯提示用户保持静止)。

在STM32中,开启串口接收中断,在中断服务函数中将字符存入缓冲区,当检测到换行符\n时,设置一个“数据包就绪”标志位。

// 示例:串口中断服务函数 void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { char rc = USART_ReceiveData(USART1); if(rc == '\n') { rx_buffer[rx_index] = '\0'; // 字符串结束符 data_ready_flag = 1; // 设置标志位 rx_index = 0; } else { rx_buffer[rx_index++] = rc; if(rx_index >= RX_BUF_SIZE) rx_index = 0; // 防止溢出 } } }

在主循环中检测到这个标志位,就解析缓冲区里的字符串,提取出ID、口罩状态和坐标。

3. 驱动GY-906读取温度GY-906的I2C地址通常是0x5A(7位地址)。读取物体温度(TObj1)的流程是:先发送设备地址+写位,发送寄存器地址0x07;然后发送重复起始条件,发送设备地址+读位,连续读取两个字节的数据(低字节在前),组成一个16位整数。这个整数需要乘以0.02(分辨率)再减去273.15,才能得到摄氏温度。

float MLX90614_ReadTemp(void) { uint8_t data[2] = {0}; uint16_t tempRaw = 0; float tempC = 0; // 1. 发送要读取的寄存器地址 0x07 (物体温度1) HAL_I2C_Mem_Read(&hi2c1, 0x5A << 1, 0x07, I2C_MEMADD_SIZE_8BIT, data, 2, 100); // 2. 计算原始值 tempRaw = (data[1] << 8) | data[0]; // 3. 转换为摄氏度 tempC = (float)tempRaw * 0.02 - 273.15; return tempC; }

注意事项:GY-906的测量需要稳定时间。上电后,最好等待几百毫秒再进行第一次读取。连续读取时,间隔不宜太短(建议大于100ms),否则模块自身发热会影响精度。测温时,务必确保被测对象(额头)在模块的视场角内,并且距离在2-5厘米左右,避免环境热源(如灯光、窗户)的干扰。

4. 主状态机逻辑主循环的核心是一个状态机:

typedef enum { STATE_IDLE, STATE_FACE_DETECTED, STATE_MEASURING_TEMP, STATE_DISPLAY_RESULT, STATE_UPLOAD_DATA } SysState_t; SysState_t system_state = STATE_IDLE; while(1) { switch(system_state) { case STATE_IDLE: if(data_ready_flag) { // 收到OpenMV数据包 ParseData(rx_buffer, &id, &mask_status, &face_x, &face_y); system_state = STATE_FACE_DETECTED; data_ready_flag = 0; } break; case STATE_FACE_DETECTED: // 可以在这里通过串口发送指令给OpenMV,提示用户“请保持静止” UART_SendString("CMD:READY\n"); HAL_Delay(300); // 等待用户稳定 system_state = STATE_MEASURING_TEMP; break; case STATE_MEASURING_TEMP: current_temp = MLX90614_ReadTemp(); // 简单的温度滤波,比如连续读3次取平均 system_state = STATE_DISPLAY_RESULT; break; case STATE_DISPLAY_RESULT: OLED_Clear(); OLED_ShowString(0, 0, "ID:"); OLED_ShowNum(24, 0, id, 3); OLED_ShowString(0, 16, "Mask:"); OLED_ShowString(48, 16, mask_status ? "YES" : "NO!"); OLED_ShowString(0, 32, "Temp:"); OLED_ShowFloatNum(48, 32, current_temp, 2); // 显示两位小数 if(current_temp > 37.3 || mask_status == 0) { // 阈值判断 OLED_ShowString(0, 48, "ALERT!"); Buzzer_On(); // 触发蜂鸣器报警 } else { OLED_ShowString(0, 48, "PASS"); Buzzer_Off(); } system_state = STATE_UPLOAD_DATA; break; case STATE_UPLOAD_DATA: // 将 id, mask_status, current_temp 打包,通过串口发送给Wi-Fi模块或PC sprintf(upload_buf, "{\"id\":%d,\"mask\":%d,\"temp\":%.2f}\n", id, mask_status, current_temp); UART_SendString(upload_buf); HAL_Delay(2000); // 结果显示和上传保持2秒 system_state = STATE_IDLE; // 回到空闲状态,等待下一个人 break; } }

这个状态机清晰地描述了整个控制流程,避免了逻辑混乱。HAL_Delay在实际应用中最好用定时器替代,以实现非阻塞延时,保证系统响应性。

4. 系统集成、调试与性能优化要点

当硬件焊接好,两端代码都初步编写完成后,就进入了最考验耐心的集成调试阶段。

4.1 硬件联调与信号稳定性排查

首先确保电源稳定。用万用表测量各模块的VCC电压是否在额定范围内(尤其是3.3V)。然后从最简单的模块开始调试:

  1. OLED调试:先写一个简单的测试程序,让STM32在OLED上显示“Hello World”,确保I2C/SPI通信和屏幕本身正常。
  2. GY-906调试:编写一个单独读取温度的程序,对着你的手或一个恒温物体(比如一杯温水)测量,观察串口打印的值是否合理、稳定。常见问题:I2C总线没应答。检查接线(SCL, SDA是否接反、接错),检查上拉电阻(通常模块已内置,如果通信距离长可外加4.7k上拉),用逻辑分析仪抓取I2C波形看时序是否正确。
  3. OpenMV与STM32串口调试:这是通信的核心。先在OpenMV端写一个固定发送“TEST”字符串的程序,在STM32端用中断接收并打印出来。确保波特率(如115200)、数据位、停止位、校验位双方设置完全一致。一个关键技巧:在OpenMV发送数据和STM32接收解析时,都加入\r\n作为帧结束符,并在STM32解析前做好缓冲区溢出保护和字符串格式校验。

4.2 视觉与测温的时空同步优化

这是本项目的难点之一。摄像头“看到”人脸和红外传感器“感到”温度,存在物理位置和时间的差异。

  • 空间对齐:在机械结构上,尽量让OpenMV摄像头和GY-906传感器的中心轴平行且靠近,指向同一方向。可以通过标定,建立一个粗略的映射关系:当人脸出现在画面中央(例如坐标(160,120)附近)时,认为其额头正对测温探头。
  • 时间同步:在代码逻辑上,采用“视觉触发,延时测温”策略。当OpenMV稳定检测到人脸(例如连续5帧都检测到,且位置变化不大)后,才发送信号给STM32。STM32收到信号后,延时200-500ms(让人有时间稳定姿势),再进行温度读取。可以在OLED上增加“请稍候测温”的提示,提升用户体验。
  • 温度补偿:GY-906读取的是物体表面温度。人体额头温度受环境温度影响。MLX90614本身会测量环境温度(Ta),芯片内部有补偿算法。我们读取的物体温度(To)已经是补偿后的。但为了更精确,可以在设备安装位置放置一个参考黑体(或使用已知温度物体),进行一点软件上的偏移校准。

4.3 模型优化与系统性能提升

OpenMV上的神经网络模型是性能瓶颈。以下优化手段非常有效:

  1. 模型量化:在PC端训练时,使用TensorFlow的量化感知训练(QAT)或训练后动态范围量化(DRQ),将32位浮点权重转换为8位整数(int8)。这能大幅减少模型体积和提升推理速度,而精度损失通常很小(<1%)。
  2. 输入尺寸优化:人脸识别和口罩检测模型的输入图像尺寸不要盲目追求大。96x96或甚至48x48的灰度图像,对于嵌入式设备已经足够。更小的尺寸意味着更少的计算量。
  3. 帧率与分辨率平衡:OpenMV的sensor.set_framesize()设置很重要。QVGA (320x240) 是一个很好的平衡点。分辨率太低(如QQVGA)会影响检测和识别精度,太高(如VGA)则会严重拖慢帧率。可以实测不同分辨率下的算法帧率,选择能满足实时性(例如>5fps)的最高分辨率。
  4. STM32端的代码优化:
    • 避免阻塞:将所有HAL_Delay()替换为基于HAL_GetTick()的非阻塞状态机。例如,测温等待时间可以用一个uint32_t start_tick = HAL_GetTick();记录开始时间,然后判断if(HAL_GetTick() - start_tick > 300)。
    • 合理使用中断:除了串口,还可以将GY-906的DRDY(数据就绪)引脚连接到STM32的外部中断引脚(如果模块支持),实现异步读取,而不是轮询。
    • 内存管理:STM32F103内存小,避免使用大的全局数组和递归。使用malloc/free要非常小心,最好静态分配。

5. 常见问题与故障排查实录

在实际开发中,我遇到了不少坑,这里总结一下,希望能帮你节省时间。

问题现象可能原因排查步骤与解决方案
OpenMV无法检测到人脸1. 光线太暗或过曝。
2. 人脸距离摄像头太近或太远。
3. Cascade分类器文件未正确加载或版本不匹配。
4. 摄像头未正确对焦(对于带自动对焦的型号)。
1. 调整环境光照,或开启OpenMV的自动增益/白平衡。
2. 调整距离,使人脸框约占画面1/4到1/2。
3. 检查.cascade文件路径和文件名,尝试使用OpenMV IDE自带的示例文件测试。
4. 运行sensor.set_auto_focus()或手动调焦。
人脸识别准确率低1. 训练数据集质量差、数量少、多样性不足。
2. 模型输入图像预处理不一致(训练和推理时缩放、归一化方式不同)。
3. 现场光照与训练集差异大。
1. 扩充数据集,每人至少20-30张不同角度、表情、光照的图片。
2. 确保推理代码中的图像预处理(缩放、色彩空间转换、归一化)与训练时完全一致。
3. 考虑在OpenMV端增加简单的人脸对齐(根据眼睛位置旋转)或使用直方图均衡化增强对比度。
GY-906测温数值跳动大或不准确1. 测量距离太远或不在视场中心。
2. 被测物体发射率低(如光亮的金属额头)。
3. 模块前方有透明遮挡物(亚克力板)。
4. 环境有强热源干扰(阳光、暖气)。
5. I2C通信受干扰。
1. 确保额头距离探头2-5cm,并正对。
2. 在额头贴一小块黑色电工胶布(发射率接近0.95)作为测量点。
3. 移除任何遮挡物,或使用专门透红外线的材料(如聚乙烯)。
4. 改变设备安装位置,避开热源。
5. 缩短I2C走线,增加上拉电阻(4.7kΩ),并确保电源地线良好。
STM32与OpenMV串口通信乱码或丢包1. 双方波特率等参数设置不一致。
2. 串口线过长或受干扰。
3. STM32接收中断处理不当,未及时清除标志位或缓冲区溢出。
4. 未处理帧尾,数据粘包。
1. 用示波器或逻辑分析仪测量波特率是否准确。
2. 使用屏蔽线,缩短距离。
3. 检查中断优先级,在中断服务函数中只做最必要的操作(存数据、设标志),主循环解析。确保RXNE标志被清除。
4. 使用明确的帧头帧尾(如$开头,\n结尾),并在主循环中解析完整帧。
系统整体反应慢,卡顿1. OpenMV图像处理算法耗时过长。
2. STM32主循环中有长时间阻塞(如长延时)。
3. 模型推理速度慢。
1. 降低图像分辨率,优化检测区域(ROI),跳帧处理(如每2帧处理1帧)。
2. 将STM32所有延时改为非阻塞式。
3. 对模型进行量化、剪枝优化,或使用更轻量的模型(如MobileNetV1的深度可分离卷积版)。
OLED显示异常(花屏、不显示)1. I2C/SPI通信失败。
2. 初始化序列不正确或延时不足。
3. 屏幕供电不足。
1. 用逻辑分析仪检查I2C/SPI是否有起始信号和数据。
2. 参考屏幕数据手册,严格按初始化步骤和时序编写代码,必要时增加HAL_Delay。
3. 检查屏幕VCC电压,确保在3.3V左右,电流足够(可并联一个100uF电容)。

最后分享一个调试心得:一定要分模块调试,逐层集成。不要试图一次性把所有的代码都写完再联调。先让OpenMV单独运行,在它的IDE里看到人脸框和识别结果;再让STM32单独运行,能正确读温度和显示;最后再把串口通信加上。每完成一步,都用调试器或串口打印关键变量值来验证。遇到问题,先用最简化的测试程序(例如,STM32只循环发送一个字符给OpenMV)来排除硬件连接和基础配置问题。耐心和细致的调试,是项目成功的关键。这个系统虽然涉及的技术点不少,但每个部分都有成熟的方案和社区支持,只要你愿意动手,一定能把它搭建起来。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询