MLX90614 - Suspected Sample Code Error Identified - Fix Attached
everest
Posts: 141
All,
In my application I'm seeing highly randomized 2 degree temperature swings in my readings that usually last for up to 10-15 readings before snapping back to normal. This is causing much mayhem with temperature detection! My wiring is incredibly simple, SIG is wired directly to pin 9 and I'm getting +5v and GND to the required pins on the MLX90614 module.
As an example, running the code below I'll see reading like:
29.50
29.53
29.50
27.25
27.10
29.53
29.53
31.40
31.40
The bulk of the readings are accurate, but those 2 degree jumps are just killing me! Any suggestions?
-Jeff
' {$STAMP BS2e}
' ==============================================================================
' I/O Definitions
'
' IR Sensor
Sensor CON 9 'IR Sensor for detecting sky conditions
'
' Constants
'
sensor_baud CON 84
xslave CON $35 'slave address
ShtTemp CON %00011 ' read temperature
ShtHumi CON %00101 ' read humidity
ShtStatW CON %00110 ' status register write
ShtStatR CON %00111 ' status register read
ShtReset CON %11110 ' soft reset (wait 11 ms after)
Ack CON 0
NoAck CON 1
No CON 0
Yes CON 1
MoveTo CON 2 ' for DEBUG control
ClrRt CON 11 ' clear DEBUG line to right
DegSym CON 186 ' degrees symbol for DEBUG
#SELECT $STAMP
#CASE BS2, BS2E, BS2PE
T1200 CON 813
T2400 CON 396
T9600 CON 84
T19K2 CON 32
T38K4 CON 6
#CASE BS2SX, BS2P
T1200 CON 2063
T2400 CON 1021
T9600 CON 240
T19K2 CON 110
T38K4 CON 45
#CASE BS2PX
T1200 CON 3313
T2400 CON 1646
T9600 CON 396
T19K2 CON 188
T38K4 CON 84
#ENDSELECT
Inverted CON $4000
Baud CON T38K4 + Inverted
TRUE CON 0
FALSE CON 1
'
' Variables
'
Inputs VAR Byte
temperature VAR Word
tempL VAR temperature.LOWBYTE
tempH VAR temperature.HIGHBYTE
pec VAR Byte
Celsius VAR Word
CelsiusDec VAR Word
TempDelta VAR Word
w VAR Byte
x VAR Byte
y VAR Byte
z VAR Byte
tC VAR Word ' temp - celcius
ioByte VAR w ' data from/to SHT1x
ackBit VAR x ' ack/nak from/to SHT1x
toDelay VAR y ' timeout delay timer
timeOut VAR z ' timeout status
soT VAR Word ' temp counts from SHT1x - Also recycled to detect a negative temp reading
soRH VAR Word ' humidity counts from SHT1x
rhLin VAR Word ' humidity; linearized
rhTrue VAR Word ' humidity; temp compensated
humSafe VAR Bit
cloudSafe VAR Bit
Dew VAR Bit
Ice VAR Bit
Rain VAR Bit
Humidity VAR Bit
Fail VAR Bit
'
' EEPROM Data
'
PEC0 DATA $00,$07,$0E,$09,$1C,$1B,$12,$15,$38,$3F,$36,$31,$24,$23,$2A,$2D
PEC1 DATA $70,$77,$7E,$79,$6C,$6B,$62,$65,$48,$4F,$46,$41,$54,$53,$5A,$5D
PEC2 DATA $E0,$E7,$EE,$E9,$FC,$FB,$F2,$F5,$D8,$DF,$D6,$D1,$C4,$C3,$CA,$CD
PEC3 DATA $90,$97,$9E,$99,$8C,$8B,$82,$85,$A8,$AF,$A6,$A1,$B4,$B3,$BA,$BD
PEC4 DATA $C7,$C0,$C9,$CE,$DB,$DC,$D5,$D2,$FF,$F8,$F1,$F6,$E3,$E4,$ED,$EA
PEC5 DATA $B7,$B0,$B9,$BE,$AB,$AC,$A5,$A2,$8F,$88,$81,$86,$93,$94,$9D,$9A
PEC6 DATA $27,$20,$29,$2E,$3B,$3C,$35,$32,$1F,$18,$11,$16,$03,$04,$0D,$0A
PEC7 DATA $57,$50,$59,$5E,$4B,$4C,$45,$42,$6F,$68,$61,$66,$73,$74,$7D,$7A
PEC8 DATA $89,$8E,$87,$80,$95,$92,$9B,$9C,$B1,$B6,$BF,$B8,$AD,$AA,$A3,$A4
PEC9 DATA $F9,$FE,$F7,$F0,$E5,$E2,$EB,$EC,$C1,$C6,$CF,$C8,$DD,$DA,$D3,$D4
PEC10 DATA $69,$6E,$67,$60,$75,$72,$7B,$7C,$51,$56,$5F,$58,$4D,$4A,$43,$44
PEC11 DATA $19,$1E,$17,$10,$05,$02,$0B,$0C,$21,$26,$2F,$28,$3D,$3A,$33,$34
PEC12 DATA $4E,$49,$40,$47,$52,$55,$5C,$5B,$76,$71,$78,$7F,$6A,$6D,$64,$63
PEC13 DATA $3E,$39,$30,$37,$22,$25,$2C,$2B,$06,$01,$08,$0F,$1A,$1D,$14,$13
PEC14 DATA $AE,$A9,$A0,$A7,$B2,$B5,$BC,$BB,$96,$91,$98,$9F,$8A,$8D,$84,$83
PEC15 DATA $DE,$D9,$D0,$D7,$C2,$C5,$CC,$CB,$E6,$E1,$E8,$EF,$FA,$FD,$F4,$F3
'
' Main Code
'
Main:
PAUSE 250
GETTEMPERature:
Celsius = 999
soT = 999
SEROUT Sensor,sensor_baud,[noparse][[/noparse]0,"!TEMR",xslave,$07]
SERIN Sensor,sensor_baud,1000,Main,[noparse][[/noparse]tempL,tempH,pec]
z=0
y = xslave<<1+0
GOSUB calculateCRC
y = $07
GOSUB calculateCRC
y = xslave<<1+1
GOSUB calculateCRC
y = tempL
GOSUB calculateCRC
y = tempH
GOSUB calculateCRC
IF z<>pec THEN GOTO Main
GOSUB convertTemperatures
GOSUB Main
calculateCRC:
w=z^y
READ w,z
RETURN
convertTemperatures:
'DEBUG CLS, "Raw Temp Data: ", DEC temperature, CR
IF (temperature*2) < 27315 THEN overWordsize
Celsius = (temperature/100*2)-273
CelsiusDec = (temperature*2)-27315
GOSUB displayTemperatures
RETURN
overWordsize:
soT = ((27315-(temperature*2))/100)
CelsiusDec = (27315-(temperature*2))
SEROUT 16, Baud, 10, [noparse][[/noparse]CLS, "I-", DEC soT,".",DEC2 CelsiusDec ]
RETURN
displayTemperatures:
SEROUT 16, Baud, 10, [noparse][[/noparse]CLS, "I", DEC Celsius,".",DEC2 CelsiusDec ]
RETURN
Post Edited (everest) : 9/16/2009 4:37:40 AM GMT
In my application I'm seeing highly randomized 2 degree temperature swings in my readings that usually last for up to 10-15 readings before snapping back to normal. This is causing much mayhem with temperature detection! My wiring is incredibly simple, SIG is wired directly to pin 9 and I'm getting +5v and GND to the required pins on the MLX90614 module.
As an example, running the code below I'll see reading like:
29.50
29.53
29.50
27.25
27.10
29.53
29.53
31.40
31.40
The bulk of the readings are accurate, but those 2 degree jumps are just killing me! Any suggestions?
-Jeff
' {$STAMP BS2e}
' ==============================================================================
' I/O Definitions
'
' IR Sensor
Sensor CON 9 'IR Sensor for detecting sky conditions
'
' Constants
'
sensor_baud CON 84
xslave CON $35 'slave address
ShtTemp CON %00011 ' read temperature
ShtHumi CON %00101 ' read humidity
ShtStatW CON %00110 ' status register write
ShtStatR CON %00111 ' status register read
ShtReset CON %11110 ' soft reset (wait 11 ms after)
Ack CON 0
NoAck CON 1
No CON 0
Yes CON 1
MoveTo CON 2 ' for DEBUG control
ClrRt CON 11 ' clear DEBUG line to right
DegSym CON 186 ' degrees symbol for DEBUG
#SELECT $STAMP
#CASE BS2, BS2E, BS2PE
T1200 CON 813
T2400 CON 396
T9600 CON 84
T19K2 CON 32
T38K4 CON 6
#CASE BS2SX, BS2P
T1200 CON 2063
T2400 CON 1021
T9600 CON 240
T19K2 CON 110
T38K4 CON 45
#CASE BS2PX
T1200 CON 3313
T2400 CON 1646
T9600 CON 396
T19K2 CON 188
T38K4 CON 84
#ENDSELECT
Inverted CON $4000
Baud CON T38K4 + Inverted
TRUE CON 0
FALSE CON 1
'
' Variables
'
Inputs VAR Byte
temperature VAR Word
tempL VAR temperature.LOWBYTE
tempH VAR temperature.HIGHBYTE
pec VAR Byte
Celsius VAR Word
CelsiusDec VAR Word
TempDelta VAR Word
w VAR Byte
x VAR Byte
y VAR Byte
z VAR Byte
tC VAR Word ' temp - celcius
ioByte VAR w ' data from/to SHT1x
ackBit VAR x ' ack/nak from/to SHT1x
toDelay VAR y ' timeout delay timer
timeOut VAR z ' timeout status
soT VAR Word ' temp counts from SHT1x - Also recycled to detect a negative temp reading
soRH VAR Word ' humidity counts from SHT1x
rhLin VAR Word ' humidity; linearized
rhTrue VAR Word ' humidity; temp compensated
humSafe VAR Bit
cloudSafe VAR Bit
Dew VAR Bit
Ice VAR Bit
Rain VAR Bit
Humidity VAR Bit
Fail VAR Bit
'
' EEPROM Data
'
PEC0 DATA $00,$07,$0E,$09,$1C,$1B,$12,$15,$38,$3F,$36,$31,$24,$23,$2A,$2D
PEC1 DATA $70,$77,$7E,$79,$6C,$6B,$62,$65,$48,$4F,$46,$41,$54,$53,$5A,$5D
PEC2 DATA $E0,$E7,$EE,$E9,$FC,$FB,$F2,$F5,$D8,$DF,$D6,$D1,$C4,$C3,$CA,$CD
PEC3 DATA $90,$97,$9E,$99,$8C,$8B,$82,$85,$A8,$AF,$A6,$A1,$B4,$B3,$BA,$BD
PEC4 DATA $C7,$C0,$C9,$CE,$DB,$DC,$D5,$D2,$FF,$F8,$F1,$F6,$E3,$E4,$ED,$EA
PEC5 DATA $B7,$B0,$B9,$BE,$AB,$AC,$A5,$A2,$8F,$88,$81,$86,$93,$94,$9D,$9A
PEC6 DATA $27,$20,$29,$2E,$3B,$3C,$35,$32,$1F,$18,$11,$16,$03,$04,$0D,$0A
PEC7 DATA $57,$50,$59,$5E,$4B,$4C,$45,$42,$6F,$68,$61,$66,$73,$74,$7D,$7A
PEC8 DATA $89,$8E,$87,$80,$95,$92,$9B,$9C,$B1,$B6,$BF,$B8,$AD,$AA,$A3,$A4
PEC9 DATA $F9,$FE,$F7,$F0,$E5,$E2,$EB,$EC,$C1,$C6,$CF,$C8,$DD,$DA,$D3,$D4
PEC10 DATA $69,$6E,$67,$60,$75,$72,$7B,$7C,$51,$56,$5F,$58,$4D,$4A,$43,$44
PEC11 DATA $19,$1E,$17,$10,$05,$02,$0B,$0C,$21,$26,$2F,$28,$3D,$3A,$33,$34
PEC12 DATA $4E,$49,$40,$47,$52,$55,$5C,$5B,$76,$71,$78,$7F,$6A,$6D,$64,$63
PEC13 DATA $3E,$39,$30,$37,$22,$25,$2C,$2B,$06,$01,$08,$0F,$1A,$1D,$14,$13
PEC14 DATA $AE,$A9,$A0,$A7,$B2,$B5,$BC,$BB,$96,$91,$98,$9F,$8A,$8D,$84,$83
PEC15 DATA $DE,$D9,$D0,$D7,$C2,$C5,$CC,$CB,$E6,$E1,$E8,$EF,$FA,$FD,$F4,$F3
'
' Main Code
'
Main:
PAUSE 250
GETTEMPERature:
Celsius = 999
soT = 999
SEROUT Sensor,sensor_baud,[noparse][[/noparse]0,"!TEMR",xslave,$07]
SERIN Sensor,sensor_baud,1000,Main,[noparse][[/noparse]tempL,tempH,pec]
z=0
y = xslave<<1+0
GOSUB calculateCRC
y = $07
GOSUB calculateCRC
y = xslave<<1+1
GOSUB calculateCRC
y = tempL
GOSUB calculateCRC
y = tempH
GOSUB calculateCRC
IF z<>pec THEN GOTO Main
GOSUB convertTemperatures
GOSUB Main
calculateCRC:
w=z^y
READ w,z
RETURN
convertTemperatures:
'DEBUG CLS, "Raw Temp Data: ", DEC temperature, CR
IF (temperature*2) < 27315 THEN overWordsize
Celsius = (temperature/100*2)-273
CelsiusDec = (temperature*2)-27315
GOSUB displayTemperatures
RETURN
overWordsize:
soT = ((27315-(temperature*2))/100)
CelsiusDec = (27315-(temperature*2))
SEROUT 16, Baud, 10, [noparse][[/noparse]CLS, "I-", DEC soT,".",DEC2 CelsiusDec ]
RETURN
displayTemperatures:
SEROUT 16, Baud, 10, [noparse][[/noparse]CLS, "I", DEC Celsius,".",DEC2 CelsiusDec ]
RETURN
Post Edited (everest) : 9/16/2009 4:37:40 AM GMT
Comments
This so far has resulted in 100% accurate readings, but it's really a bit alarming how often I notice slight pauses in the read-outs. . .i.e the software is managing errors coming out of the sensor. . .
Any suggestions on the root cause of this would be much appreciated! This is an ugly band-aid fix.
-Jeff
So this problem is a little more complex than I thought. . .bottom line, the sample code that's provided for the MLX90614 appears to be broken. . .because of how it tries to work around the floating point math limitation of the Stamp2, it's mathematically impossible to get anything but an odd number for the temperature value. . .specifically it's this line that's seems to me to be the problem:
Celsius = (temperature/100*2)-273
Celsius is then reported as the temperature value and another equation generates the fractional value. . .but looking at this one I THINK it's pretty easy to see the problem. . .take any value, divide it by 100 and toss out the remainder. . .multiply by 2. . .and subtract 273 (or any odd number for that matter). . .and again, I think you will get an odd number 100% of the time.
I'll admit though that I'm a complete dunce with math. . .could someone sanity check me here??? What am I missing?
-Jeff
-Phil
-Jeff
Excellent find, I have confirmed that it will increment and decrement equally on the 10° FOV sensor; checking to make sure there is no strange situatation with the 90° as well. Sorry for the confusion again, we will get that code updated so no one else has the same issue.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Respectfully,
Joshua Donelson
www.parallax.com
-Jeff