ESP32+AMG8833+RGB屏240*320(ST7789)红外热成像

news/2024/11/14 4:46:50/

ESP32+AMG8833+RGB屏240*320(ST7789)红外热成像

本文是参考https://blog.csdn.net/zgj_online/article/details/104357810
来的,所用的硬件有所不同

主控:node esp-32s
显示模块:IPS(240*320)屏
热成像传感器:AMG8833

  • 关于esp32引脚功能安信可官网查看:https://docs.ai-thinker.com/
    esp32
    我是在Linux下搭建Arduino IDE的,需要改IPS屏的spi接口具体看这篇博客:https://blog.csdn.net/ironpandaaa/article/details/106870675

在这里插入图片描述
然后是AMG8833采用I2C通信,接的是SDA->21,SCL->22;
在这里插入图片描述

最后附上代码:在这里插入代码片


#include <Arduino.h>
#include <Adafruit_AMG88xx.h>
#include <Wire.h>
#include <SPI.h>#include <Button2.h>#include <TFT_eSPI.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 8Adafruit_AMG88xx amg;
unsigned long delayTime;
float pixels[AMG_COLS * AMG_ROWS];
uint16_t displayPixelWidth, displayPixelHeight;
uint16_t displayPixelX, displayPixelY;
float get_point(float *p, uint8_t rows, uint8_t cols, int8_t x, int8_t y) {if (x < 0)        x = 0;if (y < 0)        y = 0;if (x >= cols)    x = cols - 1;if (y >= rows)    y = rows - 1;return p[y * cols + x];
}void set_point(float *p, uint8_t rows, uint8_t cols, int8_t x, int8_t y, float f) {if ((x < 0) || (x >= cols)) return;if ((y < 0) || (y >= rows)) return;p[y * cols + x] = f;
}// src is a grid src_rows * src_cols
// dest is a pre-allocated grid, dest_rows*dest_cols
void interpolate_image(float *src, uint8_t src_rows, uint8_t src_cols, float *dest, uint8_t dest_rows, uint8_t dest_cols) {float mu_x = (src_cols - 1.0) / (dest_cols - 1.0);float mu_y = (src_rows - 1.0) / (dest_rows - 1.0);float adj_2d[16]; // matrix for storing adjacentsfor (uint8_t y_idx=0; y_idx < dest_rows; y_idx++) {for (uint8_t x_idx=0; x_idx < dest_cols; x_idx++) {float x = x_idx * mu_x;float y = y_idx * mu_y;//Serial.print("("); Serial.print(y_idx); Serial.print(", "); Serial.print(x_idx); Serial.print(") = ");//Serial.print("("); Serial.print(y); Serial.print(", "); Serial.print(x); Serial.print(") = ");get_adjacents_2d(src, adj_2d, src_rows, src_cols, x, y);/*Serial.print("[");for (uint8_t i=0; i<16; i++) {Serial.print(adj_2d[i]); Serial.print(", ");}Serial.println("]");*/float frac_x = x - (int)x; // we only need the ~delta~ between the pointsfloat frac_y = y - (int)y; // we only need the ~delta~ between the pointsfloat out = bicubicInterpolate(adj_2d, frac_x, frac_y);//Serial.print("\tInterp: "); Serial.println(out);set_point(dest, dest_rows, dest_cols, x_idx, y_idx, out);}}
}// p is a list of 4 points, 2 to the left, 2 to the right
float cubicInterpolate(float p[], float x) {float r = p[1] + (0.5 * x * (p[2] - p[0] + x*(2.0*p[0] - 5.0*p[1] + 4.0*p[2] - p[3] + x*(3.0*(p[1] - p[2]) + p[3] - p[0]))));/*Serial.print("interpolating: ["); Serial.print(p[0],2); Serial.print(", ");Serial.print(p[1],2); Serial.print(", ");Serial.print(p[2],2); Serial.print(", ");Serial.print(p[3],2); Serial.print("] w/"); Serial.print(x); Serial.print(" = ");Serial.println(r);*/return r;
}// p is a 16-point 4x4 array of the 2 rows & columns left/right/above/below
float bicubicInterpolate(float p[], float x, float y) {float arr[4] = {0,0,0,0};arr[0] = cubicInterpolate(p+0, x);arr[1] = cubicInterpolate(p+4, x);arr[2] = cubicInterpolate(p+8, x);arr[3] = cubicInterpolate(p+12, x);return cubicInterpolate(arr, y);
}// src is rows*cols and dest is a 4-point array passed in already allocated!
void get_adjacents_1d(float *src, float *dest, uint8_t rows, uint8_t cols, int8_t x, int8_t y) {//Serial.print("("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.println(")");// pick two items to the leftdest[0] = get_point(src, rows, cols, x-1, y);dest[1] = get_point(src, rows, cols, x, y);// pick two items to the rightdest[2] = get_point(src, rows, cols, x+1, y);dest[3] = get_point(src, rows, cols, x+2, y);
}// src is rows*cols and dest is a 16-point array passed in already allocated!
void get_adjacents_2d(float *src, float *dest, uint8_t rows, uint8_t cols, int8_t x, int8_t y) {//Serial.print("("); Serial.print(x); Serial.print(", "); Serial.print(y); Serial.println(")");float arr[4];for (int8_t delta_y = -1; delta_y < 3; delta_y++) { // -1, 0, 1, 2float *row = dest + 4 * (delta_y+1); // index into each chunk of 4for (int8_t delta_x = -1; delta_x < 3; delta_x++) { // -1, 0, 1, 2row[delta_x+1] = get_point(src, rows, cols, x+delta_x, y+delta_y);}}
}
/* 画温度颜色对比条 */
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<colorSize; i++) {int x = i/barHeight;tft.drawLine(14+x*barWidth, barHeight-i%barHeight+posY, 14+x*barWidth+barWidth, barHeight-i%barHeight+posY, camColors[255-i]);}tft.setTextSize(1);tft.setTextDatum(BL_DATUM);tft.setTextColor(camColors[colorSize-1]);tft.drawString(String(MINTEMP), 0, tft.height());tft.setTextColor(camColors[barHeight-1]);tft.drawString(String(MINTEMP+int(MAXTEMP-MINTEMP)/2), 38, tft.height());tft.setTextDatum(TL_DATUM);tft.setTextColor(camColors[barHeight]);tft.drawString(String(MINTEMP+int(MAXTEMP-MINTEMP)/2), 0, 0);tft.setTextColor(camColors[0]);tft.drawString(String(MAXTEMP), 38, 0);
}/* 画热成像素点 */
void drawpixels(float *p, uint8_t rows, uint8_t cols, uint8_t boxWidth, uint8_t boxHeight, boolean showVal) {int colorTemp;float curMax = get_point(p, rows, cols, 0, 0), curMin = get_point(p, rows, cols, 0, 0), curMid = get_point(p, rows, cols, cols/2, rows/2);uint16_t colorMax = camColors[0], colorMin = camColors[0],colorMid = camColors[0]; //画热成像for (int y=0; y<rows; y++) {for (int x=0; x<cols; x++) {float val = get_point(p, rows, cols, x, y);if(val >= MAXTEMP) colorTemp = MAXTEMP;else if(val <= MINTEMP) colorTemp = MINTEMP;else colorTemp = val;//      uint8_t colorIndex = map(colorTemp, MINTEMP, MAXTEMP, 0, 255);uint8_t colorIndex = map(colorTemp, MINTEMP, MAXTEMP, 255, 0);   //取值重要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 settingsstatus = 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 pixelsamg.readPixels(pixels);/* for(int i=0; i<AMG88xx_PIXEL_ARRAY_SIZE; i++){uint8_t colorIndex = map(pixels[i], MINTEMP, MAXTEMP, 0, 255);colorIndex = constrain(colorIndex, 0, 255);//draw the pixels!tft.fillRect(displayPixelX+displayPixelHeight * floor(i / 8), displayPixelY+displayPixelWidth * (i % 8),displayPixelHeight, displayPixelWidth, camColors[colorIndex]);} *//* Serial.print("[");for(int i=1; i<=AMG88xx_PIXEL_ARRAY_SIZE; i++){Serial.print(pixels[i-1]);Serial.print(", ");if( i%8 == 0 ) Serial.println();}Serial.println("]");Serial.println(); */float dest_2d[INTERPOLATED_ROWS * INTERPOLATED_COLS];//int32_t t = millis();interpolate_image(pixels, AMG_ROWS, AMG_COLS, dest_2d, INTERPOLATED_ROWS, INTERPOLATED_COLS);/* Serial.print("Interpolation took "); Serial.print(millis()-t); Serial.println(" ms"); */uint16_t boxsize = min(tft.width() / INTERPOLATED_COLS, tft.height() / INTERPOLATED_COLS);drawpixels(dest_2d, INTERPOLATED_ROWS, INTERPOLATED_COLS, boxsize, boxsize, false);//delay(100);
}

