MLX90614ESF-AAA TO-39 Temperature sensor ERROR

henriksod

Member
Hello, I am having a problem with my MLX90614ESF-AAA TO-39 Temperature sensor and my AXE401 (PICAXE 28x2). When running the following code, the serial terminal outputs:
CRC = 18
T_ambient - Error, T_object - Error
Since the CRC8 isn't 0, this happens.

Code:
' MLX90614_1.Bas
'
' Continually measures and displays T_ambient and T_object.
'
' PICAXE-28X2               MLX90614ESF-AAA
'
' Term 14 SCL --------------- SCL
' Term 15 SDA --------------- SDA
'
' 4.7K resistors to +5 VDC on SDA and SCL
'
' Note that this is a direct interface with the PICAXE.  The Parallax and
' Sparkfun boards are not required.
' 
' copyright, Peter H Anderson, Baltimore, MD, Mar 12, 11

#picaxe 28x2
#Terminal 9600
#No_Table
#No_Data
#freq m4

Symbol Lo = B0
Symbol Hi = B1
Symbol PEC = B2
Symbol Status = B3
Symbol Whole = B4
Symbol Fract = B5
Symbol Val = W3
Symbol TC_100 = W4
Symbol SlaveAdr_2 = B10
Symbol RamLocation = B11
Symbol X = B12
Symbol N = B13
Symbol CRC8 = B14

Top:

    Hi2cSetup I2CMaster, 45, I2CSlow, I2CByte 

    SlaveAdr_2 = $00 * 2 ' use general slave adr

Again:

    RamLocation = $06 ' ambient temperature

    GoSub ReadRAM
    If Status = 1 Then
       TC_100 = Val * 2 - 27315
       SerTxD ("T_ambient = ") 
       GoSub DisplayTc
       
    Else
       SerTxD ("T_ambient - Error")
    End If

    SerTxD (",  ")

    RamLocation = $07 ' ambient temperature

    GoSub ReadRAM
    If Status = 1 Then
       TC_100 = Val * 2 - 27315
       SerTxD ("T_object = ") 
       GoSub DisplayTc
    Else
       SerTxD ("T_object - Error")  
    End If
      
    SerTxD (CR, LF)

    Pause 1000
    GoTo Again

ReadRAM:
      
    Hi2cin [SlaveAdr_2], RamLocation, (Lo, Hi, PEC)

    Val = Hi
    Val = Val * 256 + Lo
   
    'SerTxD ("Hello ", #TC_100, "  ", #PEC, CR, LF)
                        
    CRC8 = $00
    X = SlaveAdr_2
    GoSub CalcCRC8
    X = RamLocation
    GoSub CalcCRC8
    X = SlaveAdr_2 + 1
    GoSub CalcCRC8
    X = Lo
    GoSub CalcCRC8
    X = Hi
    GoSub CalcCRC8
    X = PEC
    GoSub CalcCRC8

    'SerTxD ("CRC = ", #CRC8, CR, LF)
    If CRC8 = 0 Then
       Status = 1 ' success
    Else
       Status = 0
    Endif
    
    Return

