MLX90640 (32x24) how to change I2C address

Dear All,

As I know so far, MLX90640 thermal camera sensor have options to change address. I want to change the I2C address, so that I can use multiple sensors of the same kind with different address.. Datasheet page 19 (https://cdn.sparkfun.com/assets/7/b/f/2/d/MLX90640-Datasheet-Melexis.pdf) says that we can change ID1, ID2, ID3. How to change this? Please share me some codes if you have worked on it.

Thanks in advance :slight_smile:
Achumarya

What you want to change is the I2C address not the chip ID(s). The relevant EEPROM address is 0x240F, the register is 0x8010.
Read the value of register 0x8010, if it's 0xBE33 you've done it right. Write the new value 0xBEXX where XX is the new address to that register. Power cycle after you've done that.

Thank you for the information, Pylon. So what I need to do is not changing the device ID. For I2C address, I need to write a new value to 0xBE33. In datasheet I saw that 0x240F is melexis reserved I2C address. So is it possible that we can change it?

Does the below code can help me out for this? ( Arduino and Multiple MLX90614 Sensors - Chris Ramsay )

// remap_mlx90614.ino

#include "i2cmaster.h"

// New slave address, purposefully left shifted
byte NewMLXAddr = 0x1B;
// 0x5A is the default address - uncomment this to set it back
// byte NewMLXAddr = 0x5A;

void setup(){
Serial.begin(9600);
Serial.println("Setup...");
// Initialise the i2c bus, enable pullups and then wait
i2c_init();
PORTC = (1 << PORTC4) | (1 << PORTC5);
delay(5000);
// Read current address bytes
ReadAddr(0);
// Change address to new value (NewMLXAddr);
ChangeAddr(NewMLXAddr, 0x00);
// Read address bytes
ReadAddr(0);
Serial.print("> Cycle power NOW to set address to: ");
Serial.print(NewMLXAddr, HEX);
Serial.println(" - you have 10 seconds");
// Cycle power to MLX during this 10 second pause
delay(10000);
// Read temperature using default address
ReadTemp(0);
// Read temperature using new address (note left bit shift for reading)
ReadTemp(NewMLXAddr<<1);
Serial.println("---DONE---");
}

void loop(){
delay(5000);
ReadTemp(NewMLXAddr<<1);
}

word ChangeAddr(byte NewAddr1, byte NewAddr2) {
Serial.println("> Change address");
// Send start condition and write bit
i2c_start_wait(0 + I2C_WRITE);
// Send command for device to return address
i2c_write(0x2E);
// Send low byte zero to erase
i2c_write(0x00);
// Send high byte zero to erase
i2c_write(0x00);

if (i2c_write(0x6F) == 0) {
// Release bus, end transaction
i2c_stop();
Serial.println("> Data erased.");
}
else {
// Release bus, end transaction
i2c_stop();
Serial.println("> Failed to erase data");
return -1;
}

Serial.print("> Writing data: ");
Serial.print(NewAddr1, HEX);
Serial.print(", ");
Serial.println(NewAddr2, HEX);

for (int a = 0; a != 256; a++) {
// Send start condition and write bit
i2c_start_wait(0 + I2C_WRITE);
// Send command for device to return address
i2c_write(0x2E);
// Send low byte zero to erase
i2c_write(NewAddr1);
// Send high byte zero to erase
i2c_write(NewAddr2);
if (i2c_write(a) == 0) {
// Release bus, end transaction then wait 10ms
i2c_stop();
delay(100);
Serial.print("> Found correct CRC: 0x");
Serial.println(a, HEX);
return a;
}
}

// Release bus, end transaction
i2c_stop();
Serial.println("> Correct CRC not found");
return -1;
}

void ReadAddr(byte Address) {
Serial.println("> Read address");
// Inform the user
Serial.print(" MLX address: ");
Serial.print(Address, HEX);
Serial.print(", Data: ");

// Send start condition and write bit
i2c_start_wait(Address + I2C_WRITE);
// Send command for device to return address
i2c_write(0x2E);
i2c_rep_start(Address + I2C_READ);

// Read 1 byte and then send ack (x2)
Serial.print(i2c_readAck(), HEX);
Serial.print(", ");
Serial.print(i2c_readAck(), HEX);
Serial.print(", ");
Serial.println(i2c_readNak(), HEX);
i2c_stop();
}

float ReadTemp(byte Address) {
int data_low = 0;
int data_high = 0;
int pec = 0;

Serial.println("> Read temperature");
// Inform the user
Serial.print(" MLX address: ");
Serial.print(Address, HEX);
Serial.print(", ");

i2c_start_wait(Address + I2C_WRITE);
// Address of temp bytes
i2c_write(0x07);
// Read - the famous repeat start
i2c_rep_start(Address + I2C_READ);
// Read 1 byte and then send ack (x2)
data_low = i2c_readAck();
data_high = i2c_readAck();
pec = i2c_readNak();
i2c_stop();

// This converts high and low bytes together and processes the temperature
// MSB is a error bit and is ignored for temperatures
// Zero out the data
float temp = 0x0000;
// This masks off the error bit of the high byte, then moves it left
// 8 bits and adds the low byte.
temp = (float)(((data_high & 0x007F) << 8) + data_low);
temp = (temp * 0.02) - 273.16;
Serial.print(temp);
Serial.println(" C");
return temp;
}

Edit your post and insert code tags!

Did this code work with the mlx90640 ?

Hi friend.
I need change de i2c slave address for read multiple ir mlx90614 sensor.

Try these codes and I can't get it. Can anyone help me?
a big hug!