头文件就是加载的库,最重要的是AMG8833传感器这个
在这里插入图片描述


http://www.ppmy.cn/news/203389.html

相关文章

MTK8188平台

MTK8188平台 AWB模块 PB Weight 往上为紫&#xff0c;往下为绿&#xff0c;往左为红&#xff0c;往右为蓝 分为有白点的流程和没白点的流程 一共分为96*128个block然后剔除很亮和很暗的pixel&#xff0c;然后将每四个child block称为parent block 烧录otp的时候一般是单色…

AMG8833 8x8热成像传感器

文章目录 前言一、如何使用AMG8833二、配置头文件.h,.c文件2.1.IIC头文件&#xff0c;C文件2.2.AMG8833模块的驱动文件&#xff0c;.h,.c 三、Keil相关配置3.1.路径添加 四、主函数编写4.1测试结果 总结及注意事项 前言 AMG8833这款传感器是 8x8 红外热传感器阵列。 当连接到您…

STC8H8K64U——74HC595

74HC595 单片74HC595驱动程序&#xff0c;实现八个LED灯依次点亮。 /* 频率&#xff1a;100MHz Q0~Q7并行三态输出端 OE 输出使能端&#xff0c;高电平时&#xff0c;移位寄存器清零&#xff0c;Q0~Q7处于高阻态。 MR 主复位&#xff0c;低电平时&#xff0c;移位寄存器清零。…

