1. 项目概述
这个基于单片机的红外热视仪项目是我去年指导学弟完成的一个毕业设计,当时选择这个课题主要考虑到几个因素:首先红外热成像技术确实很实用,从工业检测到安防监控都有广泛应用;其次市面上现成的热像仪动辄上万,用单片机实现一个低成本方案很有意义;最后这个项目软硬件结合,能全面锻炼学生的工程能力。
从最终效果来看,这个设计确实达到了预期目标:用不到300元的成本实现了一个能显示热像图并具备高温报警功能的完整系统。特别值得一提的是,我们采用的AMG8833红外传感器模块虽然分辨率只有8×8,但通过插值算法成功实现了85×85的热像显示,效果相当不错。
2. 硬件设计详解
2.1 核心器件选型
主控芯片选择:
我们最终选用Arduino Nano而不是STM32,主要基于几点考虑:
- 开发环境友好,库支持完善,特别适合毕业设计这种时间有限的项目
- 虽然性能不如STM32,但处理8×8的温度矩阵和TFT显示绰绰有余
- 成本更低(约20元),且自带USB转串口,调试方便
红外传感器对比:
市面上常见的低成本红外传感器主要有MLX90640和AMG8833两种:
- MLX90640(32×24分辨率)价格约400元
- AMG8833(8×8分辨率)价格约150元
考虑到毕业设计的预算限制,我们选择了AMG8833。虽然分辨率低,但通过后续的插值算法可以弥补这一缺陷。
显示模块选型:
TFT屏幕我们测试了三种:
- 0.96寸OLED(128×64):显示区域太小
- 1.44寸TFT(128×128):勉强可用但细节不够
- 1.8寸TFT(128×160):最终选择,显示效果最佳
2.2 电路设计要点
整个硬件系统由以下几个关键部分组成:
-
电源模块:
- 采用AMS1117-3.3V稳压芯片为AMG8833供电
- Arduino Nano直接由USB或7-12V直流供电
- 重要经验:AMG8833对电源噪声敏感,必须加装100nF去耦电容
-
传感器接口:
- AMG8833通过I2C通信(SCL/SDA)
- 特别注意:I2C需要上拉电阻(4.7kΩ)
- DS18B20温度传感器用于环境温度补偿,接单总线
-
显示接口:
- TFT采用SPI接口(CS/DC/RST/MOSI/SCK)
- 为节省IO口,我们没有接MISO(不需要读取屏幕数据)
-
报警模块:
- 蜂鸣器接PWM引脚(D3)实现可调音调
- LED报警灯接普通IO口(D4)
硬件设计最容易出问题的是I2C总线,我们遇到过两次故障:
- 忘记加上拉电阻导致通信失败
- 线缆过长(>20cm)引入干扰
解决方法:使用4.7kΩ上拉电阻,并尽量缩短走线距离
3. 软件设计实现
3.1 系统工作流程
整个软件系统的运行流程如下:
-
初始化阶段:
- 配置I2C时钟频率(400kHz)
- 初始化AMG8833(设置帧率、模式等)
- 初始化TFT显示屏(设置旋转方向、清屏等)
-
主循环流程:
c复制void loop() { amg.readPixels(pixels); // 读取64个温度点 convertTo8x8Matrix(); // 转换为一维数组 bilinearInterpolation(); // 双线性插值到85×85 displayHeatmap(); // 显示热像图 checkAlarm(); // 温度报警检查 delay(100); // 控制刷新率 }
3.2 核心算法解析
双线性插值算法:
这是本项目的关键技术,将8×8的原始数据插值为85×85的显示数据。基本原理是在已知四个相邻点之间进行线性插值:
code复制pixels2[hang][lie] = (1-ku)*(1-kv)*arr[a][b]
+ (1-ku)*kv*arr[a][b+1]
+ ku*(1-kv)*arr[a+1][b]
+ ku*kv*arr[a+1][b+1];
其中ku和kv是插值权重系数,通过12等分实现11个插值点:
c复制if(hang%12==0){ku=0;}
if(hang%12==1){ku=0.0833;} // 1/12
if(hang%12==2){ku=0.1666;} // 2/12
...
if(hang%12==11){ku=0.9166;} // 11/12
温度-颜色映射:
我们预定义了一个256色的调色板camColors[],将温度映射到不同颜色:
c复制uint8_t colorIndex = map(pixels3[i], MINTEMP, MAXTEMP, 0, 255);
colorIndex = constrain(colorIndex, 0, 255);
tft.fillRect(..., camColors[colorIndex]);
3.3 关键代码优化
原始代码有几个可以优化的地方:
-
插值计算优化:
原代码使用大量if判断计算ku/kv,可以改为查表法:c复制const float k_table[12] = {0, 0.0833, 0.1666, ..., 0.9166}; ku = k_table[hang%12]; -
显示刷新优化:
只刷新温度变化超过0.5°C的区域,减少刷新量:c复制if(fabs(pixels3[i] - last_temp[i]) > 0.5){ tft.fillRect(...); last_temp[i] = pixels3[i]; } -
内存优化:
原代码使用了三个大数组(pixels、arr、pixels2),可以合并减少内存占用
4. 实现效果与测试
4.1 性能指标测试
我们对系统进行了全面测试,主要指标如下:
| 测试项目 | 测试结果 | 备注 |
|---|---|---|
| 温度测量范围 | 0°C ~ 80°C | 超出范围精度下降 |
| 测量精度 | ±2°C | 在25°C环境温度下校准 |
| 刷新率 | 5Hz | 受限于AMG8833的帧率 |
| 显示分辨率 | 85×85像素 | 实际传感器分辨率8×8 |
| 报警响应时间 | <0.5s | 从超温到触发报警的时间 |
4.2 典型应用场景
-
电子设备热检测:
- 成功检测出开发板上STM32芯片的局部过热点
- 可清晰显示USB接口的发热情况
-
人体测温:
- 在30cm距离内可检测人体体温
- 需注意环境温度补偿(使用DS18B20)
-
家用电器检测:
- 发现电热水壶底座接触不良导致的局部过热
- 观察到冰箱门封条处的冷泄漏
4.3 常见问题解决
在实际调试中我们遇到了几个典型问题:
-
热像图出现条纹干扰
- 原因:I2C时钟速度过高导致数据错误
- 解决:将I2C时钟从400kHz降至100kHz
-
温度测量值漂移
- 原因:AMG8833未进行校准
- 解决:增加两点校准(冰水混合物和沸水)
-
显示刷新闪烁
- 原因:全屏刷新导致
- 解决:改为差异刷新,只更新变化区域
5. 项目改进方向
虽然这个毕业设计已经实现了基本功能,但还有几个可以提升的方向:
-
硬件改进:
- 改用STM32F103提升处理能力
- 增加SD卡模块存储热像图
- 添加蓝牙/WiFi模块实现无线传输
-
算法优化:
- 实现更高级的三次样条插值
- 增加温度补偿算法提高精度
- 开发移动平均滤波减少噪声
-
功能扩展:
- 增加多点温度监测功能
- 实现温度变化趋势分析
- 添加PC端配置软件
这个项目最让我满意的是用极低成本实现了热成像的基本功能,学弟在毕业答辩时获得了优秀成绩。对于想尝试类似项目的同学,我的建议是先从AMG8833入手理解基本原理,等掌握了基础后再考虑升级到更高端的传感器。