Reading i2c IR temperature sensor

What I want to do is read my MLX90614 IR temperature sensor via my spark core.
After struggeling to do this for a while I come here to ask for help.

It is possible to read this sensor succesfully via arduino, using some libraries which are not compatible with spark (AVR library is used for instance). I am trying to only use the Wire library which should be compatible (correct me if I am wrong).

datasheet

The MLX90614 sensor has the default slave adress of 0x5A. The data that I need is stored in the RAM at adress 0x07. That data sent in 2 bytes (16 bits total) and a PEC error byte for as far I understand the datasheet.
I just can’t seem to properly request the data or my fault is in the receiving of the data. Below is the code I have so far, it is based on the example codes here: source 1, arduino example.

The code I have so far (it returns -1,-1 for the 2 data bytes, which should be around 60-200,60-200 for normal values).
Also, the prototyping is done on arduino, but if the Wire library is indeed compatible with spark then it should be no problem (again, correct me if I am wrong).

#include <Wire.h>

void setup(){
  int ch;
  Serial.begin(9600);
  Serial.println("Setup...");
}

void loop(){
  int ch = 0;
  do{
    do{
      do{
        Wire.begin();
        Serial.println("Begin Transmission");
        ch = Wire.write(0x5A);
      } 
      while (ch == 0);

      ch = 0;
      Serial.println("Request RAM");
      ch = Wire.write(0x07);
    } 
    while (ch == 0);
    

    ch = 0;
    Wire.begin();
    Serial.println("Read setup");
    ch = Wire.write(0x5A);
  } 
  while (ch == 0);

  Serial.println("Reading");
  Wire.requestFrom(0x07, 2);

  int c = Wire.read();
  int d = Wire.read();
  int e = Wire.read();
  Serial.println("result:");
  Serial.print(c);
  Serial.print(",");
  Serial.print(d);

  delay (5000);
}

Does anyone know how to read the sensor properly via spark?

Thanks :smile:

@TheHawk1337, first things first. The Spark requires that the I2C lines be pulled up to function correctly as is done in the Arduino example you link to. Make sure the pull-ups go to the 3.3V supply.

I found a good example on Adafruit originally written for the teensy 3 which required very minor modification for the Spark. Give that a shot first to see if everything reads then we can move on to your sketch.

#define LED_pin D7 
#define slaveAddress 0x5A

void setup(){
  // 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 copy-paste into the web IDE as a new “app”, compile and flash over to your core. The little onboard blue LED should flash when a reading is successfully made and the result is output to the serial port. Keep me posted! :smile:

Hi,

Thanks for the quick reply! I will test it tomorrow (I don’t have permission yet to take the sensor home, it belongs to school :wink: ).

Hi,

I tested the sensor (sorry for the delay). The code works fine but stops after a few loops somehow. I added some reference points to see where it stops:

#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();
}

void loop(){
  Wire.beginTransmission(slaveAddress);
  Serial.println("1");
  // Store the two relevant bytes of data for temperature
  byte dataLow = 0x00;
  byte dataHigh = 0x00;

  delay(20);

  Wire.write(0x07);    // This is the command to view object temperature in the sensor's RAM
  delay(20);
  Serial.println("2");

  Wire.endTransmission(false);
  delay(20);
  Serial.println("3");

  Wire.requestFrom(slaveAddress, 2);
  delay(20);
  Serial.println("4");

  while (Wire.available()){
    dataLow = Wire.read();
    dataHigh = Wire.read();
    Serial.println("5");
    digitalWrite(LED_pin, HIGH);    // Blink the LED to indicate a successful reading
  }
  delay(20);
  
  Serial.println("6");
  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(celcius);
  Serial.println("C");
  Wire.endTransmission(true);

delay(3000);
}

So it seems to fail after Wire.requestFrom(slaveAddress, 2); . I cannot figure out why. I tried longer delays in between without succes. Any other suggestions?

@TheHawk1337, I took a step back and decided to port an Adafruit library for your sensor since they have great libraries. I put the Adafruit-MLX90614-Library on my github. Give it a shot and hopefully, that will work for you :smile:

1 Like

Hi,

I seem to be missing something, I somehow need to add one extra library after another (Wire.h, Stream.h, twi.h and on and on and on). Besides that it throws this error:

In file included from ../inc/spark_wiring.h:30:0,
from ../inc/application.h:31,
from /Adafruit_MLX90614.h:20,
from /Adafruit_MLX90614.cpp:19:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
/Adafruit_MLX90614.cpp: In member function 'uint16_t Adafruit_MLX90614::read16(uint8_t)':
/Adafruit_MLX90614.cpp:81:11: warning: unused variable 'pec' [-Wunused-variable]

I am sure it will work, I am just missing something :confused:

@TheHawk1337, you don’t need to add any libraries whatsoever and shouldn’t! What you show are not errors, just warnings which are common in most builds :open_mouth:

I have the example and the library files loaded on the web IDE and compiling just fine. How are you compiling the code?

