SHT75 temp/humidity sensor giving inaccurate value
I have just written a little Spin routine to try to communicate with this sensor, all seemed to be going well and i was able to read the Humidity value and compare it to another sensor and it looks fine. however, when i attempt to read the temperature it looks ok at room temperature but not what i would expect to see when i blow on it.
when it has stabilized i see a reading of :
Humidity:48.64648% degC:19.37 RawTempBin:01011100010111 RawTempDec:5911 degF:66.86601
but when i breath on it (for about 10 seconds) i get somewhere around:
Humidity:93.04173% degC:79.41001 RawTempBin:10111010000111 RawTempDec:11911 degF:174.938
174.9 degreesF !!! ?????
im not sure what to make of it other than im not understanding what exactly a band:gap PTAT (Proportional To Absolute Temperature) temperature sensor really is..
further more, i have watched the output on a scope to confirm that the "RawTempBin" value is correct. that being said i have taken the RawTempDec value and punched it into the formula (T=d1+d2*SOt) provided in the pdf using the values:
d1 = -39.7
d2 = 0.01
the output was as expected and confirms that the math is correct in Spin.
PDF is here:
http://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/Humidity/Sensirion_Humidity_SHT7x_Datasheet_V5.pdf
my code for communication with the SHT75:
thank you all for your help
[EDIT]
ok i found a problem, where i specify the commands i accidentally copy-pasted the command %00000101 twice when it should have been %00000011 for temp readings. so i changed it to:
SHTAddr byte %000
RHcommand byte %00000101
TEMPcommand byte %00000011
the readings however are still a little high.
room temperature -
Humidity:49.03014% degC:54.73 RawTempBin:10010011110011 RawTempDec:9459 degF:130.514
breath-
Humidity:90.55299% degC:76.21 RawTempBin:10110010100111 RawTempDec:11431 degF:169.178
hmm... 38.6 degree delta, that's better i suppose.. but still that's almost a 56 degree offset from our cozy 74F room temp.
when it has stabilized i see a reading of :
Humidity:48.64648% degC:19.37 RawTempBin:01011100010111 RawTempDec:5911 degF:66.86601
but when i breath on it (for about 10 seconds) i get somewhere around:
Humidity:93.04173% degC:79.41001 RawTempBin:10111010000111 RawTempDec:11911 degF:174.938
174.9 degreesF !!! ?????
im not sure what to make of it other than im not understanding what exactly a band:gap PTAT (Proportional To Absolute Temperature) temperature sensor really is..
further more, i have watched the output on a scope to confirm that the "RawTempBin" value is correct. that being said i have taken the RawTempDec value and punched it into the formula (T=d1+d2*SOt) provided in the pdf using the values:
d1 = -39.7
d2 = 0.01
the output was as expected and confirms that the math is correct in Spin.
PDF is here:
http://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/Humidity/Sensirion_Humidity_SHT7x_Datasheet_V5.pdf
my code for communication with the SHT75:
CON
_clkmode = xtal1 + pll16x 'Standard clock mode * crystal frequency = 80 MHz
_xinfreq = 5_000_000
sclk = 1
data = 0
trigger = 2
var
long address[2]
long command[4]
long compound[4]
OBJ
ser : "fullduplexserial"
f : "FloatMath"
fp : "FloatString"
DAT
c1 long -2.0468
c2 long 0.0367
c3 long -1.5955 * (0.000001)
d1 long -39.7
d2 long 0.01
SHTAddr byte %000
RHcommand byte %00000101
TEMPcommand byte %00000101
PUB main | tempC, tempRaw
ser.start(31,30,0,115200)
'fp.SetPositiveChr(" ")
dira[trigger]~~
repeat
waitcnt(clkfreq/1 + cnt)
ser.str(string("H:"))
ser.str(fp.FloatToString(GetRH))
ser.str(string(" C:"))
tempC := GetTEMP
ser.str(fp.FloatToString(tempC))
ser.str(string(" Raw:"))
tempRaw := GetTEMPRaw
ser.bin(tempRaw,14)
ser.str(string(" dec:"))
ser.dec(tempRaw)
ser.str(string(" F:"))
ser.str(fp.FloatToString(cvtCtoF(tempC)))
ser.tx(13)
PRI calc_dp(temp,humidity)
PRI cvtCtoF(celsius)
return f.FAdd(f.FMul(1.8,celsius),32.0)
PRI calc_rh(RHraw)
compound[0] := f.FMul(c2, f.FFloat(RHraw))
compound[1] := f.FMul(c3,f.FFloat(RHraw*RHraw))
compound[2] := f.FAdd(compound[0],compound[1])
return f.FAdd(c1,compound[2])
PRI calc_T(Traw)
compound[0] := f.FMul(d2, f.FFloat(Traw))
return f.FAdd(d1, compound[0])
PRI GetRH | RHdata
InitCom
SendAddr(SHTAddr)
SendCmd(RHcommand)
AckAndWait
SendIdleBits
RHdata := ReadInData(12)
EndTrans
return calc_rh(RHdata)
PRI GetTemp | TEMPdata
InitCom
SendAddr(SHTAddr)
SendCmd(TEMPcommand)
AckAndWait
SendIdleBits
TEMPdata := ReadInData(14)
EndTrans
return calc_T(TEMPdata) 'calc_T(TEMPdata)
PRI GetTempRaw | TEMPdata
InitCom
SendAddr(SHTAddr)
SendCmd(TEMPcommand)
AckAndWait
SendIdleBits
outa[Trigger]~~
TEMPdata := ReadInData(14)
outa[Trigger]~
EndTrans
return TEMPdata
PRI ReadInData(len) | output
output := 0
repeat 4
outa[sclk]~~
pause
output := (output << 1) + ina[data]
outa[sclk]~
pause
repeat while ina[data] == 0
pause
dira[data]~~
outa[data]~
pause
outa[sclk]~~
pause
outa[sclk]~
pause
dira[data]~
repeat len-4
outa[sclk]~~
pause
output := (output << 1) + ina[data]
outa[sclk]~
pause
return output
PRI EndTrans
dira[data]~~
outa[data]~
PRI ACK
outa[sclk]~~
pause
outa[sclk]~
pause
PRI SendIdleBits
repeat 4 'idle bits
outa[sclk]~~
pause
outa[sclk]~
pause
PRI AckAndWait
outa[sclk]~~
pause
outa[sclk]~
pause
dira[data]~
repeat while ina[data] == 1
'long wait here for sensor to take measurement
PRI InitCom
dira[sclk]~~
dira[data]~~
outa[sclk]~
outa[data]~~
outa[sclk]~~
pause
outa[data]~
pause
outa[sclk]~
pause
outa[sclk]~~
pause
outa[data]~~
pause
outa[sclk]~
pause
outa[data]~
pause
PRI SendAddr(adr) | x
repeat x from 0 to 2
outa[data] := (adr >> x) & 1
outa[sclk]~~
pause
outa[sclk]~
outa[data]~
pause
PRI SendCmd(cmd) | x
repeat x from 4 to 0
outa[data] := (cmd >> x) & 1
outa[sclk]~~
pause
outa[sclk]~
outa[data]~
pause
PRI SendRegVal(Value) | x
repeat x from 7 to 0
outa[data] := (Value >> x) & 1
outa[sclk]~~
pause
outa[sclk]~
outa[data]~
pause
PUB pause
waitcnt(1000+ cnt)
thank you all for your help
[EDIT]
ok i found a problem, where i specify the commands i accidentally copy-pasted the command %00000101 twice when it should have been %00000011 for temp readings. so i changed it to:
SHTAddr byte %000
RHcommand byte %00000101
TEMPcommand byte %00000011
the readings however are still a little high.
room temperature -
Humidity:49.03014% degC:54.73 RawTempBin:10010011110011 RawTempDec:9459 degF:130.514
breath-
Humidity:90.55299% degC:76.21 RawTempBin:10110010100111 RawTempDec:11431 degF:169.178
hmm... 38.6 degree delta, that's better i suppose.. but still that's almost a 56 degree offset from our cozy 74F room temp.

