I have made a C++ library class for Melexis90620 (in order to use multiple sensors simultanuously ), a test program to demo this class, python program to show the contour.
Also, I made I2C C program to control itby Raspberry PI, but raspberry Pi can not read from RAM (reading EEPROM is fine).
A new plan under evaluation is to use 4 Melexis90620 togother to make 16X16 pixel IR camera. The only obstacle is to change the I2C slave address. I saw some guy has change the address of Melexis90614. I dump EEPROM of reserved addr, I found some byte should be addr, but I dont know how to write EEPROM. (command sequence)
I have purchased some Melexis90620 IR temperature sensor for our wind turbine conditioning monitoring project. Unfortunately, the evaluation board MLX90620 EVB is mad to me, the sensor voltage can not be adjusted, it is either 0.3V or 4.6V.
So I can only do my programming for evaluation, a quick search reach me code on Arduino forum, it works good on my Arduino Mega 2560. But, there is no function to calculate the V_IR_compensation coeff. Then, I made such function and bypass the limitation of float computation on Arduino.
The pow() on AVR MCU is not as powerful as 32bit CPU, there is delicate difference between std C float and 16bit MCU. It can not do pow(2,42), which should not overflow on X86 cpu.
Furthermore, I have made a C++ library class for Melexis90620, which will made it easier to control multiple sensors. I think the greater contribution is that alpha_ij is computed on Arduino, there is no need to do eeprom dump and write it back. It is really a plug-and-play Arduino sensor module.
My solutions is simple, divided by ow(2,X) is finished in two steps: (1) divided by pow(2,20) at first, (2) divided pow(2,X-20) in later stage. It may only apply to Melexis9062, as the power in EEPROM is quite stable, about 42.
As an employee, I can not just paste my code without approvement.
A piece code is shown here: it can be easily adopted into C version on forum:
#define SENS_COEF_ADDR 0xE0 //alpha0
#define DI_BASE 0x80 //sensitivity offset, delta_alpha
// calc only once in setup()
//Author: qingfeng xia 2013 , University of Strathclyde
void Melexis90620::calculate_alpha_ij(const byte _eeprom)
//sensivity compensation coeff: alpha
//unsigned long long alpha0_scaler=1; // left shift to do power two calc
// a trick to bypass the overflow problem ,
unsigned char base_scale=20;
float base_divider=pow(2, base_scale);
float alpha0_scaler_f= pow(2, (unsigned char)(_eeprom[SENS_COEF_ADDR+2])-base_scale); // (float) (alpha0_scaler<< (unsigned char)(_eeprom[SENS_COEF_ADDR+2]));
float delta_alpha_scaler_f=pow(2, (unsigned char)(_eeprom[SENS_COEF_ADDR+3])-base_scale);
unsigned short alpha0=((unsigned short)(_eeprom[SENS_COEF_ADDR+1] )<< 8) + _eeprom[SENS_COEF_ADDR];
float alpha0_scaled= alpha0/( alpha0_scaler_f) ; // divided by base_divider later
Serial.println(SENS_COEF_ADDR); // 224
Serial.println(_eeprom[SENS_COEF_ADDR+2]); // 41, out of range of shifting can do!
Serial.println(“coeff for alpha ij:”);
Serial.println(alpha0_scaler_f); // overflow is solved by base_scale and base_divider!
Serial.println(alpha0_scaled); // 0, 02 (if it is too small, println can not show it , try scientific natation!)
//Serial.println(“Debug print alpha_ij”);
for (w=0;w<IM_WIDTH; w++)
for (h=0;h<IM_HEIGHT ;h++)
i= IM_HEIGHT*w + h; // column first
alpha_ij[i]=(alpha0_scaled + delta_alpha/delta_alpha_scaler_f)/base_divider; //
Serial.println(float2s(alpha_ij[i],8)); // correctly , around 2.0e-8
// Arduino does only print a zero, if too small , try to use print2s()
//Serial.println(“Debug finish print alpha_ij”);
unsigned char ram_addr=0xC0;
unsigned char eeprom_addr=0xA0;
unsigned int frequency=8;
Melexis90620 mlx(frequency, ram_addr, eeprom_addr);
unsigned long BAUDRATE=115200; //serial
pinMode(ledPin, OUTPUT); //flashing LED
Serial.begin(BAUDRATE); //baudrate , can that be used in other module?
PORTC = (1 << PORTC4) | (1 << PORTC5); // Enable pullups for 20 21 mega 2560.
mlx.check_error_and_reset(); //POR brown-out flag check, print errror if failed
Serial.println(“melexis init sucessfully”);
// datasheet section 7 principle of operation
mlx.check_error_and_reset(); // POR brown-out flag check
//TA refresh is slower than the pixel readings, I’ll read the values and computate them not every loop.
Serial.println(“TA on melexis90620 is : “);
count = 0;
digitalWrite(ledPin, HIGH); // sets the LED on
digitalWrite(ledPin, LOW); // sets the LED off
Serial.println(“T array on melexis90620 is : “);
mlx.suspend(); // 30mA, the meter is not precise enough to test that
mlx.resume(); //40mA at 2.6V
Serial.println(“Trigger step measurement again”);
//delay((int)(1000/frequency)); // wait 1/frequency, or checking busy condition
CC-BY-NC 4.0 licensed free for non-commercial usage
Author: Qingfeng XIA
copyright (C) 2011-2020
please keep the original link in your reference.