reading MLX90614 IR sensor


36 posts   Page 1 of 2   1, 2
by giohdl » Tue Sep 18, 2012 8:19 pm
I am trying to read a Melexis MLX90614 IR sensor with my Raspberry.
I'm using the Occidentalis v0.2 distribution and I've installed the i2ctools package.
The sensor uses the i2c protocol and in fact I can detect it using the command:
i2cdetect -y 0 ,,,,that gives me the device address at 0x5a..
However when I use the i2cget command to read from the temperature
sensor register I always got the value 0xff.
Is the I2C driver included in the distribution able to correctly manage this sensor?
Moreover I've found in the documentation of the sensor that it requires a "repeated start" conmmand to properly give the result of reading. Is the i2cget command able to read the sensor using that kind of command?
Thank you for you help.
Posts: 4
Joined: Tue Sep 18, 2012 7:46 pm
by Grumpy Mike » Wed Sep 19, 2012 3:35 am
Is the I2C driver included in the distribution able to correctly manage this sensor?

Yes.
requires a "repeated start" conmmand to properly give the result of reading. Is the i2cget command able to read the sensor using that kind of command?

Send it twice.

Without seeing your code it is hard to be any more specific.
User avatar
Posts: 868
Joined: Sat Sep 10, 2011 7:49 pm
Location: Manchester (England England)
by jjhuff » Thu Sep 20, 2012 5:54 am
I'm seeing similar behavior. The only register reading anything but ones is 0xf0, which should be flags...and it's value doesn't make any sense. The sensor worked fine via my BusPirate.

I've also tried python-smbus:
Code: Select all
import smbus
addr = 0x5a
i2c = smbus.SMBus(0)
for x in range(0,0x3F)+[0xf0,]:
        ret = i2c.read_word_data(addr, x)
        print "%02x: %02x %d"%(x,ret,ret)


i2cdump:
Code: Select all
# i2cdump -y 0 0x5a w
     0,8  1,9  2,a  3,b  4,c  5,d  6,e  7,f
00: ffff ffff ffff ffff ffff ffff ffff ffff
08: ffff ffff ffff ffff ffff ffff ffff ffff
10: ffff ffff ffff ffff ffff ffff ffff ffff
18: ffff ffff ffff ffff ffff ffff ffff ffff
20: ffff ffff ffff ffff ffff ffff ffff ffff
28: ffff ffff ffff ffff ffff ffff ffff ffff
30: ffff ffff ffff ffff ffff ffff ffff ffff
38: ffff ffff ffff ffff ffff ffff ffff ffff
40: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
48: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
50: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
58: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
60: ffff ffff ffff ffff XXXX ffff ffff ffff
68: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
70: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
78: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
80: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
88: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
90: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
98: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
a0: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
a8: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
b0: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
b8: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
c0: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
c8: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
d0: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
d8: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
e0: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
e8: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
f0: f701 ffff ffff ffff ffff ffff ffff ffff
f8: ffff ffff ffff ffff ffff ffff ffff ffff
Posts: 2
Joined: Thu Sep 20, 2012 5:38 am
by giohdl » Wed Sep 26, 2012 7:52 am
Hi all,
I've tried two different approachs in order to read from the sensor.
lmsensors and quick2wire python api
First, I've sent the bash command
"i2cdetect -y 0" , that gives me the correct device address on the smbus
->0x5a

The measured temperature should be in the 0x07 ram register so I've tried with

i2cget -y 0 0x5a 0x07 w , that gives me the word
->0xffff
same result with i2cget -y 0 0x5a 0x07 wp
->0xffff

Next I've used the quick2wire api libraries. Here's the code:

#!/usr/bin/env python3

import quick2wire.i2c as i2c

address = 0x5a
ram_register = 0x07

with i2c.I2CMaster() as bus:

msb_reg, lsb_reg = bus.transaction(
i2c.writing_bytes(address, ram_register),
i2c.reading(address, 2))[0]

print("MSB: ", bin(msb_reg)[2:])
print("LSB:", bin(lsb_reg)[2:])

Unfortunately, I've got the same results than i2cget
->1111111
->1111111

