Hi, I am currently working on a project in which I want to work with the mlx90640 sensor and a TFT display. If I flash both separately from each other it works without problems with the respective code. But when I combine the code to run them together, I constantly get the message/error message “GetFrame Error: -1”. As far as I could find so far, it seems to be because the sensor cannot finish writing its array. However, the solutions I have found online do not work. Can anyone here perhaps help me?
If anyone needs it, here is the code:
/*
Thermal Camera by Hexa
*/
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>
#include <Wire.h>
#include "MLX90640_API.h"
#include "MLX9064X_I2C_Driver.h"
#define TFT_RST D0 // you can also connect this to the Arduino reset in which case, set this #define pin to -1!
#define TFT_CS D1
#define TFT_DC D2
#define TFT_SCL D5
#define CAM_SCL D6
#define SDA D7
#define VCC "3v3"
#define GND "GND"
#define TA_SHIFT 8 //Default shift for MLX90640 in open air
#define THERMAL_BLACK 0x0000
#define THERMAL_BLUE 0x000F
#define THERMAL_LIGHTBLUE 0x07FF
#define THERMAL_GREEN 0x07E0
#define THERMAL_LIGHTGREEN 0xAFE5
#define THERMAL_YELLOW 0xFFE0
#define THERMAL_ORANGE 0xFD20
#define THERMAL_RED 0xF800
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
float highest_temp = 30;
const byte MLX90640_address = 0x33; //Default 7-bit unshifted address of the MLX90640
float image[24][32];
static float mlx90640To[768];
paramsMLX90640 mlx90640;
/*
-------------------------------------------------------------------------------------------------------
setup
-------------------------------------------------------------------------------------------------------
*/
void setup() {
Wire.begin(SDA, CAM_SCL);
Wire.setClock(400000); //Increase I2C clock speed to 400kHz
Serial.begin(9600);
Serial.print("Thermal Camera Device by HexaDevelopmentDE");
uint16_t time = millis();
if (isConnected() == false) {
Serial.println("MLX90640 not detected at default I2C address. Please check wiring. Freezing.");
while (1);
}
Serial.println("MLX90640 online!");
//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) {
Serial.println("Failed to load system parameters");
}
status = MLX90640_ExtractParameters(eeMLX90640, &mlx90640);
if (status != 0) {
Serial.println("Parameter extraction failed");
}
tft.initR(INITR_BLACKTAB);
tft.setRotation(1); // rotate 90 degrees
Serial.println("Initialized");
time = millis() - time;
Serial.print("Boot Time: ");
Serial.println(time, DEC);
delay(500);
tft.fillScreen(ST77XX_BLACK);
drawtext("Thermal Camera Device by HexaDevelopmentDE", ST77XX_WHITE);
delay(1000);
tft.fillScreen(ST77XX_WHITE);
}
/*
-------------------------------------------------------------------------------------------------------
loop
-------------------------------------------------------------------------------------------------------
*/
void loop() {
tft.fillScreen(ST77XX_WHITE);
createTempArray();
printArray(image);
delay(100);
}
/*
-------------------------------------------------------------------------------------------------------
functions
-------------------------------------------------------------------------------------------------------
*/
void drawtext(char *text, uint16_t color) {
tft.setCursor(0, 0);
tft.setTextColor(color);
tft.setTextWrap(true);
tft.print(text);
}
void createTempArray() {
for (byte x = 0 ; x < 2 ; x++) { //Read both subpages
uint16_t mlx90640Frame[834];
int status = MLX90640_GetFrameData(MLX90640_address, mlx90640Frame);
if (status < 0) {
Serial.print("GetFrame Error: ");
Serial.println(status);
}
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);
}
int i = 0;
for (int y = 0 ; y < 24 ; y++) {
for (int x = 0 ; x < 32 ; x++) {
image[y][x] = mlx90640To[i];
i++;
}
}
}
//Returns true if the MLX90640 is detected on the I2C bus
boolean isConnected() {
Wire.beginTransmission((uint8_t)MLX90640_address);
if (Wire.endTransmission() != 0) {
return (false); //Sensor did not ACK
}
return (true);
}
void printArray(float a[24][32] ) {
for ( int y = 0; y < 24; y++ ) {
for ( int x = 0; x < 32; x++ ) {
//Serial.print (String(a[y][x]) + " ");
float diff = highest_temp-a[y][x];
//Serial.print (String(diff) + " ");
if(a[y][x] >= highest_temp) {
tft.drawPixel(x, y, THERMAL_RED);
//break;
} else if(diff <= 0.25 && diff > 0) {
tft.drawPixel(x, y, THERMAL_ORANGE);
//break;
} else if(diff <= 0.5 && diff > 0.25) {
tft.drawPixel(x, y, THERMAL_YELLOW);
//break;
} else if(diff <= 0.75 && diff > 0.5) {
tft.drawPixel(x, y, THERMAL_LIGHTGREEN);
//break;
} else if(diff <= 1 && diff > 0.75) {
tft.drawPixel(x, y, THERMAL_GREEN);
//break;
} else if(diff <= 2 && diff > 1) {
tft.drawPixel(x, y, THERMAL_LIGHTBLUE);
//break;
} else if(diff <= 5 && diff > 2) {
tft.drawPixel(x, y, THERMAL_BLUE);
//break;
} else if(diff > 5) {
tft.drawPixel(x, y, THERMAL_BLACK);
//break;
}
}
}
}