# esp32_amg8833 **Repository Path**: cnghosth/esp32_amg8833 ## Basic Information - **Project Name**: esp32_amg8833 - **Description**: No description available - **Primary Language**: Arduino - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 4 - **Created**: 2021-03-31 - **Last Updated**: 2021-08-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # esp32_amg8833 #### 介绍 用基于ESP32+amg8833模块开发的红外热成像测温仪,开发板用的是TTGO T-Display ESP32,测温模块用的是AMG8833 IR 8x8红外热像传感器。 在新冠战疫的环境下,不仅一罩(口罩)难求,还有一枪(测温枪)难求。咱就自己搞个测温枪吧。 最初的想法是红外测温枪+人脸识别,放在学校门口,就可以为师生每天自动记录体温了。趁全国人民做月子期间,试着做做吧。 #### 接线说明 |AMG8833|ESP32|说明| | --- | --- | --- | |VIM|5V| | |GND|GND| | |SDA|21|wire_sda| |SCL|22|wire_scl| ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200217144033497.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pnal9vbmxpbmU=,size_16,color_FFFFFF,t_70) 我淘来的amg8833板子有两排针脚的。刚开始想不明白为什么为么多针脚,了解了才知道,AMG8833字那排针脚没有啥实际意义的,就是为了方便固定用的。有针脚说明那排才有意义。 #### 开发环境 我用的是vs code+platformio,也可以直接用arduino ide。 安装Adafruit AMG88xx Library库,人家已经为你写好驱动库了,调用即可 本代码基于example里的thermal_cam_interpolate AMG8833的分辨是8*8的,要显示成图像的话,就看到一个8*8的格子,很粗,很粗,很粗。根本成不了像,thermal_cam_interpolate里的算法,是根据格子单的温度做拆分的,形成更细的分辨率,有兴趣的同学可以看看interpolate_image,该部分功能在项目里我放到了interpolation.cpp .h里了。 程序中增加了温度对比条显示,中心点温度、最高温度、最低温度。 代码在[gitee仓库](https://gitee.com/topmonkey/esp32_amg8833.git)自行取。 #### 测温效果 测个水杯的温度 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200217144155277.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pnal9vbmxpbmU=,size_16,color_FFFFFF,t_70) 测个手的温度 ![在这里插入图片描述](https://images.gitee.com/uploads/images/2020/0217/145807_763da274_398940.jpeg) 我用测温枪实测对比后,发现温度还是挺准的。 这个红红的外壳请忽视,做其它项目时的半成品。 #### main代码 ```bash #include #include #include #include #include #include #include "interpolation.h" TFT_eSPI tft = TFT_eSPI(); Button2 btn1(35); Button2 btn2(0); /*256位的温度颜色对照表*/ const uint16_t camColors[] = {0x480F, 0x400F,0x400F,0x400F,0x4010,0x3810,0x3810,0x3810,0x3810,0x3010,0x3010, 0x3010,0x2810,0x2810,0x2810,0x2810,0x2010,0x2010,0x2010,0x1810,0x1810, 0x1811,0x1811,0x1011,0x1011,0x1011,0x0811,0x0811,0x0811,0x0011,0x0011, 0x0011,0x0011,0x0011,0x0031,0x0031,0x0051,0x0072,0x0072,0x0092,0x00B2, 0x00B2,0x00D2,0x00F2,0x00F2,0x0112,0x0132,0x0152,0x0152,0x0172,0x0192, 0x0192,0x01B2,0x01D2,0x01F3,0x01F3,0x0213,0x0233,0x0253,0x0253,0x0273, 0x0293,0x02B3,0x02D3,0x02D3,0x02F3,0x0313,0x0333,0x0333,0x0353,0x0373, 0x0394,0x03B4,0x03D4,0x03D4,0x03F4,0x0414,0x0434,0x0454,0x0474,0x0474, 0x0494,0x04B4,0x04D4,0x04F4,0x0514,0x0534,0x0534,0x0554,0x0554,0x0574, 0x0574,0x0573,0x0573,0x0573,0x0572,0x0572,0x0572,0x0571,0x0591,0x0591, 0x0590,0x0590,0x058F,0x058F,0x058F,0x058E,0x05AE,0x05AE,0x05AD,0x05AD, 0x05AD,0x05AC,0x05AC,0x05AB,0x05CB,0x05CB,0x05CA,0x05CA,0x05CA,0x05C9, 0x05C9,0x05C8,0x05E8,0x05E8,0x05E7,0x05E7,0x05E6,0x05E6,0x05E6,0x05E5, 0x05E5,0x0604,0x0604,0x0604,0x0603,0x0603,0x0602,0x0602,0x0601,0x0621, 0x0621,0x0620,0x0620,0x0620,0x0620,0x0E20,0x0E20,0x0E40,0x1640,0x1640, 0x1E40,0x1E40,0x2640,0x2640,0x2E40,0x2E60,0x3660,0x3660,0x3E60,0x3E60, 0x3E60,0x4660,0x4660,0x4E60,0x4E80,0x5680,0x5680,0x5E80,0x5E80,0x6680, 0x6680,0x6E80,0x6EA0,0x76A0,0x76A0,0x7EA0,0x7EA0,0x86A0,0x86A0,0x8EA0, 0x8EC0,0x96C0,0x96C0,0x9EC0,0x9EC0,0xA6C0,0xAEC0,0xAEC0,0xB6E0,0xB6E0, 0xBEE0,0xBEE0,0xC6E0,0xC6E0,0xCEE0,0xCEE0,0xD6E0,0xD700,0xDF00,0xDEE0, 0xDEC0,0xDEA0,0xDE80,0xDE80,0xE660,0xE640,0xE620,0xE600,0xE5E0,0xE5C0, 0xE5A0,0xE580,0xE560,0xE540,0xE520,0xE500,0xE4E0,0xE4C0,0xE4A0,0xE480, 0xE460,0xEC40,0xEC20,0xEC00,0xEBE0,0xEBC0,0xEBA0,0xEB80,0xEB60,0xEB40, 0xEB20,0xEB00,0xEAE0,0xEAC0,0xEAA0,0xEA80,0xEA60,0xEA40,0xF220,0xF200, 0xF1E0,0xF1C0,0xF1A0,0xF180,0xF160,0xF140,0xF100,0xF0E0,0xF0C0,0xF0A0, 0xF080,0xF060,0xF040,0xF020,0xF800,}; //low range of the sensor (this will be blue on the screen) #define MINTEMP 14 //high range of the sensor (this will be red on the screen) #define MAXTEMP 30 /*32*32为优化后的分辨率,不宜太高,提升分辨率修改此处即可*/ #define INTERPOLATED_COLS 32 #define INTERPOLATED_ROWS 32 #define AMG_COLS 8 #define AMG_ROWS 8 Adafruit_AMG88xx amg; unsigned long delayTime; float pixels[AMG_COLS * AMG_ROWS]; uint16_t displayPixelWidth, displayPixelHeight; uint16_t displayPixelX, displayPixelY; /* 画温度颜色对比条 */ void drawTemperateBar () { const int colorSize = 256; const int barHeight = 128; const int barWidth = 10; const int posY = (tft.height()-barHeight)/2-1; for(int i=0; i= MAXTEMP) colorTemp = MAXTEMP; else if(val <= MINTEMP) colorTemp = MINTEMP; else colorTemp = val; uint8_t colorIndex = map(colorTemp, MINTEMP, MAXTEMP, 0, 255); colorIndex = constrain(colorIndex, 0, 255); //draw the pixels! tft.fillRect(displayPixelX + boxWidth * x, displayPixelY + boxHeight * y, boxWidth, boxHeight, camColors[colorIndex]); //取最大值 if(val >= curMax){ curMax = val; colorMax = camColors[colorIndex]; } //取最小值 if(val <= curMin){ curMin = val; colorMin = camColors[colorIndex]; } //取中心点 if(y == rows/2 && x == cols/2){ colorMid = camColors[colorIndex]; } if (showVal) { tft.setCursor(boxWidth * y + boxWidth/2 - 12, 40 + boxHeight * x + boxHeight/2 - 4); tft.setTextSize(1); tft.setTextColor(TFT_WHITE); tft.print(val,1); } } } //画中心点十字 uint8_t midX = displayPixelX+cols*boxWidth/2; uint8_t midY = displayPixelY+rows*boxHeight/2; tft.drawLine(midX-10, midY, midX+10, midY, TFT_WHITE); tft.drawLine(midX, midY-10, midX, midY+10, TFT_WHITE); char temp[7]; tft.setTextSize(1); tft.setTextColor(TFT_WHITE); //显示最高温度 tft.setTextDatum(TL_DATUM); tft.drawString(F("MAX"), tft.width()-40, 0); tft.fillRect(tft.width()-45, 10, 40, 30, colorMax); tft.setTextDatum(CL_DATUM); memset(temp, 0, sizeof(temp)); sprintf(temp, "%0.1f", curMax); tft.drawString(String(temp), tft.width()-40, 25); //显示最低温度 tft.setTextDatum(TL_DATUM); tft.drawString(F("MIN"), tft.width()-40, 47); tft.fillRect(tft.width()-45, 57, 40, 30, colorMin); tft.setTextDatum(CL_DATUM); memset(temp, 0, sizeof(temp)); sprintf(temp, "%0.1f", curMin); tft.drawString(String(temp), tft.width()-40, 72); //显示中心点温度 tft.setTextDatum(TL_DATUM); tft.drawString(F("POINT"), tft.width()-40, 94); tft.fillRect(tft.width()-45, 104, 40, 30, colorMid); tft.setTextDatum(CL_DATUM); memset(temp, 0, sizeof(temp)); sprintf(temp, "%0.1f", curMid); tft.drawString(String(temp), tft.width()-40, 119); } void setup() { Serial.begin(9600); //初始化屏幕 tft.init(); tft.setRotation(1); tft.fillScreen(TFT_BLACK); tft.setTextColor(TFT_WHITE); tft.setTextSize(2); tft.setTextDatum(MC_DATUM); tft.drawString(F("Thermal Camera"), tft.width()/2, tft.height()/2); delay(2000); tft.fillScreen(TFT_BLACK); displayPixelWidth = tft.height() / 8; displayPixelHeight = tft.height() / 8; displayPixelX = (tft.width() - displayPixelWidth*8)/2; displayPixelY = (tft.height() - displayPixelHeight*8)/2; drawTemperateBar(); bool status; // default settings status = amg.begin(); if (!status) { Serial.println("Could not find a valid AMG8833 sensor, check wiring!"); while (1); } Serial.println("-- Thermal Camera Test --"); delay(100); // let sensor boot up } void loop() { //read all the pixels amg.readPixels(pixels); /* for(int i=0; i