Thermal imaging camera with better MLX90640 grove sensor

Is thermal imaging camera project possible with the Seeed Studio Grove - Thermal Imaging Camera / IR Array MLX90640 module that would give better imaging on Wio terminal? Could you try it?

It does work better with the MLX90640, but this one is not currently available, we will provide the corresponding demo as soon as it arrives @kalon33

I can’t get the demo program to work, it just outputs Failed to load system parameters. Any hints would be appreciated.

@rich Can you share your Sketch? Are there any messages when something goes wrong?

Below is the sketch, I was using the two libraries I downloaded as well.

It reaches out to the device, but nothing happens after that first message is sent

It outputs Failed to load system parameters.

Blockquote
/*
Output the temperature readings to all pixels to be read by a Processing visualizer
*/

#include <Wire.h>

#include “MLX90641_API.h”
#include “MLX90641_I2C_Driver.h”

#define debug SerialUSB

const byte MLX90641_address = 0x33; //Default 7-bit unshifted address of the MLX90641
#define TA_SHIFT 8 //Default shift for MLX90641 in open air

uint16_t eeMLX90641[832];
float MLX90641To[192];
uint16_t MLX90641Frame[242];
paramsMLX90641 MLX90641;
int errorno = 0;
void setup() {
Wire.begin();
Wire.setClock(400000); //Increase I2C clock speed to 400kHz

debug.begin(115200); //Fast debug as possible

while (!debug); //Wait for user to open terminal
debug.println("MLX90641 IR Array Example");

if (isConnected() == false) {
    debug.println("MLX90641 not detected at default I2C address. Please check wiring. Freezing.");
    while (1);
}

//Get device parameters - We only have to do this once
int status;
status = MLX90641_DumpEE(MLX90641_address, eeMLX90641);
errorno = status;//MLX90641_CheckEEPROMValid(eeMLX90641);//eeMLX90641[10] & 0x0040;//

if (status != 0) {
    debug.println("Failed to load system parameters");
   while(1);
}

status = MLX90641_ExtractParameters(eeMLX90641, &MLX90641);
//errorno = status;
if (status != 0) {
    debug.println("Parameter extraction failed");
   // while(1);
}

//Once params are extracted, we can release eeMLX90641 array

//MLX90641_SetRefreshRate(MLX90641_address, 0x02); //Set rate to 2Hz
MLX90641_SetRefreshRate(MLX90641_address, 0x03); //Set rate to 4Hz
//MLX90641_SetRefreshRate(MLX90641_address, 0x07); //Set rate to 64Hz

}

void loop() {
long startTime = millis();
float vdd = 0;
float Ta = 0;

for (byte x = 0 ; x < 2 ; x++) {
    int status = MLX90641_GetFrameData(MLX90641_address, MLX90641Frame);

    float vdd = MLX90641_GetVdd(MLX90641Frame, &MLX90641);
    float Ta = MLX90641_GetTa(MLX90641Frame, &MLX90641);

    float tr = Ta - TA_SHIFT; //Reflected temperature based on the sensor ambient temperature
    float emissivity = 0.95;

    MLX90641_CalculateTo(MLX90641Frame, &MLX90641, emissivity, tr, MLX90641To);
}
long stopTime = millis();

debug.print("vdd=");
debug.print(vdd,2);
debug.print(",Ta=");
debug.print(Ta,2);

debug.print(",errorno=");
debug.print(errorno,DEC);


for (int x = 0 ; x < 64 ; x++) {
    debug.print(MLX90641Frame[x], HEX);
    debug.print(",");
}

delay(1000);

for (int x = 0 ; x < 192 ; x++) {
    debug.print(MLX90641To[x], 2);
    debug.print(",");
}
debug.println("");

}

//Returns true if the MLX90641 is detected on the I2C bus
boolean isConnected() {
Wire.beginTransmission((uint8_t)MLX90641_address);
if (Wire.endTransmission() != 0) {
return (false); //Sensor did not ACK
}
return (true);
}

Blockquote

Hi @rich:
there exist correct code to get mlx90641’s data in github. I would say It is very helpful for you.

I updated that and now it still fails with

Parameter extraction failed

I tried this code, and I see little difference from what I was using. I still see slightly different error, as it is now saying Parameter extraion failed as opposed the the earlier code that said “Failed to load system parameters”. In both cases I was trying to get the demo code working first, before I tried to integrate it.

Hi @rich:
did you modify the https://github.com/Seeed-Studio/Seeed_Arduino_MLX9064x/blob/master/examples/Visualization/Visualization.ino#L7 to #define USE_MLX90640? I would say, It is a necessity if you want to use mlx90640 with this lib.

/*
    Output the temperature readings to all pixels to be read by a Processing visualizer
*/

#include <Wire.h>

#define USE_MLX90640

#ifndef USE_MLX90641
    #include "MLX90640_API.h"
#else
    #include "MLX90641_API.h"
#endif

#include "MLX9064X_I2C_Driver.h"

#if defined(ARDUINO_ARCH_AVR)
    #define debug  Serial

#elif defined(ARDUINO_ARCH_SAMD) ||  defined(ARDUINO_ARCH_SAM)
    #define debug  Serial
#else
    #define debug  Serial
#endif

#ifdef USE_MLX90641
    const byte MLX90641_address = 0x33; //Default 7-bit unshifted address of the MLX90641
    #define TA_SHIFT 8 //Default shift for MLX90641 in open air

    uint16_t eeMLX90641[832];
    float MLX90641To[192];
    uint16_t MLX90641Frame[242];
    paramsMLX90641 MLX90641;
    int errorno = 0;
