From Swordfish Wiki

SwordfishUser: MLX90614

Module provides read/write capability to the Melexis MLX90614 family of non-contact IR sensors.

Sample Code:

Device = 18F2620
Clock = 20

Include "usart.bas"
Include "convert.bas"
Include "mlxir.bas"

Dim TAC As Float
Dim TAF As Float
Dim TOC As Float
Dim TOF As Float

// main program...
    USART.SetBaudrate(br9600)
    Repeat
        If MLXIR.ReadMLXTemps(TAC,TAF,Ambient) And MLXIR.ReadMLXTemps(TOC,TOF) Then
            USART.Write("Ambient Temp: ",FloatToStr(TAF,1),
                        "F  Object Temp: ",FloatToStr(TOF,1),"F",13,10)
        Else
            USART.Write("ERROR - Unable to read sensor")
        End If
        DelayMS(1000)
    Until false

Module code:

Module MLXIR

Include "i2c.bas"

//Ram Register addresses
Public Const
    Ambient_Sensor_Data = $03,
    IR_Sensor1_Data = $04,
    IR_Sensor2_Data = $05,
    Ambient = $06,
    Object1 = $07,
    Object2 = $08,
    Ta1_PKI = $0A,
    Ta2_PKI = $0B,
    Scale_Alpha_Ratio = $13,
    Scale_Alpha_Slope = $14,
    IIR_Filter = $15,
    Ta1_PKI_Fraction = $16,
    ta2_PKI_Fraction = $17,
    FIR_Filter = $1B

//Rom Register addresses
Public Const
    TOmax = $00,
    TOmin = $01,
    PWMctrl = $02,
    Ta_Range = $03,
    Ke = $04,
    ConfigR1 = $05,
    SMBus_Address = $0E,
    ID_1 = $1C,
    ID_2 = $1D,
    ID_3 = $1E,
    ID_4 = $1F

Public Const
    Rom = true,
    Ram = false

Const Tries = 5         //number of read/write tries until error is declared

Dim CRC As Byte

{
*******************************************************************************
* Name    : CRC8smb                                                           *
* Purpose : local helper function to provide SMB bus CRC8 calculations        *
*         : module level variable CRC contains the old CRC value              *
*******************************************************************************
}
Function CRC8smb(pData As Byte) As Byte
    Dim Index As Byte
    pData = pData Xor CRC   //xor new byte and old crc to get remainder + byte
    For Index = 0 To 7      //check all 8 bits
        If pData.7 =1 Then          //if bit 7 is a 1
            pData = pData << 1      //shift it out
            pData = Pdata Xor $07   //then xor with the polynomial
        Else                        //if the bit is not a 1
            pData = pData << 1      //just shift it out
        End If
    Next                            //check next bit
    Result = pData
End Function

{
*******************************************************************************
* Name    : ReadMLX                                                           *
* Purpose : Reads Ram or Rom location.  Defaults to reading RAM at Slave      *
*         : address 0.  pRegister should be selected from the constants list. *
*         : Function returns a false if the read is not successful.           *
*******************************************************************************
}

Public Function ReadMLX(ByRef pData As Word,pRegister As Byte,
                        pRom As Boolean = false,
                        pSAddress As Byte = 0) As Boolean
    Dim SAddressRead As Byte
    Dim SAddressWrite As Byte
    Dim PEC As Byte
    Dim ReadTries As Byte
    SAddressRead = (pSAddress << 1) + 1     //construct slave address for read
    SAddressWrite = pSAddress << 1          //construct slave address for write
    pRegister.5 = 0                         //working with RAM
    If pRom Then
        pRegister.5 = 1                     //working with ROM
    End If
    ReadTries = Tries