The strange thing is that either i2cget and quick2wire
code work perfectly with the TC74 Microchip sensor, which should have
the same I2C interface.

Any suggestion?
Posts: 4
Joined: Tue Sep 18, 2012 7:46 pm
by giohdl » Tue Oct 02, 2012 4:02 pm
I think I've found the problem...
i2c c/python libraries implement the "read transactions" on the smbus
such as that after the "command byte", they send a "Stop" bit
then a "restart" bit. That can be observed in the attached image where
SDA goes high while SCL is high, i.e. this is a STOP condition for the smbus protocol.

So the true implemented read transaction in these libraries becames
<START>< Address+0><ACK><Command><ACK>
>STOP> <REPATED START>< Address+1><Data Byte><NACK><STOP>
instead of
<START>< Address+0><ACK><Command><ACK>
<REPATED START>< Address+1><Data Byte><NACK><STOP>

As reported in the Melexis support site, that's a problem for the sensor because
the first STOP condition reset the communication.

I suppose that the only possible solution
for this particular sensor is bit-banging over the GPIO pins.

Regards....
Attachments
mlx2.jpg
mlx2.jpg (59.99 KiB) Viewed 18956 times
Posts: 4
Joined: Tue Sep 18, 2012 7:46 pm
by jjhuff » Thu Oct 04, 2012 5:16 pm
Yeah, I was expecting this might be the cause, but didn't have a scope handy. I'm just using a little AVR to handle the interface now.
Posts: 2
Joined: Thu Sep 20, 2012 5:38 am
by giohdl » Fri Oct 05, 2012 2:33 pm
Hi all,
I've used bit-banging for the I2C protocol over GPIO and the wiringPi library from
https://projects.drogon.net/raspberry-pi/wiringpi
I was able to read the sensor without problems...
I hope developers could improve the
ordinary I2c interface on raspy...
Bye.
Posts: 4
Joined: Tue Sep 18, 2012 7:46 pm
by cdan » Thu Dec 06, 2012 8:49 am
giohdl wrote:Hi all,
I've used bit-banging for the I2C protocol over GPIO and the wiringPi library from
https://projects.drogon.net/raspberry-pi/wiringpi
I was able to read the sensor without problems...
I hope developers could improve the
ordinary I2c interface on raspy...
Bye.


Hi,
would it be possible for you to post the code you have used to read the MLX90614?

Best regards,
Dan.
Posts: 5
Joined: Tue Nov 27, 2012 12:09 pm
by blackworker » Sun Dec 23, 2012 1:34 pm
I have exact the same problem with the Sensor.

I need just a repeated Start-Bit not a Stop AND Start-Bit :cry:

But i have not the skills zu rewrite the i2c-drivers or do some bit banging. The interrupts on Linux are my main-problem, that the timings on SDA and SCL are not correct.

Have anyone else solved this problem?

Regards
Posts: 1
Joined: Sun Dec 23, 2012 1:27 pm
by echoskope » Fri Dec 28, 2012 2:53 pm
Not sure if this is any help but...

http://www.kernel.org/doc/Documentation ... s-protocol

That documentation shows using i2c_smbus_read_word_data() as being

<start><addr><ack><command><ack><start><addr><ack><data><nack><stop>

which I think is what you are looking for. Having said this, I am not sure if the python smbus code uses this in the background or if they have their own unique libraries...

