My latest project is to make a thermal camera. Adafruit has lots of info on the AMG8833 8x8 thermal camera, as well as example software to use it with a ILI9341 LCD screen.
AMG8833 -> ESP8266 -> ILI9341LCD = Thermal Camera!
The Adafruit examples include an interpolated version. Although the camera is 8x8 it calculates the colors between the pixels to yield many more pixels. The Adafruit AMG8833 tutorial is here:
https://learn.adafruit.com/adafruit-amg8833-8x8-thermal-camera-sensor
The drivers and example files are here: https://github.com/adafruit/Adafruit_AMG88xx
I made this change to the interpolate example code:
#ifdef ESP8266
#define STMPE_CS 16
#define TFT_CS D10
#define TFT_DC D9
#define SD_CS 2
#endif
Here is the back side of the LCD. I soldered jumpers to power, reset and LED to reduce the number of jumper wires needed to connect the LCD.
AMG8833 Thermal camera |
The LCD is powered by 3.3 volts and the thermal sensor is powered by 5 volts only because there is no other 3.3 volt pin available.
Here is a video of it working:
I have added a display of the maximum temperature. Basically you create two variables, scan through the readings and pick the highest temperature, then convert it to Fahrenheit and display it.
Here are the changes that are needed to the demo code to find and display the peak temperature:
int HighTemp = 0;
int HTemp = 0;
void loop() {
//read all the pixels
amg.readPixels(pixels);
Serial.print("[");
HighTemp=0;
for(int i=1; i<=AMG88xx_PIXEL_ARRAY_SIZE; i++){
Serial.print(pixels[i-1]);
Serial.print(", ");
if( i%8 == 0 ) Serial.println();
if (pixels[i-1] > HighTemp) HighTemp = pixels[i-1];
}
Serial.println("]");
Serial.println();
HTemp = ((HighTemp * 9/5) + 32);
Serial.println (HTemp);
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(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);
//draw the pixels!
uint16_t color;
color = val * 2;
tft.fillRect(boxWidth * x, boxHeight * y, boxWidth, boxHeight, camColors[colorIndex]);
if (showVal) {
tft.setCursor(boxWidth * y + boxWidth/2 - 12, 40 + boxHeight * x + boxHeight/2 - 4);
tft.setTextColor(ILI9341_WHITE); tft.setTextSize(2);
tft.print(val,1);
}
}
}
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setCursor(rows*boxWidth,0);
tft.print(" High");
tft.setCursor(rows*boxWidth,20);
tft.print(" Temp:");
tft.setCursor(rows*(boxWidth+1),40);
tft.print(HTemp);
tft.print(" ");
// }
}