DisplayTc:

    Whole = TC_100 / 100
    Fract = TC_100 // 100

    SerTxD (#Whole, ".")
    If Fract < 10 Then
        SerTxD ("0")
    Endif
    SerTxD (#Fract)

    Return
   
CalcCRC8:

   X = X ^ CRC8
   For N = 0 to 7
      If X > 127 Then
         X = X * 2
         X = X ^ $07
      Else
         X = X * 2
      Endif
   Next
   CRC8 = X
   Return
The temperature sensor is connected to SCL on S.13, SDA on S.12, +5V on S.0 power supply, GND on S.0 0V.

The 7-bit slave address (SA) is $5A, upper 7 bits of the slave address 81bit byte is $B4.
Since there is only one device on the i2c bus, I use $00.

How to solve this issue and get temperature data from my temperature sensor?

EDIT: I forgot to mention that I use the AXE408 shield on the AXE401. I have bypassed S.12 and S.13 so they do not connect with the shield. May be good to know.

I've also tried the following code and got the output ($5A and $B4 gave this result. $00 gave nothing.):
Temp = 37561
Code:
'Program to read from IR sensor
'SDSU FSAE
'Written by John Langholz
'MLX90615
init:

'symbols and defines
symbol ir_lo = b0
symbol ir_hi = b1
symbol ir_pec = b2
symbol slave_addr = b3
symbol temp = w2		;b4 and b5


'initialize i2c communications
slave_addr = $B4							;standard is $B4 but all respond to $00
hi2csetup i2cmaster, slave_addr, i2cslow, i2cbyte	;Set up the i2c protocols 10110100

main:

hi2cin $27, (ir_lo, ir_hi, ir_pec)				;read out of ram at location $07
temp = ir_hi*255 + ir_lo					;shift and add for the full word
temp = temp*2 - 27315						;convert into *C

SerTxD ("Temp = ", #temp, 13, 10)				;temp output shifted 2 dec left

pause	10								;wait to update temp set at 100Hz logging rate

goto main
EDIT #2: This is how I've set it up in pictures:


There is nothing in between the wiring. Blue power supply cable goes to white cable to the sensor, green gnd cable goes to yellow cable on sensor and so on.
Sorry for the mixture of colors, not very organised.
2014-01-26-18.54.18.jpg

2014-01-26-19.02.jpg (Tab is on the right hand side)

Better image:



AXE401 docs: http://www.picaxe.com/docs/axe401.pdf
Sensor docs: https://www1.elfa.se/data1/wwwroot/assets/datasheets/suMELEXIS_IR-tempsensor_EN.pdf
 
Last edited:

AllyCat

Senior Member
Hi,

Code:
 PICAXE-20X2               MLX90614ESF-AAA
'
' Term 13 SCL --------------- SCL
' Term 12 SDA --------------- SDA
Since there is only one device on the i2c bus, I use $00.
For a 20X2, shouldn't SCL be on Leg 11 and SDA on Leg 13 (or 14 + 15 for a 28X2) ?

EDIT: Also, I believe that the "General Call" address (00) is not (fully) supported with PICaxe.

Cheers, Alan.
 
Last edited:

henriksod

Member
I forgot to change that in the code for this post. It is a PICAXE-28x2 as stated at the beginning.

Yes, it should be on those legs on the microchip, but on the project board, it is connected to S.12, S.13.

"28X2 has I2C connections on S.12 (instead of S.A4) and S.13 (instead of S.A5)"
http://www.picaxe.com/docs/axe401.pdf
 
Last edited:

AllyCat

Senior Member
The temperature sensor is connected to SCL on pin 13, SDA on pin 12, +5V on pin 0 power supply, GND on pin 0 0V.
What do you mean by "pin(s)0" ? Which pins/legs are you actually using? Also note my edit above, you should/must use the correct I2C address.

Cheers, Alan.
 

henriksod

Member
I use S.0's pins for power supply for the sensor. I am sorry for your confusion. I have edited the posts now.
 
Last edited:

henriksod

Member
I just by accident touched the sensor when I was doing some testing and got burnt by the heat. I think that it has to be the 9v battery I intended to use for my motors on the axe408 shield. I removed it now.
I hope that my sensor isn't destroyed by this...
 

Paix

Senior Member
@Henriksod, sounds like your sensor had a thermo-tactile readout . . . hot, hot, hot! here's hoping your chip is a survivor. :)
 

MPep

Senior Member
Most likely you've got the sensor reverse powered.
Also, the sensor is a 5V part (or 3V) so the 9V shouldn't make any difference, unless you've got it directly across the 9V!!!!
 

henriksod

Member
Yes, I hope so! Anyhow, the code is still spitting errors. I tried this code from another forum topic that seemed to work for him, but it throws CRC errors at me as the other codes I've tried:
Code:
' MLX90614_08M2.Bas	
' (c)2011 by MR Burnette for all rights not reserved by PH Anderson
' Modified for M2 chips by Armp - Thanks Peter and Ray 1/12/13
'
' 20M2 - Straight Drop In Replacement for 20X2,
' 08M2 - Connect 20X2 socket Pin 11 to Pin 17, Pin 13 to Pin 18,
' 196 Bytes
'
#picaxe 28x2
 
SYMBOL Lo 		= B0	' B1-B0 overmapped by W0 
SYMBOL Hi 		= B1
SYMBOL Temperature= W0

SYMBOL PEC 		= B2
SYMBOL RamLocation= B3  ' Could be a Constant in this example

SYMBOL X          = B4
SYMBOL Tenths	= B4	   
SYMBOL N          = B5
SYMBOL CRC8 	= B6
	
SYMBOL SlaveAdr = $5A * 2 'Hi2cSetup does not allow General Call 0 address.

sertxd("Beginning data:",CR,LF)

Initialize:
' Return to this section on error condition on I2C bus CRC
Hi2cSetup I2CMaster, SlaveAdr , I2CSlow, I2CByte

Again: ' RAM location $07 is the object temperature in Kevin * 50
  
    RamLocation = $07
    GoSub ReadRAM 
    If Temperature = 0 Then Error
        
   'Temperature = Temperature+2/5   	'Use for Kelvin - integer divide by 5 with Rounding
    Temperature = Temperature - 12767 *3 /5 *3 /5  'to return Temp as xxx.xF - Armp 
     
    Tenths=Temperature//10 : Temperature=Temperature/10
    Sertxd (#Temperature,".",#Tenths,CR,LF)
     
    Pause 900	' Results in approx 1 reading per second
                  ' MLX90614 requires 865ms to settle
    
 GoTo Again

ReadRAM:
    Hi2cin  RamLocation, (Lo, Hi, PEC)    
    CRC8 = $00
    X = SlaveAdr  	: GoSub CalcCRC8
    X = RamLocation	: GoSub CalcCRC8
    X = SlaveAdr + 1	: GoSub CalcCRC8
    X = Lo			: GoSub CalcCRC8
    X = Hi			: GoSub CalcCRC8
      
    If CRC8 <> PEC Then
       Temperature = 0		' Return Zero K if CRC Error
    Endif    
  
    Return

CalcCRC8:
   X = X ^ CRC8
   For N = 0 to 7
      If X > 127 Then
         X = X * 2
         X = X ^ $07
      Else
         X = X * 2
      Endif
   Next
   CRC8 = X
   Return

Error:
   	Sertxd("CRC Error...", CR,LF)
     	Goto Initialize   
   
END
CRC Error...
 

Armp

Senior Member
Yes, I hope so! Anyhow, the code is still spitting errors. I tried this code from another forum topic that seemed to work for him, but it throws CRC errors at me as the other codes I've tried:
If that code doesn't work you've probably got a wiring error, and/or fried the sensor. Really need a clear photo and schematic.

Armp
 

hippy

Technical Support
Staff member
the code is still spitting errors
To find why it is giving an error you need to trim the code so it doesn't use or process the data, just reports what it is returning.

Code:
#Picaxe 28X2
#Terminal 9600

Symbol Lo  = b0
Symbol Hi  = b1
Symbol PEC = b2

Hi2cSetup I2CMaster, $B4 , I2CSlow, I2CByte
Do
  Hi2cin  7, (Lo, Hi, PEC)
  SerTxd( #Lo, 9, #Hi, 9, #PEC, CR, LF )
  Pause 1000
Loop
I suspect that may simply display "255 255 255". With the sensor having got hot it may now be damaged and/or there may be some other I2C connection errors. Unfortunately it is not clear in your photos how the sensor is wired up.
 

Armp

Senior Member
The photo's rather blurry, but are you sure you have the sensor wired correctly?
Is the tab on the right hand side of the photo - if so I think the power pins should be on the side nearest the camera.
 

henriksod

Member
I based the wiring of the sensor from page 5 of https://www1.elfa.se/data1/wwwroot/assets/datasheets/suMELEXIS_IR-tempsensor_EN.pdf

Did I read it wrong?

To find why it is giving an error you need to trim the code so it doesn't use or process the data, just reports what it is returning.

Code:
#Picaxe 28X2
#Terminal 9600

Symbol Lo  = b0
Symbol Hi  = b1
Symbol PEC = b2

Hi2cSetup I2CMaster, $B4 , I2CSlow, I2CByte
Do
  Hi2cin  7, (Lo, Hi, PEC)
  SerTxd( #Lo, 9, #Hi, 9, #PEC, CR, LF )
  Pause 1000
Loop
I suspect that may simply display "255 255 255". With the sensor having got hot it may now be damaged and/or there may be some other I2C connection errors. Unfortunately it is not clear in your photos how the sensor is wired up.
$B4 says 181 255 255.
$5A says 91 255 255.
$00 says nothing.

I have linked a better image in the topic post.
 
Last edited:

hippy

Technical Support
Staff member
$B4 says 181 255 255.
$5A says 91 255 255.
$00 says nothing.
191 = $B5 = $B4 + 1 = $B4 with the lsb set
91 = $5B = $5A + 1 = $5A with the lsb set

This usually indicates the I2C bus is not correctly wired, the I2C device is not connected or not functioning correctly.

Added: Looking at the latest photos and the pinout as Armp has posted; it does look like the sensor is wired incorrectly.

The first thing to do would be to correct the wiring, run the test program again and see if that gives more sensible results. If wired correctly and it still is not working then my money would be on having damaged the sensor when it got hot and it needs to be replaced.
 
Last edited:

hippy

Technical Support
Staff member
189 57 15 passes CRC checking and seems to give a sensible reading (22.47 from simulating PHA's code), but 105 58 120 does not pass CRC checking. Those with 255 in the results would indicate some error or issue somewhere.

I am not familiar with the sensor but I would have expected every reading to be valid. It could be a loose connection, poor or unreliable power supply or a damaged sensor. It would be worth trying with a new sensor to discount the problem being down to damage to the one you are using.
 

Armp

Senior Member
I have now switched the wires as should be done and tested the code you gave me ($B4):
It is most likely that the sensor has been damaged :( but there are a couple of things you can try.
You are using Hippy's code above, exactly - right? Specifically you're running at the default clock speed.

Firstly I would add a 0.1uF capacitor across the Vdd and Vss pins at the sensor, as shown in the spec Fig 23, page 32

Secondly I'd set the I2C bus speed to a lower value than 100khz to give a bit more time for the sensor to respond.
Replace Hi2cSetup I2CMaster, $B4 , I2CSlow, I2CByte
with Hi2cSetup I2CMaster, $B4 , 207, I2CByte

Lastly slow the loop down by changing Pause 1000 to Pause 2000

Good luck!
 

henriksod

Member
It is a miracle that the sensor isn't destroyed! It finally works. I just had to change pins for S.12 and S.13 and isolate the pins with some electrical tape so the didn't interfere and it worked! This is now the output (temp is measured in degrees celsius):

Putting my hand in front of the sensor and taking it away.
183 57 141
Temp = 21
181 57 167
Temp = 21
177 57 243
Temp = 21
187 58 120
Temp = 26
5 59 230
Temp = 27
32 59 9
Temp = 28
49 59 75
Temp = 28
59 59 201
Temp = 28
235 57 125
Temp = 22
184 57 78
Temp = 21
186 57 100
Temp = 21
177 57 243
Temp = 21
It must have been the old pins that touched the plates on the AXE408 board to the buffers BUFF 12 and BUFF 13 that caused the wierd behaviour.

Code:
Code:
#Picaxe 28X2
#Terminal 9600

Symbol Lo  = b0
Symbol Hi  = b1
Symbol PEC = b2
symbol temp = w2

Hi2cSetup I2CMaster, $B4 , I2CSlow, I2CByte
Do
  Hi2cin  7, (Lo, Hi, PEC)
  
  SerTxd( #Lo, 9, #Hi, 9, #PEC, CR, LF )
  
  temp = HI*255 + LO					;shift and add for the full word
  temp = temp*2 - 27315					;convert into *C
  temp = temp/100

  SerTxD ("Temp = ", #temp, 13, 10)				;temp output shifted 2 dec left
  
  Pause 1000
Loop
EDIT: I am still getting CRC errors from the other codes... I would like to have it output ambient and object temperatures.
 
Last edited:

hippy

Technical Support
Staff member
Even though you are not CRC checking the data above it seems they would all pass CRC checking.

If other readings are failing CRC checking it may be that the code isn't passing correct data to the checking routines so it may be failing because that data is wrong, not the data you are receiving.

Post the full code you are using ( please do not update the code in the first post ! ) and people will be able to see if there may be anything that may need altering with that.
 

henriksod

Member
Even though you are not CRC checking the data above it seems they would all pass CRC checking.

If other readings are failing CRC checking it may be that the code isn't passing correct data to the checking routines so it may be failing because that data is wrong, not the data you are receiving.

Post the full code you are using ( please do not update the code in the first post ! ) and people will be able to see if there may be anything that may need altering with that.
Code that works:
Code:
#Picaxe 28X2
#Terminal 9600

Symbol Lo  = b0
Symbol Hi  = b1
Symbol PEC = b2
symbol temp = w2

Hi2cSetup I2CMaster, $B4 , I2CSlow, I2CByte
Do
  Hi2cin  7, (Lo, Hi, PEC)
  
  SerTxd( #Lo, 9, #Hi, 9, #PEC, CR, LF )
  
  temp = HI*255 + LO					;shift and add for the full word
  temp = temp*2 - 27315					;convert into *C
  temp = temp/100

  SerTxD ("Temp = ", #temp, 13, 10)				;temp output shifted 2 dec left
  
  Pause 1000
Loop
Code that gives CRC errors:
Code:
' MLX90614_1.Bas
'
' Continually measures and displays T_ambient and T_object.
'
' PICAXE-28X2               MLX90614ESF-AAA
'
' Term 14 SCL --------------- SCL
' Term 15 SDA --------------- SDA
'
' 4.7K resistors to +5 VDC on SDA and SCL
'
' Note that this is a direct interface with the PICAXE.  The Parallax and
' Sparkfun boards are not required.
' 
' copyright, Peter H Anderson, Baltimore, MD, Mar 12, 11

#picaxe 28x2
#Terminal 9600
#No_Table
#No_Data
#freq m4

Symbol Lo = B0
Symbol Hi = B1
Symbol PEC = B2
Symbol Status = B3
Symbol Whole = B4
Symbol Fract = B5
Symbol Val = W3
Symbol TC_100 = W4
Symbol SlaveAdr_2 = B10
Symbol RamLocation = B11
Symbol X = B12
Symbol N = B13
Symbol CRC8 = B14

Top:

    Hi2cSetup I2CMaster, 45, I2CSlow, I2CByte 

    SlaveAdr_2 = $B4 * 2 ' sensor slave adr

Again:

    RamLocation = $06 ' ambient temperature

    GoSub ReadRAM
    If Status = 1 Then
       TC_100 = Val * 2 - 27315
       SerTxD ("T_ambient = ") 
       GoSub DisplayTc
       
    Else
       SerTxD ("T_ambient - Error")
    End If

    SerTxD (",  ")

    RamLocation = $07 ' ambient temperature

    GoSub ReadRAM
    If Status = 1 Then
       TC_100 = Val * 2 - 27315
       SerTxD ("T_object = ") 
       GoSub DisplayTc
    Else
       SerTxD ("T_object - Error")  
    End If
      
    SerTxD (CR, LF)

    Pause 1000
    GoTo Again

ReadRAM:
      
    Hi2cin [SlaveAdr_2], RamLocation, (Lo, Hi, PEC)

    Val = Hi
    Val = Val * 256 + Lo
   
    'SerTxD ("Hello ", #TC_100, "  ", #PEC, CR, LF)
                        
    CRC8 = $00
    X = SlaveAdr_2
    GoSub CalcCRC8
    X = RamLocation
    GoSub CalcCRC8
    X = SlaveAdr_2 + 1
    GoSub CalcCRC8
    X = Lo
    GoSub CalcCRC8
    X = Hi
    GoSub CalcCRC8
    X = PEC
    GoSub CalcCRC8

    'SerTxD ("CRC = ", #CRC8, CR, LF)
    If CRC8 = 0 Then
       Status = 1 ' success
    Else
       Status = 0
    Endif
    
    Return

DisplayTc:

    Whole = TC_100 / 100
    Fract = TC_100 // 100

    SerTxD (#Whole, ".")
    If Fract < 10 Then
        SerTxD ("0")
    Endif
    SerTxD (#Fract)

    Return
   
CalcCRC8:

   X = X ^ CRC8
   For N = 0 to 7
      If X > 127 Then
         X = X * 2
         X = X ^ $07
      Else
         X = X * 2
      Endif
   Next
   CRC8 = X
   Return
 

henriksod

Member
Yes, I know that. I just wanted to make sure there is nothing I am missing out.

Thank you for the help! I can manage on my own from now on.
 

henriksod

Member
Were you able to fix your problem. To help other users can you post the code that works?
The only things you need to know is that the slave address for the sensor is $B4 and ram locations are 6 and 7, so:

Code:
Hi2cin  6, (Lo, Hi, PEC) ' Returns ambient temperature
Hi2cin  7, (Lo, Hi, PEC) ' Returns object temperature
Setup:
Code:
Hi2cSetup I2CMaster, $B4 , I2CSlow, I2CByte
To convert to *C:
Code:
temp = HI*255 + LO       ;shift and add for the full word
temp = temp*2 - 27315	 ;convert into *C
temp = temp/100
Seems like CRC is not required. PEC, which I think is correction, is not used this way, so I still need to figure out how to use that.
 

hippy

Technical Support
Staff member
temp = HI*255 + LO ;shift and add for the full word
Should that not be * 256 ?

If you SYMBOL define 'temp' as a word variable, 'HI' and 'LO' as that word variable's component MSB and LSB byte variable parts, you don't need that maths at all; simply getting the data into the two byte variables will automatically create the word variable's 16-bit value.

Seems like CRC is not required. PEC, which I think is correction, is not used this way, so I still need to figure out how to use that.
PEC is effectively the checksum which lets you know the data received is valid or not. The CRC calculation is the means to determine if everything is valid or not.
 

henriksod

Member
Should that not be * 256 ?

If you SYMBOL define 'temp' as a word variable, 'HI' and 'LO' as that word variable's component MSB and LSB byte variable parts, you don't need that maths at all; simply getting the data into the two byte variables will automatically create the word variable's 16-bit value.



PEC is effectively the checksum which lets you know the data received is valid or not. The CRC calculation is the means to determine if everything is valid or not.
Well, it didn't work for me, so that's a problem.
 
Top