Although if you were using i2cget (from looking at its source) it appears that it calls the i2c_smbus_read_byte_data() function after using i2c_smbus_write_byte() so my first thought was it should still work but then it occurred that maybe the write command before the read command is confusing the chip (sorry I don't have one to test with!).

Sorry if this doesn't directly answer the question, but maybe it will help find a path to solve this issue.

Live long and prosper.
-echo
Posts: 1
Joined: Fri Dec 28, 2012 2:41 pm
by cdan » Thu Jan 03, 2013 7:16 pm
echoskope wrote:Not sure if this is any help but...

http://www.kernel.org/doc/Documentation ... s-protocol

That documentation shows using i2c_smbus_read_word_data() as being

<start><addr><ack><command><ack><start><addr><ack><data><nack><stop>


You are right, this is what i2c_smbus_read_word_data() should do but, unfortunately, in the i2c-bcm2708 module, this function is implemented with 2 distinct transactions, a WRITE + a READ. Consequently, it results in a STOP and a START condition beign generated inbetween the two transactions.

Here you can see what the scope shows up: http://scummos.blogspot.ro/2012/11/rasp ... start.html

Furthermore, from reading BCM2835 ARM Peripherals' specs, I tend to believe that this type of transaction is not supported by the controller. I hope I am wrong.

http://www.raspberrypi.org/wp-content/u ... herals.pdf

Best regards,
Dan.
Posts: 5
Joined: Tue Nov 27, 2012 12:09 pm
by swaysubz » Tue Jan 22, 2013 12:43 am
cdan wrote:
giohdl wrote:Hi all,
I've used bit-banging for the I2C protocol over GPIO and the wiringPi library from
https://projects.drogon.net/raspberry-pi/wiringpi
I was able to read the sensor without problems...
I hope developers could improve the
ordinary I2c interface on raspy...
Bye.


Hi,
would it be possible for you to post the code you have used to read the MLX90614?

Best regards,
Dan.



+1. Any progress in getting the repeated start to work?
Posts: 1
Joined: Tue Jan 22, 2013 12:32 am
by ilpapabuono » Sun May 26, 2013 9:00 am
giohdl wrote:
Hi all,
I've used bit-banging for the I2C protocol over GPIO and the wiringPi library from
https://projects.drogon.net/raspberry-pi/wiringpi
I was able to read the sensor without problems...
I hope developers could improve the
ordinary I2c interface on raspy...
Bye.

Hi giohdl,
I need a little help with wiringPI in interfacing MLX 90614. Have you used the wiringPiI2C libs or re-implemented the I2C protocol with wiringPI with different pins, or what?
i2c_rep_start (the problematic issue with I2C in RasPI) seems not to be directly implemented with wiringPiI2C libraries.
Please give me an hint or, if possible, a coding example, I'm not an expert at all...

Thanks in advance
Federico
Posts: 2
Joined: Sun May 26, 2013 7:56 am
by Pigmanus » Sun Jun 02, 2013 3:34 pm
Hey,
I made a short example code in C for MLX90614 IR sensor, with BCM2835 driver for reading and logging ambient and object temperature to log.csv with timesamp in every user defined LOGTIME sec. It's not perfect but works...
Steps:
-install BCM2835 C library as described here : http://www.airspayce.com/mikem/bcm2835/
-copy C code to MLXi2c.c:
Code: Select all
//fordit:  gcc MLXi2c.c -o i2c -l bcm2835
#include <stdio.h>
#include <bcm2835.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include<time.h>
#define AVG 1   //averaging samples
#define LOGTIME 10  //loging period
int main(int argc, char **argv)
{
    unsigned char buf[6];
    unsigned char i,reg;
    double temp=0,calc=0, skytemp,atemp;
    FILE *flog;
    flog=fopen("mlxlog.csv", "a");..
    bcm2835_init();
    bcm2835_i2c_begin();
    bcm2835_i2c_set_baudrate(25000);.
    // set address...........................................................................................
    bcm2835_i2c_setSlaveAddress(0x5a);
....
    printf("\nOk, your device is working!!\n");
....
....
    while(1) {
        time_t t = time(NULL);
<------>struct tm tm = *localtime(&t);
<------>calc=0;
<------>reg=7;
<------>for(i=0;i<AVG;i++){
<------>    bcm2835_i2c_begin();
<------>    bcm2835_i2c_write (&reg, 1);
<------>    bcm2835_i2c_read_register_rs(&reg,&buf[0],3);
<------>    temp = (double) (((buf[1]) << 8) + buf[0]);
<------>    temp = (temp * 0.02)-0.01;
    <-->    temp = temp - 273.15;
<------>    calc+=temp;
<------>    sleep(1);
<------>    }
<------>skytemp=calc/AVG;
<------>calc=0;
<------>reg=6;
<------>for(i=0;i<AVG;i++){
<------>    bcm2835_i2c_begin();
<------>    bcm2835_i2c_write (&reg, 1);
<------>    bcm2835_i2c_read_register_rs(&reg,&buf[0],3);
<------>    temp = (double) (((buf[1]) << 8) + buf[0]);
<------>    temp = (temp * 0.02)-0.01;
    <-->    temp = temp - 273.15;
<------>    calc+=temp;
<------>    sleep(1);
<------>    }
<------>atemp=calc/AVG;
<------>printf("%02d-%02d %02d:%02d:%02d\n    Tambi=%04.2f C, Tobj=%04.2f C\n", tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,atemp,skytemp);
<------>fprintf(flog,"%04d-%02d-%02d %02d:%02d:%02d,%04.2f,%04.02f\n",tm.tm_year+1900, tm.tm_mon +1, tm.tm_mday,tm.tm_hour, tm.tm_min, tm.tm_sec,atemp,skytemp);
<------>fflush(flog);
<------>sleep(LOGTIME-(2*AVG));
    }
...
    printf("[done]\n");
}


- translate it with GCC: gcc MLXi2c.c -o i2c -l bcm2835
- connect your device to dedicated I2C pins
- Run prog: ./i2c
- Enjoy! ;)