Comments
i may use it in the final design of my project but as for now i did figure out why my Spin wasnt showing the correct value. so before i let this thread go id like to post my updated code for anyone who would like it.
CON _clkmode = xtal1 + pll16x 'Standard clock mode * crystal frequency = 80 MHz _xinfreq = 5_000_000 sclk = 1 data = 0 trigger = 2 T_OFFSET_5V0 = 4000 T_OFFSET_3V3 = 3964 T_OFFSET_3V0 = 3960 T_OFFSET = T_OFFSET_3V3 var long address[2] long command[4] long compound[4] OBJ ser : "fullduplexserial" f : "Float32" fp : "FloatString" DAT c1 long -2.0468 c2 long 0.0367 c3 long -1.5955 * (0.000001) d1 long -39.7 d2 long 0.01 SHTAddr byte %000 RHcommand byte %00000101 TEMPcommand byte %00000011 PUB main | tempC, tempF, rh, rawHumidity ser.start(31,30,0,115200) 'fp.SetPositiveChr(" ") f.start dira[trigger]~~ repeat rawHumidity := GetRH tempC := GetTEMP tempF := cvtCtoF(tempC) waitcnt(clkfreq/10 + cnt) ser.str(string("H:")) ser.str(fp.FloatToString(rawHumidity)) ser.str(string(" C:")) ser.str(fp.FloatToString(tempC)) ser.str(string(" F:")) ser.str(fp.FloatToString(tempF)) ser.str(string(" DP:")) ser.str(fp.FloatToString(dewpoint(tempF,rawHumidity))) ser.tx(13) PRI dewpoint(t, rh) | h ' h = (log10(rh) - 2.0) / 0.4343 + (17.62 * t) / (243.12 + t) h := f.FAdd(f.FDiv(f.FSub(f.log10(rh), 2.0), 0.4343), f.FDiv(f.FMul(17.62, t), f.FAdd(243.12, t))) ' dewpoint = 243.12 * h / (17.62 - h) return f.FDiv(f.FMul(243.12, h), f.FSub(17.62, h)) PRI cvtCtoF(celsius) return f.FAdd(f.FMul(1.8,celsius),32.0) PRI calc_rh(RHraw) compound[0] := f.FMul(c2, f.FFloat(RHraw)) compound[1] := f.FMul(c3,f.FFloat(RHraw*RHraw)) compound[2] := f.FAdd(compound[0],compound[1]) return f.FAdd(c1,compound[2]) PRI calc_T(Traw) compound[0] := f.FMul(d2, f.FFloat(Traw)) return f.FAdd(d1, compound[0]) PRI GetRH | RHdata InitCom SendAddr(SHTAddr) SendCmd(RHcommand) AckAndWait RHdata := 0 RHdata := ReadInData(RHdata) AckData RHdata := ReadInData(RHdata) EndTrans return calc_rh(RHdata) PRI GetTemp | TEMPdata InitCom SendAddr(SHTAddr) SendCmd(TEMPcommand) AckAndWait TEMPdata := 0 TEMPdata := ReadInData(TEMPdata) AckData TEMPdata := ReadInData(TEMPdata) EndTrans return calc_T(TEMPdata) 'calc_T(TEMPdata) PRI AckData repeat while ina[data] == 0 pause dira[data]~~ outa[data]~ pause outa[sclk]~~ pause outa[sclk]~ pause dira[data]~ PRI ReadInData(output) dira[data]~ repeat 8 outa[sclk]~~ pause output := (output << 1) + ina[data] outa[sclk]~ pause return output PRI EndTrans dira[data]~~ outa[data]~ PRI ACK outa[sclk]~~ pause outa[sclk]~ pause PRI AckAndWait outa[sclk]~~ pause outa[sclk]~ pause dira[data]~ repeat while ina[data] == 1 'long wait here for sensor to take measurement PRI InitCom dira[sclk]~~ dira[data]~~ outa[sclk]~ outa[data]~~ outa[sclk]~~ pause outa[data]~ pause outa[sclk]~ pause outa[sclk]~~ pause outa[data]~~ pause outa[sclk]~ pause outa[data]~ pause PRI SendAddr(adr) | x repeat x from 0 to 2 outa[data] := (adr >> x) & 1 outa[sclk]~~ pause outa[sclk]~ outa[data]~ pause PRI SendCmd(cmd) | x repeat x from 4 to 0 outa[data] := (cmd >> x) & 1 outa[sclk]~~ pause outa[sclk]~ outa[data]~ pause PRI SendRegVal(Value) | x repeat x from 7 to 0 outa[data] := (Value >> x) & 1 outa[sclk]~~ pause outa[sclk]~ outa[data]~ pause PUB pause waitcnt(4000 + cnt)unfortunately the dewpoint method does not seem to work correctly, it was pulled out of another object for the SHT11, if anyone is ever able to figure out why i would really love to know!