Hi, sorry for Bumping this thread back up. I’m posting because I got quite confused in the process of using this sensor and especially multiple ones. But now that I have gone through all this trouble I wanted to clarify the process for the upcoming community that might use this pyrometer.
First, download Error - Melexis the MLX90614 Datasheet as it can come handy.
Second, the explanation and visual wiring diagram on this site http://bildr.org/2011/02/mlx90614-arduino/ is a good place to start wiring the sensor up. It also includes the necessary library and example to start you up. There is a couple of things I want to say about it thought. First, you don’t absolutely need the pull-up resistors and same goes for the capacitor. Some internal pull-up resistors are setted up in the code and the capacitor is just needed in case you would have parasitic noise on your power lines. I do recommend keeping the real pull-up resistors for those beginners who might get some wires wrong and burn things up thought. Also it says nothing about using multiple sensors.
I have made some modification on the code so people get less confused. First, I’ve added one line for the internal pull-up resistor set-up for the Arduino MEGA. I also made the reading part a function, so it can be called easily without messing up your code. The read functions takes two arguments for flexibility, one is the sensor address, and the other is the unit (C for Celsius, K for kelvin, or F for farehneit). Be aware that the default address of the sensor is 0x5A. So if you want to speak to more than one sensor, you will need to assign them different address first.
Here is the modified code I found on this forum that you need to run on each sensor separately to assign them a new address (different for each one). The only thing you need to change is to uncomment the right pull-up resistor code line, and to change MLXAddr for your given address. When you run this, open up serial monitor, and when asked, you need to power cycle the sensor (deconnect/reconnect +5V or +3V wire).
#include <i2cmaster.h>
// Pins: Standard: SDA:A4 SCL:A5
// Mega: SDA:D20 SCL:D21
//byte MLXAddr = 0x5A<<1; // Default address
//byte MLXAddr = 0; // Universal address
byte MLXAddr = 0x0A<<1; // New Address: Change this value to wathever you want the new adress of the MLX to be.
void setup(){
Serial.begin(9600);
Serial.println("Setup...");
i2c_init(); // Initialise the i2c bus
//PORTC = (1 << PORTC4) | (1 << PORTC5); // Enable pullups resistors (uncomment for std arduinos)
PORTD = (1 << PORTD1) | (1 << PORTD0); // Enable pullups resistors (uncomment for arduino MEGA)
delay(5000); // Wait to allow serial connection
ReadAddr(0); // Read current address bytes
ChangeAddr(MLXAddr>>1, 0x00); // Change address to new value
ReadAddr(0); // Read address bytes
Serial.println("Manually cycle power the MLX, you have 10 seconds.");
delay(10000); // Cycle power to MLX during this pause
Serial.println("Cycle power delay expired.");
delay(2000); // Additionnal delay buffer
Serial.println("Testing temperature reading on universal address.");
ReadTemp(0); // Read temperature using default address
Serial.println("Testing temperature reading on new address.");
ReadTemp(MLXAddr); // Read temperature using new address
Serial.println("Done");
}
void loop(){
delay(1000); // wait a second
}
word ChangeAddr(byte NewAddr1, byte NewAddr2) {
Serial.println("> Change address");
i2c_start_wait(0 + I2C_WRITE); //send start condition and write bit
i2c_write(0x2E); //send command for device to return address
i2c_write(0x00); // send low byte zero to erase
i2c_write(0x00); //send high byte zero to erase
if (i2c_write(0x6F) == 0) {
i2c_stop(); //Release bus, end transaction
Serial.println(" Data erased.");
}
else {
i2c_stop(); //Release bus, end transaction
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++) {
i2c_start_wait(0 + I2C_WRITE); //send start condition and write bit
i2c_write(0x2E); //send command for device to return address
i2c_write(NewAddr1); // send low byte zero to erase
i2c_write(NewAddr2); //send high byte zero to erase
if (i2c_write(a) == 0) {
i2c_stop(); //Release bus, end transaction
delay(100); // then wait 10ms
Serial.print("Found correct CRC: 0x");
Serial.println(a, HEX);
return a;
}
}
i2c_stop(); //Release bus, end transaction
Serial.println("Correct CRC not found");
return -1;
}
void ReadAddr(byte Address) {
Serial.println("> Read address");
Serial.print(" MLX address: ");
Serial.print(Address, HEX);
Serial.print(", Data: ");
i2c_start_wait(Address + I2C_WRITE); //send start condition and write bit
i2c_write(0x2E); //send command for device to return address
i2c_rep_start(Address + I2C_READ);
Serial.print(i2c_readAck(), HEX); //Read 1 byte and then send ack
Serial.print(", ");
Serial.print(i2c_readAck(), HEX); //Read 1 byte and then send ack
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");
Serial.print(" MLX address: ");
Serial.print(Address, HEX);
Serial.print(", ");
i2c_start_wait(Address + I2C_WRITE);
i2c_write(0x07); // Address of temp bytes
// read
i2c_rep_start(Address + I2C_READ);
data_low = i2c_readAck(); //Read 1 byte and then send ack
data_high = i2c_readAck(); //Read 1 byte and then send ack
pec = i2c_readNak();
i2c_stop();
//This converts high and low bytes together and processes temperature, MSB is a error bit and is ignored for temps
float Temperature = 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.
Temperature = (float)(((data_high & 0x007F) << 8) + data_low);
Temperature = (Temperature * 0.02) - 273.16;
Serial.print(Temperature);
Serial.println(" C");
return Temperature;
}
See next post for actual temperature reading code.