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