MLX90614 IR Temp sensor

Having an issue with using this sensor with my core.

Copied this code from https://community.spark.io/t/reading-i2c-ir-temperature-sensor/4529

#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");

delay(100);
}

Just getting a constant reading of 459.688019F - Using D0 & D1 for SDA & SCL

I’m pretty sure it isn’t the sensor as it works perfectly well with an Arduino.

Anybody have any clue what could be wrong?

@craiglockwood, do you have pull-up resistors on the two I2C lines? Are you using the device library I posted on my github? That library and example work fine.

1 Like

Hi @peekay123

I am using pull up resistors (the sensor came on a board with resistors already wired up) - image below. Link to exact sensor: http://www.elechouse.com/elechouse/index.php?main_page=product_info&cPath=152_158&products_id=2241

I am using your library (thanks for writing it).

To be sure - I am using the following code:

// This #include statement was automatically added by the Spark 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");

delay(100);
}

With the Adafruit_MLX90614.cpp and Adafruit_MLX90614.H library files added.

I am fairly new to Spark stuff but been doing arduino stuff for some time. I may have made a stupid/simple error somewhere.

You can't - or better shall not - cast a float into a String!

Serial.println(fahrenheit, 2); will do the conversion - actually selecting the appropriate overload - and formating for two decimals for you.

To test this theory try setting your var like float fahrenheit = 12345.67; and see what your Serial.println((String)fahrenheit); will give you.

I don't think this cast to String does what you think it does--what happens if you just do this:

Serial.print(fahrenheit);

Thanks @ScruffR but that just gives me the same reading -459.69 to 2 DEC places. Still not the correct reading (reading not changing either)

Then I'd try dropping the (double) cast (or replace it for a (int16_t) cast) in this line too

No difference with either change. This electronics stuff is hard, eh? :grin:

@ScruffR Ah, yes - this does give a Serial out out of 12345.67 as expected

OK, this was a bit unexpected/counterintuitive for me.

Obviously (String) cast (better class cast operator) was designed cleverer than I thought :blush:
But obviously not only I fell for it (ey @bko ;-))

So we seem to have established that it was not your coding, but might rather be the sensor or its wiring.

1 Like

Hmm - very strange. If I disconnect the SDA/SCL pins (D0 & D1) the serial output is still 459.69.

I suspect the Spark is faulty/broken. The sensor works fine on an Arduino.

Grrrr.

Gah! Tried with another Core and get exactly the same results.

Really not sure what the issue is here - it is obviously something I am doing wrong.

Since I’ve already damaged my reputation with my cast suggestions, I can’t do any more harm by asking other stupid questions :wink:

Are you powering the sensor off 3V3 or Vin?


To redeem myself I’ll have a look at Paul’s library, maybe I can spot a difference between it and your code.

@ScruffR powering from 3V3. Just tried with 10k pull up resistors too (thinking maybe the onboard pullups weren’t up to the job). Same results.

I bet I am doing something so wrong - been over everything countless times.

I might have missed it, or Wire.endTransmission()/Wire.requestFrom() does it implicitly, but I can only see one single call to Wire.beginTransmission() where Paul’s lib does a fresh begin each time he wants to get a 16bit reading.

This is how Paul (aka @peekay123 ) does it

uint16_t Adafruit_MLX90614::read16(uint8_t a) {
  uint16_t ret;

  Wire.beginTransmission(_addr); // start transmission to device 
  Wire.write(a); // sends register address to read from
  Wire.endTransmission(false); // end transmission
  
  Wire.requestFrom(_addr, (uint8_t)3);// send data n-bytes read
  ret = Wire.read(); // receive DATA
  ret |= Wire.read() << 8; // receive DATA

  uint8_t pec = Wire.read();

  return ret;
}

Also note that he asks for three not two bytes in Wire.requestFrom(). Since you’re reading in a while(), you might even overwrite your first byte by reading the pec into the same var.


On the other hand: Since you’ve already included Paul’s lib, why do you not just use it?

Not sure what you mean by ‘why do you not just use it?’

OK - swapped out with a third Core and all works perfectly.

Some of these cores have been sitting at the bottom of a drawer for ages - possibly got damaged. All working well with a shiny new one.

Thank you for taking the time out - I really appreciate it.

1 Like

You've got

#include "Adafruit_MLX90614.h"

But you're missing

Adafruit_MLX90614 mlx = Adafruit_MLX90614();

void setup() {
  ...
  mlx.begin();  
}

void loop() {
  ...
  tmp = mlx.readObjectTempF()
  ...
}

Anyhow - good to hear that you've got it working.

But your Cores should not have died, just hanging around unused :confused:

1 Like

Please @ScruffR and @craiglockwood, is it possible to use the same code for a photon? Because am experiencing a lot of problems with mine. I am trying to design a body worn temperature sensor using the MLX90614 IR sensor and a photon to transfer the data via wifi to my iPhone using the BLYNK APP. I have tried several times with different photons and it seems like whenever i flash the code to my photon, the photon stops working i.e. it connects to the WIFI but automatically turns off or remain frozen on cyan. I have become depressed in that I have destroyed three photons already with this process of flashing the code. Please below is the code am flashing, Am just a beginner in programming so please don’t laugh lol.

// This #include statement was automatically added by the Particle IDE.
#include "blynk/blynk.h"

// This #include statement was automatically added by the Particle IDE.
#include "OneWire/OneWire.h"
#include "i2cmaster/i2cmaster.h"

char auth[] = "9ca1cf2ce8d841dab213e26a8301550a";

//#include <Wire.h>

Adafruit_MLX90614 mlx = Adafruit_MLX90614();

void setup() 
{
    Blynk.begin(auth);
    Serial.begin(9600);

    Serial.println("Adafruit MLX90614 test");  

    mlx.begin();  
}

void loop() 
{
    Blynk.run();
    Serial.print("Ambient = "); 
    Serial.print(mlx.readAmbientTempC()); 
    Serial.print("*C\tObject = "); 
    Serial.print(mlx.readObjectTempC()); 
    Serial.println("*C");
    Blynk.virtualWrite(V1, mlx.readAmbientTempC());
    Blynk.virtualWrite(V2, mlx.readObjectTempC());
    //Serial.print("Ambient = "); Serial.print(mlx.readAmbientTempF()); 
    //Serial.print("*F\tObject = "); Serial.print(mlx.readObjectTempF()); 
    //Serial.println("*F");
    //Blynk.virtualWrite(V1, mlx.readAmbientTempF());
    //Blynk.virtualWrite(V2, mlx.readObjectTempF());

    Serial.println();
    delay(500);
}

Please help me out to indicate if am doing anything wrong and your help will greatly be appreciated. Thanks

A post was merged into an existing topic: MLX90614 IR temperasure sensor with photon