I have spent so much time looking into how to change the address of a MLX90614 sensor for use of multiple sensors, so I think it might be helpful to somebody.

Dependencies:   mbed

Fork of MLX90614 IR_Temp_Sensor (change address) by Ronaldas G

main.cpp

Committer:
ronixas
Date:
2016-03-05
Revision:
0:039f25b3de3e

File content as of revision 0:039f25b3de3e:

#include "mbed.h"


DigitalOut myled(LED1); //displays I2C wait

I2C i2c(p28,p27);   //sda,scl
Serial pc(USBTX,USBRX);  //serial usb config

bool ch,ch2,ch3;
float temp; //temperature in degrees C
char p1,p2;
 
 /* Change MLX90614 address
 
 1. clear old address
 2. set new address
 3. check if the change happenned
 4. power cycle sensor (reconnect power)
 
 */
 
int main() {
    while (1) {

//----clear old address------------------
        
        // make sure i2c is inactive
        i2c.stop();            
        wait(0.1);
        //send start bit
        i2c.start();
        // address the sensor using universal address 0x00 not its default 0x5A
        ch = i2c.write(0x00); // last bit 0 indicates write
        // prints if sensor acknowledges
        if (!ch){ pc.printf("no ack\n"); }
        else pc.printf("ack 0x00\n");
        // write command
        // EEPROM address. Datasheet says 0x0E BUT!!! accessing EEPROM requires ading 0x20. Hence, 0x2E
        ch2 = i2c.write(0x2E);
        // prints if sensor acknowledges
        if (!ch2) pc.printf("no ack address location\n");
            pc.printf("ack 0x0E\n");
        // delete old address
        // LSB
        i2c.write(0x00);
        // MSB
        i2c.write(0x00);
        // use CRC-8 calculator to obtain PEC bit http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
        // I send 2E0000 --> PEC 0x6F
        ch3 = i2c.write(0x6F);
        // prints if sensor acknowledges
        if(!ch3) pc.printf("no PEC\n");
            else pc.printf("PEC success\n");
        // release the bus
        i2c.stop();
        wait(1);
    
//-----set new address----------------
    
        // send start bit
        i2c.start();
        // send universal device address 0x00
        i2c.write(0x00);
        // prints if sensor acknowledges
        if (!ch) pc.printf("no ack\n");
        else pc.printf("ack\n");
        // send EEPROM location for slave address
        ch2 = i2c.write(0x2E);
        // prints if sensor acknowledges
        if (!ch2) pc.printf("no ack slave address location\n");
        else pc.printf("ack 2\n");
        //write new address anything between 0x0000 and 0x007F (default 0x5A, PEC 0xE1)
        // LSB
        i2c.write(0x04);
        // MSB
        i2c.write(0x00);
        // send PEC calculated from CRC-8
        // I send 2E0400 -> PEC 0x3B 
        i2c.write(0x3B);
        // release the bus
        i2c.stop();
        wait(1);
        
//----read address to make sure it worked------------

        // send start bit
        i2c.start();
        // send universal address
        ch = i2c.write(0x00);
        // prints if sensor acknowledges
        if (!ch) pc.printf("no ack\n");
        else pc.printf("ack\n");
        // send EEPROM slave location address
        ch2 = i2c.write(0x2E);
        // send repeated start
        i2c.start();
        // send universal address 0x00 (seven bit) and use 1 as the eight bit -> 0x01
        i2c.write(0x01); // last bit 1 indicates read request
        // read LSB
        p1 = i2c.read(1);
        // read MSB
        p2 = i2c.read(1);
        // read PEC
        i2c.read(0);
        // release the bus
        i2c.stop();
        wait(0.1);
        // print hex
        pc.printf("0x%x%x\nMSB 0x%x, LSB 0x%x\n", p2, p1, p2, p1);
        wait(10);
        
//-----now turn of the sensor for the change to take effect----do not access it without turning it off first!!!!-------     
    }
}