Go Down

Topic: MLX90640 (32x24) how to change I2C address (Read 144 times) previous topic - next topic

achumarya

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  :)
Achumarya

pylon

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.

achumarya

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? ( https://chrisramsay.co.uk/posts/2014/09/arduino-and-multiple-mlx90614-sensors/ )


// 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;
 }

pylon


Go Up