MLX90614
SwordfishUser.MLX90614 History
Hide minor edits - Show changes to output
Changed lines 81-82 from:
* : module level variable CRC contains the old CRC
value *
to:
* : module level variable CRC contains the old CRC value *
Changed lines 81-82 from:
* : module level variable CRC contains the old CRC value *
to:
* : module level variable CRC contains the old CRC
value *
value *
Changed line 81 from:
* : module level variable CRC contains the CRC value *
to:
* : module level variable CRC contains the old CRC value *
Added lines 1-226:
Module provides read/write capability to the Melexis MLX90614 family of non-contact IR sensors.
Sample Code:
=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:
=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 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
=]
Sample Code:
=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:
=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 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
=]