If you don’t want to miss my updates, remember to check the public account in the upper right corner and set it as a star, take down the stars and give them to me.


Today I am sharing a project to make a DIY infrared thermal imager.

● Parallel TFT touch based on ESP32-S3, resolution 320*240:

The reason for using this touch is: 1) Its refresh rate is much higher than that of SPI displays, 2) Based on ESP32-S3, combined with WiFi, it can directly transmit data/results to the local network for remote monitoring.
● MLX90640 infrared thermal imager specifically designed for this application.

● A set of acrylic casing designed for this, with laser cutting:

This project uses very few components, and the hardware assembly is very simple.
The thermal imaging camera communicates with the controller via I2C, with an I2C address of 0x33, while the ESP32-S3 parallel TFT has a built-in connector for external sensors (I2C/GPIO), so the thermal imaging camera is connected to the TFT via a simple plug-and-play cable:

Insert the SD card into the SD slot for data storage:

The firmware is the core work of this application, and for the MLX90640, the Adfruit_MLX90640 Lib is used.Additionally, since the raw data obtained from the MLX90640 is 32 * 24 data with noise, it needs more processing:
1) Filter the data to smooth the display.
Void filter_frame(float *in, float *out){ if (MLX_MIRROR == 1) { for (int i = 0; i < 32 * 24; i++) { out[i] = (out[i] + in[i]) / 2; } } else { for (int i = 0; i < 24; i++) for (int j = 0; j < 32; j++) { out[32 * i + 31 - j] = (out[32 * i + 31 - j] + in[32 * i + j]) / 2; } }}
void qusort(float s[], int start, int end){ int i, j; i = start; j = end; s[0] = s[start]; while (i < j) { while (i < j && s[0] < s[j]) j--; if (i < j) { s[i] = s[j]; i++; } while (i < j && s[i] <= s[0]) i++; if (i < j) { s[j] = s[i]; j--; } } s[i] = s[0]; if (start < i) qusort(s, start, j - 1); if (i < end) qusort(s, j + 1, end);}
//Transform 32*24 to 320 * 240 pixelvoid interpolation(float *data, uint16_t *out){ for (uint8_t h = 0; h < 24; h++) { for (uint8_t w = 0; w < 32; w++) { out[h * 10 * 320 + w * 10] = map_f(data[h * 32 + w], MINTEMP, MAXTEMP); } } for (int h = 0; h < 240; h += 10) { for (int w = 1; w < 310; w += 10) { for (int i = 0; i < 9; i++) { out[h * 320 + w + i] = (out[h * 320 + w - 1] * (9 - i) + out[h * 320 + w + 9] * (i + 1)) / 10; } } for (int i = 0; i < 9; i++) { out[h * 320 + 311 + i] = out[h * 320 + 310]; } } for (int w = 0; w < 320; w++) { for (int h = 1; h < 230; h += 10) { for (int i = 0; i < 9; i++) { out[(h + i) * 320 + w] = (out[(h - 1) * 320 + w] * (9 - i) + out[(h + 9) * 320 + w] * (i + 1)) / 10; } } for (int i = 0; i < 9; i++) { out[(231 + i) * 320 + w] = out[230 * 320 + w]; } } for (int h = 0; h < 240; h++) { for (int w = 0; w < 320; w++) { out[h * 320 + w] = camColors[out[h * 320 + w]]; } }
Comparison of outputs with/without linear interpolation algorithm:


After programming, power the system with a 5V source via USB-C, the display works normally, and temperature is detected:

All temperatures can be stored on the SD card for storage.
Moreover, because the main control room ESP32 WiFi, all data and images can be displayed and stored on the local network PC or smartphone, a simple temperature display was made with Python:

Original link:
https://github.com/Makerfabs/ESP32-S2-MLX90640-Touch-Screen-Thermal-Camera/tree/main/firmware/Thermal_Camera_V2

<<< STM32 project summary >>>
<<< Raspberry Pi project summary >>>
<<< ESP32 project summary >>>
<<< ESP8266 project summary >>>
<<< Arduino project summary >>>
<<< Darwin project sharing all series >>>