Reading i2c IR temperature sensor

@ScruffR, Thank you ScruffR. I was thinking that I’d need to get into the DFU business in order to recover from the solid blue state. I appreciate your help in getting me back in the game. I ordered another backup Photon to keep around just in case. :smile:

1 Like

@peekay123

Good day, I have copied and pasted your code but the reading of my MLX 90614 IS -273C AND -459.68.
heres the code :slight_smile:

// This #include statement was automatically added by the Particle IDE.
#include <OneWire.h>

// This #include statement was automatically added by the Particle IDE.
#include <Adafruit_MLX90614.h>


#define LED_pin D7 
#define slaveAddress 0x5A


void setup(){
    Serial.begin(9600);
  // An LED will blink to indicate when we have successfully read the temperature
  pinMode(LED_pin, OUTPUT);
  digitalWrite(LED_pin, LOW);
  Wire.begin();
  Wire.beginTransmission(slaveAddress);
}

void loop(){
  // Store the two relevant bytes of data for temperature
  byte dataLow = 0x00;
  byte dataHigh = 0x00;

  delay(10);

  Wire.write(0x07);    // This is the command to view object temperature in the sensor's RAM
  delay(10);

  Wire.endTransmission(false);
  delay(10);

  Wire.requestFrom(slaveAddress, 2);
  delay(10);

  while (Wire.available()){
    dataLow = Wire.read();
    dataHigh = Wire.read();
    digitalWrite(LED_pin, HIGH);    // Blink the LED to indicate a successful reading
  }
  delay(10);
  digitalWrite(LED_pin, LOW);

  double tempFactor = 0.02; // 0.02 degrees per LSB (measurement resolution of the MLX90614)
  double tempData = 0x0000; // zero out the data

  // This masks off the error bit of the high byte, then moves it left 8 bits and adds the low byte.
  tempData = (double)(((dataHigh & 0x007F) << 8) + dataLow);
  tempData = (tempData * tempFactor)-0.01;

  float celcius = tempData - 273.15;
  float fahrenheit = (celcius*1.8) + 32;

  Serial.print((String) fahrenheit);
  Serial.println("F");
  Serial.print((String) celcius);
  Serial.println("C");
  Spark.publish ( "celcius", String(celcius) + "C");
  Spark.publish ( "fahrenheit", String(fahrenheit) + "F");

delay(10000);
}

I want also to know the connections of this sensor because i think maybe there also something wrong with it.
I just bought my photon particle recently and I’m not so good in programming.
Thanks in advanced.

hubeltran.

Hello any example how to use multiple sparkfun ML90614 sensors, i got running code with MLX90614 library on sparkfun nrf52xxx board and wondering if anybody done multiple sensors with AVR and wire lib. thanks

@Racoon, you do know that this is a forum for Particle devices, right? However, since the MLX90614 has no programmable addresses, only one can be addressed at a time on the I2C bus. One way to do this is using an I2C multiplexer chip like the TI TCA9544A or the Maxim MAX7368EUE+. Each MLX90614 would occupy one of the multiplexed channels so they don’t clash.

1 Like

No you not right i can program and change address just AVR works with Wire lib. and my changes what i am doing with I2c lib. looking help with wire lib. Thanks

// remap_mlx90614.ino

 #include "i2cmaster.h"

 // New slave address, purposefully left shifted
 byte NewMLXAddr = 0x5D;
 // 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;
 }

Glad to hear I was wrong! However, this is still a Particle forum. You may want to post in the Arduino forum. Have you looked at what Adafruit did in their library?

1 Like