【电子DIY作品】看见温度的红外成像仪

[复制链接]
查看309 | 回复9 | 2024-8-1 11:01:23 | 显示全部楼层 |阅读模式
图片1.png

1、硬件介绍:
M5StickC PLUS主控采用ESP32-PICO-D4模组,,具备蓝牙4.2与WIFI功能,小巧的机身内部集成了丰富的硬件资源,如红外、RTC、麦克风、LED、IMU、按键、蜂鸣器、PMU等,屏幕尺寸1.14寸、135*240分辨率的TFT屏幕,电池容量达到120mAh。
AMG8833这款传感器是 8x8 红外热传感器阵列。 它将通过 I2C 返回一组 64 个单独的红外温度读数。测量范围从 0°C 到 80°C(32°F 到 176°F)的温度,精度为 ± 2.5°C (4.5°F)。最远可探测7 米的距离,最大帧速率为 10Hz。
图片2.png
2、开发环境:
软件开发上使用Vscode+platformIO,使用arduino进行开发。调用了官方的M5stack的库和AMG88的库文件。
  1. [env:m5stick-c]
  2. platform = espressif32
  3. board = m5stick-c
  4. framework = arduino
  5. monitor_speed = 115200
  6. lib_deps =
  7.   # RECOMMENDED
  8.   # Accept new functionality in a backwards compatible manner and patches
  9.   m5stack/M5StickCPlus @ ^0.1.0
  10.   sparkfun/SparkFun GridEYE AMG88 Library @ ^1.0.2