I see my problem, I somehow managed to uncomment the #include Wire.h . No idea how I managed that :smile:

Testing right now :smile:

Works perfectly! Thanks a lot :smile:

1 Like

Hi it’s me again.

I have been working on this school project for a while now and I made some adjustments to the code that previously worked. Now it throws this error:

In file included from ../inc/spark_wiring.h:30:0,
from ../inc/application.h:29,
from /Adafruit_MLX90614.h:20,
from /Adafruit_MLX90614.cpp:19:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
In file included from /Adafruit_MLX90614.cpp:19:0:
/Adafruit_MLX90614.h:28:23: fatal error: WProgram.h: No such file or directory
#include "WProgram.h"
^
compilation terminated.
make: *** [/Adafruit_MLX90614.o] Error 1

Error: Could not compile. Please review your code.

I don’t understand why, it worked before with the exact same code. However, with the example code @peekay123 wrote it does not throw this error whilst the library files are the same.

@TheHawk1337, you can remove these lines in Adafruit_MLX90614.h:

#ifdef SPARK_CORE
// Spark - nothing to include
#else
#if (ARDUINO >= 100)
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif
#include "Wire.h"
#endif

For some reason, the #ifdef SPARK_CORE part does not seem to be working. :smile:

2 Likes

Thanks, works fine now! :smile:

2 Likes

Hi peekay

I am having a similar problem and was hoping you could help. I have two of the MLX90614’s and they both work great on Arduino. When i set up a simple sketch just to test on the Spark my readings go to -1000C and -1800F (approximately).

When I set up your program in this thread I end up with -273.15 which would indicate a sensor reading of 0. I have setup my board with the 4.7k pullup resistors as depicted in the Arduino link with
Pin 1 on MLX (SCC) connect to ANALOG pin 5
Pin 2 on MLX (SDA) connect to ANALOG pin 4
Pin 3 on MLX (VDD) connect to 3.3V
Pin 4 on MLX (VSS) connect to GROUND

Any help would be greatly appreciated

Mike

@mikemcp, you don’t have the right I2C pins in the Spark! Look for the the correct pins:

http://docs.spark.io/hardware/#pins-and-i-o-i2c

:slight_smile:

2 Likes

Hi peekay

Thank you. I don’t know why I didn’t look at that, I guess that I thought they would keep those pins compatible with Arduino. Everything is working perfect now. Thanks again

Mike

1 Like

Hi guys,

I’m also trying to communicate with this sensor using Arduino Micro board this time.
I’ve tried to use the official Adafruit library, but no success.
ArduinoMicro uses the following I2C pins 2-SDA(PD0) and 3-SCL(PD1). Of course my sensor is connected with pullups to this pins. I’m always get this wrong answer:
Ambient = 1037.55C Object = 1037.55C
Ambient = 1899.59F Object = 1899.59F

I assume I have to change the communication pins some how, since the code was build for Arduino Uno which use different I2C pins (4 & 5).
Do you have any suggestions ? Thanks !!!

Hey @moska2004,
Just wanted to let you know that this forum is about the Spark Devices. Although they share a lot of similarities with Arduinos, they are also very different. It may well be that the code on the Spark does not work on the arduino, and the other way around. Although this community is very capable, it’s perhaps best that you ask for help in a more relevant community, since there will be porting difficulties involved, which will make it harder than it has to be.
On another note, why not just get rid of the Arduino, and move over to the much more awesome Spark? It’s very similar to arduino, and therefore easy to learn, but can do a lot more (awesome) things. And for this price, it’s going to be (really) hard to beat!

1 Like

@peekay123, Is there a tutorial on porting libraries? I’d like to port Adafruit’s MPL115A2 library but not knowing the subtle differences between an Arduino library and what the Photon needs it would challenging for me. Here’s a link to their library.
Adafruit MPL3115A2 Library
If there’s a tutorial can you point me in the right direction? If not, would you mind offering some sage tips/advice?
Thank you!

@tkurtz, search the community for “arduino port” and you will find stuff to help. This library is straight forward to port since it uses I2C which is built into the Photon firmware (no Wire.h required). The board has a regulator and level shifters so power the breakout by connecting Vin (on the board) to Vin on the Photon. I believe the SDA and SCL I2C lines are pulled-up so nothing needed there. Let me know if you need any help porting and how it works out :smile:

@tkurtz, if you really mean the MPL3115A lib it’s already on the Web IDE - and as in the other thread my suggestion was to try if it also supports the MPL115A2.

@ScruffR, I did read that other thread and attempted the MPL3115A with the MPL115A2 without success. I believe they are actually different. Would you mind reviewing the library with me so this community can learn more about how to port an i2c library? I haven’t been able to find a good instructional posting with step by step call-outs for porting from ardunio to Photon. I think many could benefit from the exercise/tutorial. Thank you for considering.

Here’s a link to the MPL115A2 library.
MPL115A2 library