『STC8H8K64U』概述

preface 大家好&#xff0c;我是初尧.C。希望看完这篇文章对你能有所帮助&#xff0c;不足之处请指正~&#x1f4dd; 本文由初尧.C 原创 CSDN首发 如需转载还请通知&#x1f6ab; &#x1f4cc;无端坠入凡生梦. 却惹三千烦恼丝&#x1f4cc; 欢迎各位&#x1f498;点赞收藏留言…

ChatGLM-6b 多任务微调

ChatGLM-6b也是一种预训练模型&#xff0c;它也可以通过微调来适应下游任务。实验表明&#xff0c;使用ChatGLM-6b微调和Bert类预训练模型微调的效果相近。如果采用多任务设计&#xff0c;ChatGLM-6b的效果会更好。你可以在这里了解更多关于ChatGLM-6B的信息: ChatGLM-6Bhttps:…

「HTML和CSS入门指南」h 标签详解

什么是<h>标签? 在 HTML 中,<h> 标签是用于定义标题的标签。HTML5 中共有六个不同等级的 <h> 标签,从 <h1> 到 <h6>,分别用于表示不同级别的标题。 <h> 标签的语法和属性 <h> 标签的语法非常简单,只需要在 HTML 文件中插入 &l…

单反相机手动拍摄技巧

1、拍静止的小东西的特写&#xff0c;如花、鸟、虫&#xff1a; 用Av档&#xff0c;光圈最好在f5.6或以下&#xff0c;焦距最好50以上&#xff0c;尽量在1m以内拍摄&#xff0c;使背景虚化&#xff01; 光线好的话&#xff0c;iso100&#xff0c;光线不好的话&#xff0c;iso最…

计算机主板 辐射,想当年单反镜头竟然还有核辐射?

我和我的小伙伴都惊呆了,相机镜头有核辐射该怎么办: 电脑也好,手机也好,说到底它们的辐射都只是电磁辐射,生活中可谓无处不在,但相机镜头竟然可能有核辐射,这是怎么回事?又该怎么办? 高端老镜头或有辐射 “辐射镜头”指的是一些采用了稀土镜片的胶片时代老镜头,因为画…