'{$STAMP BS2sx} ' sht1xdp.bsx rev C ' (C) 2002 Tracy Allen, tracy@emesystems.com ' access the Sensirion model sht11 or sht15 humidity and temperature chip ' rev B, corrected glaring error in humidity computation ' rev C added dew point calculation ' responds to keyboard commands: ' s1 gets temperature ' s2 gets humidity ' s3 turns on the sht1x internal heater ' s4 turns off the heater ' s5 gets the dew point temperature, calculated from temperature and RH ' s0 resets the interface to the sht1x sck con 0 ' connect to clock line on sht1x dta con 1 ' data line, with 5k-10k pullup and 330ohm isolation from stamp to sht dtain var in1 ' data for sht15, referenced as input on stamp. shtTR con 3 ' read temperature, sht1x command shtRH con 5 ' read humidity shtSW con 6 ' status register write shtSR con 7 ' status register read shtS0 con 30 ' restore status register defaults (then delay 11 milliseconds) baud con $f0 ' 9600, $f0 for BS2sx/p, $54 for BS2/e/pe <--SET FOR YOUR STAMP! LF con 10 ' line feed cmd var byte ' command to sht1x degC var word ' degrees Celsius * 100 RH var word ' %RH RHtc var word ' for temperature compensation of RH logEW var word ' log10 of saturation vapor pressure, calculated from degC & RH DP var word ' dew point, calculated from degC & RH ix var byte ' loop index wx var word ' temporary variable result var wx ' alias, result from sht r0 var result.byte0 r1 var result.byte1 wy var word ' temporary in calculations wz var word ' ditto wj var word ' ditto, integer part LFb var bit ' line feed flag sign var bit ' sign in calculations bt var bit ' for calculations heat var bit ' state of the sht1x heater, on=1 off=0 initialize: outs=0 dirs=%1111111111111101 gosub shtrst ' reset communication with sht goto heatOff mainloop: serout 16,baud,[">"] serin 16,baud,[wait("s"),cmd] if cmd<48 or cmd>57 then mainloop branch cmd-48,[initialize,getTemperature0,getHumidity0,heatOn,heatOff,getDewPoint0,nada,nada,nada,lineFeed] nada: goto mainloop getTemperature0: gosub getTemperature serout 16,baud,[tab,"dgC=",rep "-"\sign,dec abs degC/10,".",dec1 abs degC,cr,rep LF\LFb] goto mainloop getHumidity0: gosub getHumidity serout 16,baud,[tab,"%RH=",dec RHtc/10,".",dec1 RHtc,cr,rep LF\LFb] goto mainloop getDewPoint0: gosub getTemperature gosub getHumidity gosub getDewPoint serout 16,baud,[tab,"dpC=",rep "-"\sign,dec abs DP/10,".",dec1 abs DP,cr,rep LF\LFb] goto mainloop getTemperature: cmd=shtTR gosub shtget16 degC=result-4000 ' deg C *100 sign=degC.bit15 degC=-sign^(abs degC +5/10)+sign return getHumidity: cmd=shtRH gosub shtget16 RH=(26542-(54722**result+result))**result-40 ' temperature compensation follows: RHtc=655+(result*5)+(result**15917) ' intermediate computation RHtc=(RHtc**(degC+2480))-(RHtc**2730)+RH ' compensated value return: getdewPoint: ' enter with -4001000 ' maximum at +100 degrees C, 100%RH, where logEW=+28843 (+2.8843) ' minimum at -40 degrees C, 1%RH, where logEW=-28598 (-2.8598) ' calculate logEW/4, so divisor in divide below will be <32768 sign=logEW.bit15 logEW=-sign^(abs logEW+2/4)+sign ' logEW/4, sign extended wx=1652-logEW ' numerator sign=~wx.bit15 ' for dewpoint calculation, DP sign is opposite of wx wx=abs wx wy=20402-logEW gosub divide ' this a always a proper fraction, no integer part DP=23730**wz+5/10 ' fractional multiply, note extra decimal place and roundoff DP=-sign^DP+sign ' extend sign return divide: ' enter with wx and wy positive integers to divide wj=wx/wy ' integer part of result for ix=15 to 0 ' wz to be fractional part (as wz/65536 implied) wx=wx//wy<<1 wz.bit0(ix)=wx/wy next return log2: ' enter with wx, to find log base 2 wj=ncd wx - 1 ' integer part of result (characteristic, 0<=wb<=15) wx=wx<<(15-wj) ' left justify the operand wz=0 for ix=14 to 0 ' wz to be fractional part (mantissa, as wz/32768 implied) wy=wx**wx wz.bit0(ix)=wy.bit15 bt=~wy.bit15 wx=wy<