ReadStart:
    I2C.Start                               //follow spec for register reads
    I2C.WriteByte(SAddressWrite)
    I2C.WriteByte(pRegister)
    I2C.Restart
    I2C.WriteByte(SAddressRead)
    pData.Byte0 = I2C.ReadByte(0)           //contents are 16 bits wide
    pData.Byte1 = I2C.ReadByte(0)
    PEC = I2C.ReadByte(0)
    I2C.Stop
    //calculate CRC after communications to not affect SMB bus timing
    CRC = 0                                 //initialize CRC
    CRC = CRC8smb(SaddressWrite)            //accumulate CRC
    CRC = CRC8smb(pRegister)
    CRC = CRC8smb(SaddressRead)
    CRC = CRC8smb(pData.byte0)
    CRC = CRC8smb(pData.byte1)
    CRC = CRC8smb(PEC)                      //CRC should = 0 with no error    
    While CRC <> 0                          //If CRC is not zero 
        Dec(ReadTries)                      //count down 1 try
        If ReadTries = 0 Then               //if timeout is zero
            Result = false                  //the function failed after 
            Exit                            //TimeOut tries
        End If
        GoTo ReadStart                      //otherwise try again
    Wend
    Result = true
End Function

{
*******************************************************************************
* Name    : ReadMLXTemps                                                      *
* Purpose : Reads temperature in C and F                                      *
*         : pRegister should be Ambient, Object1 or Object2. Default is       *
*         : Object1 at Slave Address 0.  Function returns a false if read     *
*         : is not successful.                                                *
*******************************************************************************  
}

Public Function ReadMLXTemps(ByRef pTC As Float,ByRef pTF As Float,
                        pRegister As Byte = Object1,
                        pSAddress As Byte = 0) As Boolean
    Dim RawData As Word
    If ReadMLX(RawData,pRegister,Ram,pSAddress) Then 
        pTC = RawData*0.02 - 273.15    //kelvin to C
        pTF = (pTC*9)/5 + 32    //C to F
        Result = true
    Else
        Result = false
    End If
End Function

{
*******************************************************************************
* Name    : WriteMLXRom                                                       *
* Purpose : Writes to Rom location.  pRegister should be selected from the    *
*         : constants list.  pSAddress defaults to Slave Address 0.           *
*         : Use with care, writes to some ROM locations will erase device     *
*         : calibration constants.                                            *
*******************************************************************************  
}

Public Function WriteMLXRom(pData As Word,pRegister As Byte,
                            pSAddress As Byte = 0) As Boolean
    Dim SAddressWrite As Byte
    Dim TimeOut As Byte
    Dim WriteTries As Byte
    SAddressWrite = pSAddress << 1          //construct slave address for write
    pRegister.5 = 1                         //construct cmd, ROM + Reg address
    //calculate CRC before initiating communications so SMB bus timing won't
    //be affected.  SMB bus can be stalled but unlike I2C it has a timeout.
    //this eliminates having to write timing routines.
    CRC = 0                                 //initialize CRC
    CRC = CRC8smb(SAddressWrite)            //accumulate CRC
    CRC = CRC8smb(pRegister)
    CRC = CRC8smb(pData.byte0)
    CRC = CRC8smb(pData.byte1)
    WriteTries = Tries
WriteStart:
    I2C.Start                               //follow spec for ROM writes
    I2C.WriteByte(SAddressWrite)
    I2C.WriteByte(pRegister)
    I2C.WriteByte(pData.byte0)
    I2C.WriteByte(pData.byte1)
    I2C.WriteByte(CRC)
    TimeOut = $FF
    While NotAcknowledged                   //look for ack, if no ack then 
        Dec(TimeOut)                        //count down 1 loop
        If TimeOut = 0 Then                 //if timeout with no ack
            I2C.Stop                        //place stop on SMB bus
            Dec(WriteTries)                 //decrement number of tries
            If WriteTries = 0 Then          //when # of tries reach 0
                I2C.Stop                    //stop everything
                Result = false              //and fail with error
                Exit
            End If                          //if # of tries not exceeded
            GoTo WriteStart                 //then try again
        End If
    Wend
    I2C.Stop
    Result = true
End Function

//Initialize
    I2C.Initialize
Retrieved from https://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.MLX90614
Page last modified on September 26, 2007, at 07:29 PM