#else
    const byte MLX90640_address = 0x33; //Default 7-bit unshifted address of the MLX90640

    #define TA_SHIFT 8 //Default shift for MLX90640 in open air

    float mlx90640To[768];
    paramsMLX90640 mlx90640;
#endif
void setup() {
    Wire.begin();
    Wire.setClock(400000); //Increase I2C clock speed to 400kHz

    debug.begin(115200); //Fast debug as possible

    while (!debug); //Wait for user to open terminal
    //debug.println("MLX90640 IR Array Example");


#ifndef USE_MLX90641
    if (isConnected() == false) {
        debug.println("MLX9064x not detected at default I2C address. Please check wiring. Freezing.");
        while (1);
    }
    //Get device parameters - We only have to do this once
    int status;
    uint16_t eeMLX90640[832];
    status = MLX90640_DumpEE(MLX90640_address, eeMLX90640);
    if (status != 0) {
        debug.println("Failed to load system parameters");
    }

    status = MLX90640_ExtractParameters(eeMLX90640, &mlx90640);
    if (status != 0) {
        debug.println("Parameter extraction failed");
    }

    //Once params are extracted, we can release eeMLX90640 array

    //MLX90640_SetRefreshRate(MLX90640_address, 0x02); //Set rate to 2Hz
    MLX90640_SetRefreshRate(MLX90640_address, 0x03); //Set rate to 4Hz
    //MLX90640_SetRefreshRate(MLX90640_address, 0x07); //Set rate to 64H
#else
    if (isConnected() == false) {
        debug.println("MLX90641 not detected at default I2C address. Please check wiring. Freezing.");
        while (1);
    }
    //Get device parameters - We only have to do this once
    int status;
    status = MLX90641_DumpEE(MLX90641_address, eeMLX90641);
    errorno = status;//MLX90641_CheckEEPROMValid(eeMLX90641);//eeMLX90641[10] & 0x0040;//
    
    if (status != 0) {
        debug.println("Failed to load system parameters");
       while(1);
    }

    status = MLX90641_ExtractParameters(eeMLX90641, &MLX90641);
    //errorno = status;
    if (status != 0) {
        debug.println("Parameter extraction failed");
        while(1);
    }

    //Once params are extracted, we can release eeMLX90641 array

    //MLX90641_SetRefreshRate(MLX90641_address, 0x02); //Set rate to 2Hz
    MLX90641_SetRefreshRate(MLX90641_address, 0x03); //Set rate to 4Hz
    //MLX90641_SetRefreshRate(MLX90641_address, 0x07); //Set rate to 64Hz    
#endif 

}

void loop() {
#ifndef USE_MLX90641
    long startTime = millis();
    for (byte x = 0 ; x < 2 ; x++) {
        uint16_t mlx90640Frame[834];
        int status = MLX90640_GetFrameData(MLX90640_address, mlx90640Frame);

        float vdd = MLX90640_GetVdd(mlx90640Frame, &mlx90640);
        float Ta = MLX90640_GetTa(mlx90640Frame, &mlx90640);

        float tr = Ta - TA_SHIFT; //Reflected temperature based on the sensor ambient temperature
        float emissivity = 0.95;

        MLX90640_CalculateTo(mlx90640Frame, &mlx90640, emissivity, tr, mlx90640To);
    }
    long stopTime = millis();

    for (int x = 0 ; x < 768 ; x++) {
        //if(x % 8 == 0) debug.println();
        debug.print(mlx90640To[x], 2);
        debug.print(",");
    }
    debug.println("");
#else
    long startTime = millis();
    
    for (byte x = 0 ; x < 2 ; x++) {
        int status = MLX90641_GetFrameData(MLX90641_address, MLX90641Frame);

        float vdd = MLX90641_GetVdd(MLX90641Frame, &MLX90641);
        float Ta = MLX90641_GetTa(MLX90641Frame, &MLX90641);

        float tr = Ta - TA_SHIFT; //Reflected temperature based on the sensor ambient temperature
        float emissivity = 0.95;

        MLX90641_CalculateTo(MLX90641Frame, &MLX90641, emissivity, tr, MLX90641To);
    }
    long stopTime = millis();
   /*
    debug.print("vdd=");
    debug.print(vdd,2);
    debug.print(",Ta=");
    debug.print(Ta,2);
   
    debug.print(",errorno=");
    debug.print(errorno,DEC);
    
    
    for (int x = 0 ; x < 64 ; x++) {
        debug.print(MLX90641Frame[x], HEX);
        debug.print(",");
    }
    
    delay(1000);
    */
    for (int x = 0 ; x < 192 ; x++) {
        debug.print(MLX90641To[x], 2);
        debug.print(",");
    }
    debug.println("");    
#endif
}

//Returns true if the MLX90640 is detected on the I2C bus
boolean isConnected() {
#ifndef USE_MLX90641
    Wire.beginTransmission((uint8_t)MLX90640_address);
#else
    Wire.beginTransmission((uint8_t)MLX90641_address);
#endif
    if (Wire.endTransmission() != 0) {
        return (false);    //Sensor did not ACK
    }
    return (true);
}

Actually I tried both values and neither work.

Having the same issue with the mlx90640. No updates from support!!! Not good Seeedstudio, never expected this from you guys!

I’m sorry, but we also know that mlx90640 may have software problems. This product is very popular, and the samples we have have been bought by the customer.We are looking for test samples to improve the software as soon as possible.

Do we have an update on when we might get a working example? It is frustrating to buy a part and find the demo code is non-functional. I do not expect polished results, but I do expect a sample program that illustrates basic functionality.

Hi @rich:
can you give me a hardware pic? because we have tested this code and the code works fine with Wio terminal.

I am just trying to get the demo code working before I try to integrate it in anything.

Hi @rich:


this is correct connection.