SHT15 dewpoint (part 2 of 2)

fgnash

New Member
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
 
Top