I hope could help.
Happy measuring:
Gergő
Posts: 1
Joined: Sun Jun 02, 2013 3:11 pm
Location: Hungary
by ilpapabuono » Mon Jun 03, 2013 6:47 am
Thanks, a lot.
Federico
Posts: 2
Joined: Sun May 26, 2013 7:56 am
by fehlfarbe » Wed Sep 04, 2013 3:49 pm
Hi Gergő,

thanks for the code. Unfortunally it's not working with my configuration. I get a message that my device is working even if there is no device connected and then it measures strange values.

Code: Select all
Ok, your device is working!!
09-04 17:14:04
    Tambi=331.12 C, Tobj=331.14 C
09-04 17:14:14
    Tambi=331.12 C, Tobj=331.14 C


i2cdetect -y 0 finds the device at 0x5a

Is there a difference between rev1 and rev2 boards? I'm using a rev1 RasPi and the sensor is connected with SDA/SCL at pin 3/5.

Thanks in advance,
Marcus
Posts: 23
Joined: Wed Jun 20, 2012 7:49 pm
Location: Dresden, Germany
by joan » Wed Sep 04, 2013 4:03 pm
The gpios changed between R1 and R2 (see http://elinux.org/Rpi_Low-level_peripherals ). The pins remained the same. Did the buses change as well? Perhaps i2c-0 is now i2c-1.
User avatar
Posts: 12688
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK
by fehlfarbe » Wed Sep 04, 2013 6:01 pm
Hi joan,

I changed the pins of bcm2835_i2c_begin() and bcm2835_i2c_end() in bcm2835.c from RPI_V2_GPIO_P1_03/RPI_V2_GPIO_P1_05 to RPI_GPIO_P1_03/RPI_GPIO_P1_05 and recompiled the lib and Gergő's C-Code but nothing changed.

Code: Select all
void bcm2835_i2c_begin(void)
{
    // Set the I2C/BSC1 pins to the Alt 0 function to enable I2C access on them
    bcm2835_gpio_fsel(RPI_GPIO_P1_03, BCM2835_GPIO_FSEL_ALT0); // SDA
    bcm2835_gpio_fsel(RPI_GPIO_P1_05, BCM2835_GPIO_FSEL_ALT0); // SCL
...
Posts: 23
Joined: Wed Jun 20, 2012 7:49 pm
Location: Dresden, Germany
by joan » Wed Sep 04, 2013 7:14 pm
Is the device recognized?

Try

i2cdetect -y 0

and

i2cdetect -y 1

(sudo apt-get install i2c-tools if the utility isn't found)
User avatar
Posts: 12688
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK
by fehlfarbe » Wed Sep 04, 2013 7:57 pm
Hi joan,

i2cdetect -y 0 finds the device at 0x5a
Code: Select all
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- 5a -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Posts: 23
Joined: Wed Jun 20, 2012 7:49 pm
Location: Dresden, Germany
by fehlfarbe » Sun Sep 08, 2013 1:53 pm
Today I tested the code (same sdcard) with a rev2 board and it worked great even with the changed RPI_[V2_]GPIO_P1_03 pins in bcm2835_i2c_begin() / end().
The device is now detected at 0x5a with i2cdetect -y 1 instead of i2cdetect -y 0
Posts: 23
Joined: Wed Jun 20, 2012 7:49 pm
Location: Dresden, Germany
by fehlfarbe » Sun Sep 08, 2013 7:19 pm
Ok, the problem is that the BCM2835 C library ( http://www.airspayce.com/mikem/bcm2835/ ) is set to RasPi rev2 settings by default which means that i2c pins are set to GPIO2 (SDA) and GPIO3 (SCL) (see: http://elinux.org/Rpi_Low-level_peripherals) and i2c channel 1.

I changed the pins in bcm2835.c
from
RPI_V2_GPIO_P1_03 to RPI_GPIO_P1_03
and
RPI_V2_GPIO_P1_05 to RPI_GPIO_P1_05
To change the i2c channel from 1 to 0 just change bcm2835_bsc1 to bcm2835_bsc0 in the i2c functions, recompile and enjoy :)
Posts: 23
Joined: Wed Jun 20, 2012 7:49 pm
Location: Dresden, Germany
by turkoale » Mon Oct 21, 2013 12:39 pm
Hello everybody. I am new in this forum. I try read my MLX90620 whit a beaglebone black board, and my i2cdetec not detect this in 0x5A. I power the sensor whit 3.3v on beaglebone board, which may be the problem.




this is out to i2cdetec:
https://docs.google.com/file/d/0B6Uo2gxaAz-HQ2VjTkVDLTl1Smc/edit?usp=sharing


thanks :D
Posts: 2
Joined: Mon Oct 21, 2013 12:03 pm
by turkoale » Fri Jan 31, 2014 6:56 pm
I found this information in a personal blog of Pieter Jan:

http://www.pieter-jan.com/
it's can help
Posts: 2
Joined: Mon Oct 21, 2013 12:03 pm
by hangkitegale » Wed Mar 12, 2014 5:57 pm
Hi guys!
I am working with MLX90620 and Raspi Rev. B now. The device is at Bus 1 (I believe since i2cdetect -y 0 did not give me any result).

My question is, how would I access the measurement data from MLX90620?

This is some progress I have.

pi@raspberrypi ~ $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 51 52 53 54 55 56 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

This python code (I copied somewhere from the Internet, sorry I forgot the link) contains:
pi@raspberrypi ~ $ more simple_mlx.py
import smbus
addr = 0x55
i2c = smbus.SMBus(1)
for x in range(0,0x3F)+[0xF0,]:
ret = i2c.read_byte_data(addr, x)
print "%02x: %02x %d"%(x,ret,ret)

And if it run, it gives me these:
pi@raspberrypi ~ $ python simple_mlx.py
00: 00 0
01: 00 0
02: 02 2
03: df 223
04: dd 221
05: dd 221
06: df 223
07: e1 225
08: e0 224
09: e2 226
0a: e2 226
0b: e3 227
0c: e1 225
0d: e3 227
0e: e4 228
0f: e4 228
10: e4 228
11: e5 229
12: e7 231
13: e6 230
14: e6 230
15: e7 231
16: e6 230
17: e7 231
18: e6 230
19: e6 230
1a: e7 231
1b: e7 231
1c: e6 230
1d: e8 232
1e: ea 234
1f: e9 233
20: e8 232
21: ea 234
22: eb 235
23: ec 236
24: e8 232
25: ea 234
26: eb 235
27: ed 237
28: e8 232
29: e9 233
2a: eb 235
2b: ee 238
2c: e7 231
2d: ea 234
2e: ec 236
2f: ef 239
30: e9 233
31: eb 235
32: ec 236
33: ef 239
34: e8 232
35: eb 235
36: ee 238
37: ef 239
38: ea 234
39: eb 235
3a: ed 237
3b: f0 240
3c: e8 232
3d: eb 235
3e: ec 236
f0: b2 178
Posts: 2
Joined: Wed Mar 12, 2014 5:47 pm