复制代码
3、软件开发:
图片3.png
软件流程很简单,首先读取AMG8833,读取出的信息为一个8*8的浮点数温度矩阵。因为传感器的限制,读取到的原始温度矩阵分辨率只有64个点,这里需要对矩阵进行扩大,每两个点之间插入5个点,使得矩阵扩展到43*43个点的矩阵。扩展的方式为双线性插值法。即在两个方向分别进行一次线性插值(首先在一个方向上使用线性插值,然后再在另一个方向上使用线性插值执行双线性插值。尽管每个步骤在采样值和位置上都是线性的,但是插值总体上不是线性的,而是在采样位置上是二次的。
  1. float BilinearInterpolation(float q11, float q12, float q21, float q22, float x1, float x2, float y1, float y2, float x, float y)
  2. {
  3.   float x2x1, y2y1, x2x, y2y, yy1, xx1;
  4.   x2x1 = x2 - x1;
  5.   y2y1 = y2 - y1;
  6.   x2x = x2 - x;
  7.   y2y = y2 - y;
  8.   yy1 = y - y1;
  9.   xx1 = x - x1;
  10.   return 1.0 / (x2x1 * y2y1) * (q11 * x2x * y2y + q21 * xx1 * y2y + q12 * x2x * yy1 + q22 * xx1 * yy1);
  11. }

  12. //插值算法 8*8点阵过于稀疏,使用插值方式 放大点阵
  13. void zoommix()
  14. {
  15.   //取4个点的值
  16.   float q11, q12, q21, q22;
  17.   uint8_t x11, x22, y11, y22;
  18.   for (uint8_t row = 0; row < SHARP; row++)
  19.   { //遍历原始数据的每一个点
  20.     for (uint8_t col = 0; col < SHARP; col++)
  21.     {
  22.       q11 = pixels[row][col];
  23.       x11 = row * INSERT + row;
  24.       y11 = col * INSERT + col;
  25.       q12 = pixels[row][col + 1 == SHARP ? SHARP - 1 : col + 1];
  26.       q21 = pixels[row + 1 == SHARP ? SHARP - 1 : row + 1][col];
  27.       q22 = pixels[row + 1 == SHARP ? SHARP - 1 : row + 1][col + 1 == SHARP ? SHARP - 1 : col + 1];
  28.       x22 = (row + 1) * INSERT + row + 1;
  29.       y22 = (col + 1) * INSERT + col + 1;

  30.       //插入值
  31.       for (uint8_t xpos = 0; xpos <= INSERT; xpos++)
  32.       {
  33.         for (uint8_t ypos = 0; ypos <= INSERT; ypos++)
  34.         {
  35.           if (x11 + xpos < SHARP + INSERT * (SHARP - 1) && y11 + ypos < SHARP + INSERT * (SHARP - 1))
  36.           {
  37.             HDTemp[x11 + xpos][y11 + ypos] = BilinearInterpolation(q11, q12, q21, q22, x11, x22, y11, y22, x11 + xpos, y11 + ypos);
  38.           }
  39.         }
  40.       }
  41.     }
  42.   }
  43. }
复制代码
扩展后的矩阵是一个43*43个点的浮点数矩阵。需要使用图像的方式将矩阵展示出来。首先获取矩阵中最高、最低的温度值。将最低到最高温度映射到色彩空间上去,然后使用伪彩色对矩阵进行展示。
  1. void Getabcd()
  2. {
  3.   a = MinTemp + (MaxTemp - MinTemp) * 0.2121;
  4.   b = MinTemp + (MaxTemp - MinTemp) * 0.3182;
  5.   c = MinTemp + (MaxTemp - MinTemp) * 0.4242;
  6.   d = MinTemp + (MaxTemp - MinTemp) * 0.8182;
  7. }

  8. //浮点数转颜色  伪彩色
  9. uint16_t GetColor(float val)
  10. {
  11.   byte red = 0, green = 0, blue = 0;
  12.   red = constrain(255.0 / (c - b) * val - ((b * 255.0) / (c - b)), 0, 255);
  13.   if ((val > MinTemp) & (val < a))
  14.   {
  15.     green = constrain(255.0 / (a - MinTemp) * val - (255.0 * MinTemp) / (a - MinTemp), 0, 255);
  16.   }
  17.   else if ((val >= a) & (val <= c))
  18.   {
  19.     green = 255;
  20.   }
  21.   else if (val > c)
  22.   {
  23.     green = constrain(255.0 / (c - d) * val - (d * 255.0) / (c - d), 0, 255);
  24.   }
  25.   else if ((val > d) | (val < a))
  26.   {
  27.     green = 0;
  28.   }

  29.   if (val <= b)
  30.   {
  31.     blue = constrain(255.0 / (a - b) * val - (255.0 * b) / (a - b), 0, 255);
  32.   }
  33.   else if ((val > b) & (val <= d))
  34.   {
  35.     blue = 0;
  36.   }
  37.   else if (val > d)
  38.   {
  39.     blue = constrain(240.0 / (MaxTemp - d) * val - (d * 240.0) / (MaxTemp - d), 0, 240);
  40.   }

  41.   // use the displays color mapping function to get 5-6-5 color palet (R=5 bits, G=6 bits, B-5 bits)
  42.   return M5.Lcd.color565(red, green, blue);
  43. }
  44. void DisplayGradient()
  45. {
  46.   uint8_t row, col;
  47.   for (row = 0; row < SHARP + INSERT * (SHARP - 1); row++)
  48.   {
  49.     for (col = 0; col < SHARP + INSERT * (SHARP - 1); col++)
  50.     {
  51.       M5.Lcd.fillRect(row*3,col*3,3,3, GetColor(HDTemp[row][col]));
  52.     }
  53.   }
  54. }
复制代码
3、效果演示:
图片4.png
这是拍摄热水保温杯的效果,杯子没有盖盖。可以看见杯口温度明显高于周边。
图片5.png
这是拍摄正在工作的空调的照片,可以看见冷气吹出来。
整体来说,AMG8833分辨率还是太低了,无法呈现清晰的物体,而且远处的物体就显示的不很好了,温度显示也不是很准确。不能像电影里那样显示清晰的温度画面。但是作为日常工具还是不错的,检查高温热源,简单的测量温度,日常维修还是能用一用的!
m5plus.zip (1.07 MB, 下载次数: 0)

回复

使用道具 举报

WT_0213 | 2024-8-1 11:25:50 | 显示全部楼层
这个好厉害
回复 支持 反对

使用道具 举报

粉肠 | 2024-8-1 12:32:28 | 显示全部楼层
大佬
回复

使用道具 举报

爱笑 | 2024-8-1 13:55:34 | 显示全部楼层
优秀!
用心做好保姆工作
回复

使用道具 举报

MrZeFr | 2024-8-1 14:00:45 | 显示全部楼层
我有这个,但放着吃灰
回复 支持 反对

使用道具 举报

小小鸟 | 2024-8-1 16:56:28 | 显示全部楼层
厉害
回复

使用道具 举报

WildboarG | 2024-8-1 17:04:36 | 显示全部楼层
学习
回复

使用道具 举报

djy876 | 2024-8-2 08:47:17 | 显示全部楼层
这个AMG8833需要多少钱
回复 支持 反对

使用道具 举报

Francisliu | 2024-8-2 09:15:37 | 显示全部楼层
AMG8833这个还不错
回复 支持 反对

使用道具 举报

bzhou830 | 2024-8-2 14:15:35 | 显示全部楼层
优秀!
选择去发光,而不是被照亮
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则