Wednesday, November 1, 2023

MLX90640 and ESP32 Thermal Imaging Camera with 2.8" TFT SPI

I decided to update my old thermal imaging camera.  Back in 2020 I had built a AMG8833 based camera.  Its resolution was only 8x8 pixels.  The MLX90640 is 32x24 pixels, that is a huge improvement for about $40.  I was hoping that I could just unplug the one sensor and plug in the new one.  Things are never that simple!  

This is a picture of the completed project.  The camera does not do a good job.  I tried multiple cameras and they all fail to show the varying shades of colors!  BTW that is me holding the camera.




This is a picture from the blog post about the AMG8833:


For several hours I tried to get the module to work.  When using a I2C scanner I got various responses back for several addresses.  Eventually I discovered that if I powered down then up the module I would get the correct I2C address aback (0x033) but it still would not work with the Adafruit MLX90640_Simpletest example program. Then I realized that the module I have has an extra IC on it. I had ordered a MLX90640 module on eBay for a little over $40.  Eventually I discovered that on the back it says GY-MCU90640 and looked up the manual for that module.
The manual is as clear as mud.  However I was able to guess that I needed to jumper the two solder pads together to get the I2C mode to work properly. Without that jumper it is configured for serial communication.

I could not get the sparkfun MLX90640 library to load or run.  That was desired to be able to use some software already available on the web. So I was stuck with the Adafruit library that was easily installed within the Arduino IDE.  But I had to write my own interface for the LCD screen.  Then I added the screen support to the simpletest program instead of sending the results to the serial port.  Make sure you also install the ILI9341 driver within the Arduino IDE.

Connections:
LCD:
26=C/D
18=SCK
19=MISO
23=MOSI
5=CS0
3.3V=VCC,RES,LED (Jumpered on display)
GND=GND

MLX90640
22=SCL
21=SDA
3.3V=VIN
GND=GND

Here is my code:

#include <Adafruit_MLX90640.h>

#include "Adafruit_GFX.h"

#include "Adafruit_ILI9341.h"

#include "SPI.h"

#define PRINT_ASCIIART

// Use the default pins for all but:

#define TFT_CS    5 

#define TFT_DC   26


Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

Adafruit_MLX90640 mlx;

float frame[32*24]; // buffer for full frame of temperatures

int r,g,b;


void setup() {

  Serial.begin(115200);

  delay(100);

  if (! mlx.begin(MLX90640_I2CADDR_DEFAULT, &Wire)) {

    Serial.println("MLX90640 not found!");

    while (1) delay(10);

  }

  Serial.println("Found Adafruit MLX90640");

  Serial.print("Serial number: ");

  Serial.print(mlx.serialNumber[0], HEX);

  Serial.print(mlx.serialNumber[1], HEX);

  Serial.println(mlx.serialNumber[2], HEX);

  

  mlx.setMode(MLX90640_CHESS);

  mlx.setResolution(MLX90640_ADC_18BIT);

  mlx.setRefreshRate(MLX90640_2_HZ);


  // Screen setup       

  tft.begin();

  tft.setRotation(3);

  tft.fillScreen(ILI9341_BLACK);

  tft.setTextSize(2);

}


void loop() {

  if (mlx.getFrame(frame) != 0) {

    Serial.println("Failed");

    return;  }

    // determine the ranges

    int maxt=0;

    int mint=255;

    for (uint8_t h = 0; h < 24; h++) {

      for (uint8_t w = 0; w < 32; w++) {

        int t = frame[h*32 + w];             

        if (t > maxt) maxt=t ;

        if (t < mint) mint=t ;

      }

    }

    tft.setCursor(0, 210);

    tft.print("IR Camera Max Temp: "); 

    tft.fillRect(230, 210, 32, 16, ILI9341_BLACK );

    tft.setCursor(230, 210);

    tft.print(maxt);

    // drawing the picture

    for (uint8_t h = 0; h < 24; h++) {

      for (uint8_t w = 0; w < 32; w++) {

        int t = frame[h*32 + w]; 

        r=0; g=0; b=0;

        int t2= map(t, mint, maxt, 0, 255);

        if (t2 > 70) r = t2+120;

        if (r > 255) r=255;

        if (t2 > 130) g = t2; // Highlight higher temps

        if (t2 < 70) b = 255-t2; // More blue=colder

        tft.fillRect(w * 8, h * 8, 8, 8, tft.color565(r, g, b));

      }

    }

}

Here are several views of the completed wiring if you need something to compare yours to.







No comments: