Feather AMG8833 IR thermal camera and resistive touchscreen
-
Hi everyone, it is my first post on this forum, so it is better to precise that I am a newbie in the world of programming.
I bought a Adafruit HUZZAH32 - ESP32 Feather (assembled with plain and stacking headers), a Adafruit 3.5" 480x320 TFT FeatherWing and a Adafruit AMG8833 IR Thermal Camera FeatherWing (I soldered the headers myself). The aim of my project is to make a thermal camera. So I connected the TFT and the Thermal camera to the ESP32 feather, I tested with some examples found in the specific libraries (touchpaint_featherwing and thermal_cam_interpolate) and it works very well. I modified the code to add some temperature scale.
Now, I try to improve this wonderful tool: I want to use the resistive touchscreen TFT to increase the maximal and minimal temperature of the thermal camera, by pressing the TFT at specific location. So I modify my code (based on the touchpaint_featherwing example) and I supposed it is good, but the results is that the thermal camera works for a frame and then freeze. And touching the TFT at the specific location doesn't change anything.
I incorporate my code at the end of this post.
I noticed if I comment the line #23 "Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);", #103 "TouchTFT();" and at the line #162 all the function "void TouchTFT(){...}", the thermal camera doesn't freeze (but of course touching the TFT doesn't work due to the comment of the function TouchTFT() ) and it works well as before.Is it not possible to use the thermal camera and the resistive touchscreen of the TFT in the same time?
Thank you for your help.
#include <Adafruit_GFX.h> #include <Adafruit_HX8357.h> #include <SPI.h> #include <Wire.h> #include <Adafruit_AMG88xx.h> #include <Adafruit_STMPE610.h> #define STMPE_CS 32 #define TFT_CS 15 #define TFT_DC 33 #define SD_CS 14 #define TS_MINX 3800 #define TS_MAXX 100 #define TS_MINY 100 #define TS_MAXY 3750 #define TFT_RST -1 Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, TFT_RST); Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS); int MINTEMP = 15; int MAXTEMP = 28; 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,}; Adafruit_AMG88xx amg; unsigned long delayTime; #define AMG_COLS 8 #define AMG_ROWS 8 float pixels[AMG_COLS * AMG_ROWS]; #define INTERPOLATED_COLS 24 #define INTERPOLATED_ROWS 24 float get_point(float *p, uint8_t rows, uint8_t cols, int8_t x, int8_t y); void set_point(float *p, uint8_t rows, uint8_t cols, int8_t x, int8_t y, float f); void get_adjacents_1d(float *src, float *dest, uint8_t rows, uint8_t cols, int8_t x, int8_t y); void get_adjacents_2d(float *src, float *dest, uint8_t rows, uint8_t cols, int8_t x, int8_t y); float cubicInterpolate(float p[], float x); float bicubicInterpolate(float p[], float x, float y); void interpolate_image(float *src, uint8_t src_rows, uint8_t src_cols, float *dest, uint8_t dest_rows, uint8_t dest_cols); void setup() { delay(500); Serial.begin(115200); tft.begin(); tft.setRotation(135); tft.fillScreen(HX8357_BLACK); if (!amg.begin()) { while (1) { delay(1); } } DrawButtons(); } void loop() { amg.readPixels(pixels); float dest_2d[INTERPOLATED_ROWS * INTERPOLATED_COLS]; int32_t t = millis(); interpolate_image(pixels, AMG_ROWS, AMG_COLS, dest_2d, INTERPOLATED_ROWS, INTERPOLATED_COLS); uint16_t boxsize = min(tft.width() / INTERPOLATED_COLS, tft.height() / INTERPOLATED_COLS); drawpixels(dest_2d, INTERPOLATED_ROWS, INTERPOLATED_COLS, boxsize, boxsize, false); DrawLegend(); TouchTFT(); // delay(50); } void drawpixels(float *p, uint8_t rows, uint8_t cols, uint8_t boxWidth, uint8_t boxHeight, boolean showVal) { int colorTemp; 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); colorIndex = constrain(colorIndex, 0, 255); uint16_t color; color = val * 2; tft.fillRect(160+5+boxWidth * y, 308 - (5+boxHeight * x), boxWidth, boxHeight, camColors[colorIndex]); if (showVal) { tft.setCursor(boxWidth * y + boxWidth/2 - 12, 40 + boxHeight * x + boxHeight/2 - 4); tft.setTextColor(HX8357_WHITE); tft.setTextSize(1); tft.print(val,1); } } } } void DrawLegend() { float diff = MAXTEMP - MINTEMP; for (int ii = 0; ii < 255; ii += 1) { tft.fillRect(130, 300-1*ii, 30, 1, camColors[ii]); } for (int ii = 0; ii < 6; ii += 1) { tft.fillRect(120, 300-51*ii, 10, 2, camColors[ii*255/5]); tft.setTextSize(1); tft.setTextColor(camColors[ii*255/5]); tft.setCursor(85, 297-51*ii); tft.print(MINTEMP + ii*diff/5); } } void DrawButtons() { const char* butname[] = {"M+","M-","SD","m+","m-"}; for (int ii = 0; ii < 5; ii += 1) { tft.fillRect(10, 20+60*ii, 50, 30, HX8357_WHITE); tft.setTextSize(2); tft.setTextColor(HX8357_BLACK); tft.setCursor(25, 30+60*ii); tft.print(butname[ii]); } } void TouchTFT() { TS_Point p = ts.getPoint(); p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width()); p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height()); if (p.x > 10 && p.x < 60) { if (p.y > 20 && p.y < 50) { MAXTEMP = MAXTEMP + 1; tft.fillRect(10, 20+60*ii, 50, 30, HX8357_BLACK); } else if (p.y > 80 && p.y < 110) { MAXTEMP = MAXTEMP - 1; } else if (p.y > 140 && p.y < 170) { MAXTEMP = MAXTEMP; } else if (p.y > 200 && p.y < 230) { MINTEMP = MINTEMP + 1; } else if (p.y > 260 && p.y < 290) { MINTEMP = MINTEMP -1; } } }