Code:
;
;
; read the temperature and relative humidity from the SHT15
;
ReadSHT:
; on exit b16+b17 = ascii temperature
; b18+b19 = ascii humidity
; b20+b21 = ascii dewpoint
;
; TEMPERATURE
:
gosub CmdStartSHT ; command initiation sequence
; send the read temperature command, b'00000011
low sdata ; ready to send 6 zeros...
pulsout sclk,165
pulsout sclk,165
pulsout sclk,165
pulsout sclk,165
pulsout sclk,165
pulsout sclk,165
input sdata ; ...and pulled high for two ones
pulsout sclk,165
pulsout sclk,165
; now wait for him to pull the data pin low
RSAloop1:
if sdatai = 1 then goto RSAloop1
; command acknowledged, send 9th sclk
pulsout sclk,165 ; ninth pulse to trigger ack
; wait for data line to be released
RSMloop1:
if sdatai = 0 then goto RSMloop1
; now wait for the measurement to complete
RSIloop1:
if sdatai = 1 then goto RSIloop1
; clock the two bytes (12 bits) of temperature into b0+b1
gosub ClkInSht
; convert the result to two ascii bytes in b16+b17
gosub CalcTemp
;
; HUMIDITY
;
gosub CmdStartSHT ; command initiation sequence
; send the read humidity command, b'00000101
low sdata ; ready to send 5 zeros...
pulsout sclk,165
pulsout sclk,165
pulsout sclk,165
pulsout sclk,165
pulsout sclk,165
input sdata ; let data be pulled high to send ...a one
pulsout sclk,165
low sdata ; ...another zero
pulsout sclk,165
input sdata ; ...and a final one
pulsout sclk,165
; wait for him to ack by pulling data low
RSAloop2:
if sdatai = 1 then goto RSAloop2
; command acknowledged, send 9th sclk
pulsout sclk,165 ; ninth pulse to trigger ack
; wait for data line to be released
RSMloop2:
if sdatai = 0 then goto RSMloop2
; now wait for the measurement to complete
RSIloop2:
if sdatai = 1 then goto RSIloop2
; clock the two bytes (14 bits) of humidity into b0+b1
gosub ClkInSht
; convert the result to two ascii bytes in b18+b19
gosub CalcHumid
;
; DEWPOINT
;
; calculate the dewpoint to 2 ascii bytes in b20+b21
gosub CalcDewpoint
return
;
;
UpdateLCD:
b0 = $01
gosub SendCmdByte ; clear LCD display
b0 = "F"
gosub SendDataByte
b0 = temp10
gosub SendDataByte
b0 = temp01
gosub SendDataByte
b0 = " "
gosub SendDataByte
b0 = "H"
gosub SendDataByte
b0 = humd10
gosub SendDataByte
b0 = humd01
gosub SendDataByte
b0 = $C0 ; 2nd line
gosub SendCmdByte
b0 = " "
gosub SendDataByte
b0 = "D"
gosub SendDataByte
b0 = "P"
gosub SendDataByte
b0 = "="
gosub SendDataByte
b0 = dewp10
gosub SendDataByte
b0 = dewp01
gosub SendDataByte
return
;
;
; SUBROUTINES
;
CmdStartSHT:
input sdata ; init data high
low sclk ; clk low
pulsout sclk,165 ; toggle the clock nine times
pulsout sclk,165
pulsout sclk,165
pulsout sclk,165
pulsout sclk,165
pulsout sclk,165
pulsout sclk,165
pulsout sclk,165
pulsout sclk,165
; command start sequence
input sdata ; data high
high sclk ; while clock is high
low sdata ; pull data down
low sclk ; toggle the clock
high sclk ; ...while data is low
input sdata ; finally raise data while clk is still high
low sclk ; finish transmission start protocol
return
;
;
ClkInSht:
;
input sdata ; data pin pulled high
low sclk ; clock starts low
; read the high order byte
b1 = 0 ; clear output and
b2 = 0 ; ...loop counter
do
b1 = b1 << 1 ; shift result byte left 1 bit
high sclk ; rising edge to prompt data
bit8 = sdatai ; copy input bit to b1's low order bit
low sclk ; falling edge to finish this bit
inc b2
loop while b2 < 8 ; read all 8 bits
low sdata ; pull data low to acknowledge the byte
pulsout sclk,165 ; ack to allow reading the 2nd byte
;
input sdata ; data pin pulled high
; read the low order byte
b0 = 0 ; clear output and
b2 = 0 ; ...loop counter
do
b0 = b0 << 1 ; shift result byte left 1 bit
high sclk ; rising edge to prompt data
bit0 = sdatai ; copy input bit to b0's low order bit
low sclk ; falling edge to finish this bit
inc b2
loop while b2 < 8 ; read all 8 bits
; ignore the CRC byte by not pulling the data pin low to ack
; b1 = high order byte from SHT15, b0 = low order byte from SHT15
return
;
;
CalcTemp:
; input: b0 = high order 6 bits, b1 = low order 8 bits
; from Jon Williams, Nuts and Volts #91, 2002
; tC = soT * .01 - 40
; tC = soT / 10 - 400 'convert to tenths C
; tF = soT * .018 - 40
; tF = soT ** 11796 - 400 'convert to tenths F
; soT = w0
; tF = w18
; tC = W19
soT = w0 ;save sensor output
tC = soT / 100 - 40 ;Celcius in degrees
tF = soT ** 11796
tF =tF - 400 ;Fahrenheit in 10ths of a degree
tF = tF / 10 ;Fahrenheit in degrees
bintoascii tF,null,temp10,temp01 ;temp in F as 2 ascii bytes
return
;
;
CalcHumid:
; input: b0 = high order 4 bits, b1 = low order 8 bits,
; from Jon Williams, Nuts and Volts #91, 2002
; soRH = W20
; rhLin = W22
; truRH = W23
; rhLin = (soRH ** 26542)
; rhLin = rhLin - ((soRH ** 3468) * (soRH ** 3468) + 50 / 100)
; rhLin = rhLin - 40
; which becomes
soRH = w0 ;save sensor output
rhLin = soRH ** 26542
w2 = soRH ** 3468
w3 = w2 * w2
w3 = w3 + 50
w3 = w3 / 100
rhLin = rhLin - w3
rhLin = rhLin - 40
rhLin = rhLin / 10
; compensation for temperatures distant from 77F
; rhTrue = ((tC / 10 - 25) * (soRH ** 524 + 1)
; rhTrue = rhTrue + (rhLin * 10)) + 5 / 10
w1 = tC - 25
w2 = soRH ** 524 + 1
truRH = w1 * w2
w1 = rhLin * 10
w2 = 5 / 10
w1 = w1 + w2
truRH = truRH + w1
truRH = truRH / 10 ;from 10ths of a percent to whole
bintoascii truRH,null,humd10,humd01 ;humidity in 2 ascii bytes
return
;
;
CalcDewpoint:
; see SHT15 datasheet for dewpoint formula
; ln(RH/100%) is really negative: reverse the sign in use below
readtable truRH,dpLn ; natural log of RH/100 or RH in percent,
; which is Ln x 100, no decimal points
; (1762 * T) / (243 + T) ; used twice in the formula
w1 = 1762 * tC
w2 = 243 + tC
dpmT = w1 / w2
;(243 * (dpmT - Ln)) / (1762 + ln - dpmT)
w1 = dpmT - dpLn
w1 = w1 * 243
w2 = 1762 + dpLn - dpmT
w3 = w1 / w2 ;dewpoint in Celcius
dewpt = w3 * 9 / 5 + 32 ;dewpoint in Fahrenheit
bintoascii dewpt,null,dewp10,dewp01 ;dewpoint in F as 2 ascii bytes
return
;
;
; LCD OUTPUT
; random pin version after Hippy's 18X LCD tutorial
; b0 contains the 8 bit command or data
;
SendInitialCmdByte:
pause 40 ; check your LCD datasheet
SendCmdByte:
low RS ; Send to Command register
SendDataByte:
LCD11 = bit4 ; high order nib
LCD12 = bit5
LCD13 = bit6
LCD14 = bit7
pulsout E,24
LCD11 = bit0 ; low order nib
LCD12 = bit1
LCD13 = bit2
LCD14 = bit3
pulsout E,24
high RS ; Default to Data byte as next char
return
;
;
InitLCD:
b0 = $33 ; 8bit to set 4 bit
gosub SendInitialCmdByte
b0 = $32 ; 4 bit from now on
gosub SendCmdByte
b0 = $28 ; 2 line
gosub SendCmdByte
b0 = $0C ; turn on display with simple cursor
gosub SendCmdByte
b0 = $01 ; clear the screen
gosub SendCmdByte
return
;
end