Melexis90620 IR sensor controlled by Arduino and Raspberry Pi

copyright (C) 2011-2017

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:

Connecting to a MLX90620


#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[])
int h,w,i;
unsigned delta_alpha;
//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);  //31k
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
delta_alpha=_eeprom[DI_BASE+i];  //delta_alpha
alpha_ij[i]=(alpha0_scaled + delta_alpha/delta_alpha_scaler_f)/base_divider;  //
#ifdef _DEBUG
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”);


#include <Melexis90620.h>


unsigned char ram_addr=0xC0;
unsigned char eeprom_addr=0xA0;
unsigned int frequency=8;
int step_mode=0;
int ledPin=13;

Melexis90620 mlx(frequency, ram_addr, eeprom_addr);
int count=0;

void setup(){
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.

if (step_mode)
mlx.check_error_and_reset();  //POR brown-out flag check, print errror if failed
Serial.println(“melexis init sucessfully”);

void loop(){
// datasheet section 7 principle of operation
mlx.check_error_and_reset();  // POR brown-out flag check
if(count ==0){
//TA refresh is slower than the pixel readings, I’ll read the values and computate them not every loop.
float ta=mlx.calculate_TA();
Serial.println(“TA on melexis90620 is : “);
if(count >=16){
count = 0;
if (count%2)
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

if (step_mode)
Serial.println(“Trigger step measurement again”);
//delay((int)(1000/frequency));  // wait 1/frequency, or checking busy condition



BSD documentation licensed Free for non-commercial usage only
Author: Qingfeng XIA copyright (C) 2011-2013
please keep the original link in your reference.
This entry was posted in Download, Programming, Robot, Sensor. Bookmark the permalink.