前言

玩 Arduino 的,第一個會接觸到的溫度跟濕度感測器十之八九,大概是 DHT 系列的感測器。

這一系列的感測器,因為已經一堆人幫它寫好底層溝通的函式囉,所以真的是使用上超級簡單的。真的不誇張,五分鐘搞定。所以當初筆者也用同樣的方法,很快的開發了一個露點溫度濕度計

但是,現在玩 Flash FORTH 這種少數人口在玩的語言,自然就沒這麼好命囉,這種特殊協定,可是沒人會理你的。

可是啊,其實從頭打造起,來建構程式碼來跟 DHT 系列很特殊的 1-wire 通訊協定來溝通,老實說也不是那麼困難的事情啦。讓我們來練練功,根據規格書來享受一下實作一些特殊通訊協定的樂趣吧。把他當飯後的消遣,就像玩數獨一樣啊! 😬

所以來用 Flash FORTH 實作一下 DHT11, DHT22 這兩個 DHT 系列的溫度濕度雙感測器的溝通讀取吧。

 

DHT11 溫度濕度感測器

關於 DHT11,開門見山,一切從這份規格書談起

DHT系列,這種感測器以往我們都稱呼它為 Smart I/O ,因為它本身已經內建 MCU 了,所以類比的溫濕度感測器的控制就不用我們來操心。只要透過適當的觸發,立即就是透過它們特殊的 1-wire 介面,將溫度跟濕度的數值以「數位」的方式回報給我們的程式中。

所以只要照規格書,把這個硬體層的 1-wire 通訊協定給實作出來,再根據數據的解碼格式解出資料,這樣就完全OK囉!

DHT11 跟 DHT22 是同一系列的溫度濕度感測器。而 DHT11 是  DHT22 的廉價版本,規格跟精確度差 DHT22 蠻多的。個人的經驗,是極不建議買 DHT11 的,因為真的很不準確。之前為了製作露點溫度濕度計,一開始貪便宜,買了4, 5顆 DHT11。可是很驚訝地發現,這麼多顆,每一顆讀出來的讀值都有很大的差異,真是不曉得哪一顆才是正確的。然後是濕度的讀值,跟家裡的濕度計誤差超過40%以上。真是讓人信心全無, DHT11 從此列入拒絕往來戶。而改用 DHT22 後,所有準確度問題迎刃而解。果然,一分錢一分貨,貴,還是品質的保證。

HipstamaticPhoto-649170898.095405.JPG

先來看 DHT11 的規格

  量測範圍 準確度 數值解析度 反應時間
溫度 0 - 50 C +/- 2C 1C 6s - 30s
濕度 20 - 90% RH +/- 5% RH 1% 6s - 15s

 

就說嘛, +/-2C 跟 +/-5%RH 的準確度,很爛的規格厚! (跟玩具差不多...)  😅

 

硬體接線, DHT系列特殊的 1-wire 接法如下面所示

dht pins.png

主要三個 Pin, 電源跟接地兩個 Pin. 另外一個是 Data 資料接腳。 Arduino 用 DIO 接上這個資料接腳,同時必須接上一個 5K 的上拉電阻。

這種 1-wire 的戲法,看久了其實都差不多。都是利用上拉電阻來達到雙向,多個 Slave 跟 Master 一起溝通的目的。要訣也很簡單,平常大家DIO都是在傾聽的狀態,這時候 DIO 必須是高阻抗。上拉電阻的結果,只要線上所有的人都是高阻抗的傾聽態下,自然電位是 5V (HIGH) 準位。

當某個人從高阻抗的傾聽態,轉變成輸出訊號的輸出態時, 當這個 DIO - HIGH (5V) 時候,大家都會看到 HIGH (5V) 。當這個 DIO 拉 LOW (0V) 時,電流流動,上拉電阻限流。這時候所有的人都看到 LOW。

所以只要維持永遠只有一位開啟 DIO 輸出,其他所有人都維持住高阻抗的傾聽態,這樣多方的交談就可以持續。

所以只要一條線,就可以進行多人的訊息交換。 

硬體層的訊息溝通,我們在後面跟程式碼一起解說,這樣才會比較清楚。

 

DHT22 溫度濕度感測器

詳細的規格書在此啊, DHT22 也被稱為 AM2302。

HipstamaticPhoto-649170914.805474.JPG

 

來看 DHT22 的規格

  量測範圍 重複性 數值解析準確度 反應時間
溫度 -40 - 80 C +/- 0.2C 0.1C 2s
濕度 20 - 90% RH +/- 1% RH 0.1%RH 2s

 

可以量到 -40C 喲,解析度,準確性,跟重複性也都不錯喲。 筆者實際使用後的經驗是很滿意的!(但是,價格也是不便宜的啦!😅 )

 

DHT11 跟 DHT22 的接線都是一樣的。硬體層的通訊格式也是一樣的。唯一的差異在資料編碼的格式有差異。一樣,細節後面跟程式碼一起搭配解說會比較清楚些。

 

硬體接線

因為買到的已經是模組囉,所以連上拉電阻都幫你弄好囉。只要簡單的接線就好。

這裡很簡單的把 Arduino Uno Pin2 接到 DHT 的 Data Pin。

Vcc/GND 接一接,這樣就搞定惹。超級簡單的吧!

HipstamaticPhoto-649171197.168717.jpg

 

HipstamaticPhoto-649170820.298724.jpg

 

FORTH 程式碼解說

DHT的 1-wire 硬體層通訊協定

如下所示,分兩大部分

DHT protocol.png

(1) MCU Start 訊號:

首先, MCU 將 DIO 切成輸出狀態,將訊號線拉 LOW 製造 Start 訊號,要求正在傾聽的 DHT 裝置,請傳送資料給我。傳完 Start 訊號後 MCU 立刻將 DIO 切回高阻抗的傾聽狀態,避免干擾訊號線後續其他人的訊號傳輸。

(2) DHT 傳送資料:

DHT 傾聽到 Start 訊號,確認訊號符合規定也接受了,立刻將 DIO 從傾聽的高阻抗狀態轉變成輸出狀態。透過協議好的訊號規則,依序的將訊號線拉High 跟 拉 Low,傳送後續的交握確認跟 40 bits (5 bytes) 的資料。 MCU 傾聽訊號線的訊號,依序的將這些訊號根據協議好的規則重組回濕度跟溫度的資訊。

 

MCU 的 Start 訊號

如下圖所示,

start signal.png

很簡單,當 MCU 開啟 DIO 輸出,將訊號線持續拉 LOW (0V) 至少 18 mS (毫秒)以上, 當DHT 傾聽到這樣的訊號,就會接受觸發,準備接續將 DIO 從高阻抗的傾聽態轉變成電壓的輸出態,開始輸出資料。

送完 Start 訊號後, MCU 必須把 DIO 放回 HIGH (5V) 約 20 - 40 uS (微秒),然後立刻將 DIO 切為高阻抗的傾聽態。開始傾聽由 DHT 所傳送過來的訊息。

這段程式碼如下,首先定義個 delay 指令,用來控制時間用。

: delay for next ;

這個指令利用迴圈來測試,它一次 delay 所花費的時間會是 94ms / 65535 = 1.4343 uS

 

製造 Start 訊號

: start! ( --)
   DHTPin >OUTPUT
   DHTPin ->Low
     20 ms
   DHTPin ->High
     10 delay  ( ~ 14uS)
   DHTPin <INPUT
   
;

看圖說故事,先將 DHTPin 這個資料 DIO 腳位切成 OUTPUT 狀態(>OUTPUT)。 然後拉 Low,持續 20 mS 後將它拉 High,然後給它持續個 14uS 後 ( 10 delay) ,將 DIO 切回高阻抗的傾聽態 (<INPUT),準備傾聽從 DHT傳來的訊息。

 

DHT 傳送資料前的前導訊號

為了怕有問題,所以 DHT 不會立刻傳資料,而是會先傳送如上圖所示的前導訊號來交握。MCU 透過這個訊號(暗號)來確認是否是正在跟外星人交談勒,還是跟貨真價實的 DHT 來交談。如果是貨真價實的 DHT,這時候它會把訊號線拉 Low 約 80uS 後再拉 High 80uS。假如不是這樣,那肯定的現在的那個跟你傳送訊息的不是 DHT 本人囉! 🤷🏻‍♀️

先定義一個等待訊號線拉 High 的傾聽指令

: wait (  --)     \ wait until pulse-high
   begin DHTPin Pin@ until ;
   

就不斷傾聽 DHTPin ,直到訊號不為零 (Low)

 

然後就是完整的傾聽 DHT 送出所有資料的程式碼

: DHT@ ( -- n1 n2 n3 n4 CheckSum)
   start!  
   14 delay ( ~ 20uS)
   wait
   57 delay ( ~ 82uS)
   40bits@
;

先送 Start 訊號,然後我們先等個 20uS ( 14 delay) ,確定已經進到 DHT 傳送 80uS 的前導訊號 Low 之中後,利用 wait 等待前導訊號進入 80uS 的 High 後。精準的再等待 82uS 讓訊號進入 DHT 傳送 40bits 的資料傳送階段,再交由 40bits@ 接力,將 5 bytes ( 40bits) 的濕度跟溫度的資料逐一讀出。

DHT 送完前導訊號後,接下來就是要傳送 5 個 bytes 的資料。5個 bytes 的資料總共 40 bits。這五個 bytes 的資料,前面兩個 bytes 是濕度的資料,接續兩個 bytes 是溫度的資料。最後一個 byte 是 CheckSum 查驗檢查碼,用來確認這4個 bytes 的資料有無錯誤。但要注意的, 雖然硬體層同樣都是傳送 5個 bytes,但 DHT11 跟 DHT22 的濕度,溫度資料編碼並不相同。所以接收完畢後要用不同的編碼方式還原資料。

每一 byte 的資料總共 8 bits,其硬體層傳送的訊息格式如下

bit0.png

DHT 的資料,利用脈波 High 的長短來標示 bit 位元訊號。 脈波比較短的就是 0,脈波比較長的就是1。

首先會先拉 Low 長度 50 uS 的 Start 訊號,來告知並同步資料 bit 要傳送了。當接續的 High 訊號是 26 - 28 uS 的短訊號時,代表這個 bit 是 0

 

bit1.png

首先會先拉 Low 長度 50 uS 的 Start 訊號,來告知並同步資料 bit 要傳送了。當接續的 High 訊號是 70 uS 的長訊號時,代表這個 bit 是 1

所以,判斷單一 bit 脈波長短

: signal@  ( --  true=1/false=0)
   25
   for DHTPin Pin@ 0=
       if  r> 15 <  exit  ( length > 10)
       then
   next
   false abort" Error! Signal not match with expectation!"
;

用 25 次的迴圈來判斷跟量測 High訊號的長度。

這個迴圈每次的執行時間有量測過,每次會花費 293.5ms / 65535 = 4.4785 uS。所以 25次 起碼會跑 112 uS (=25*4.4785 uS) 遠超過 70uS 的長訊號。所以當迴圈執行完畢,還沒看到 Low 訊號的出現時。這肯定是有問題囉,顯示訊號與預期不一致的錯誤訊息並停止執行(Abort)。

而迴圈裡面 DHTPin Pin@ 0= 來判斷是否訊號已經變成 Low 囉,如果是 Low 就根據長度來判斷是 0 還是 1 囉。

關鍵在迴圈的計數, r> 會把迴圈目前的數字取回。 Flash FORTH 的 for-next 是倒數的。所以當這個迴圈的數目小於 15 時,代表迴圈至少執行了 25 - 15 = 10次。10次的執行時間是 10*4.4785 = 44.785 uS > 28 uS 的短脈波時間。所以 當發現已經收到脈波從High變成Low囉,此時 r> 15 < 成立的話就是長脈波,代表 1 ; 否則就是短脈波,代表0。 得到長短脈波 bit 訊號的最終結果後 exit 跳出指令執行。

 

整個 8 bits (1 byte) 的資料讀取

: 8bits@ ( --  Data)
   0  ( data)
   8 for
        wait 
        signal@ if 1 r@ lshift or then
     next
;

用個 8次的 for-next 迴圈。每次先用 wait 來等待前導訊號 Low 的結束,轉到 High 的瞬間交給 signal@ 把這個接續的 High 脈波長度判斷出來,看是0還是1。

DHT的資料有說明,它們是高位元先傳送的。剛好我們的 for-next 是倒數的,所以依序計數是 7, 6, 5 ... 0。所以當判斷出來是1的時候,就把 1 左移 for-next 當時計數的位數,利用 or 把這位元的資料合併進去 data 裡面。依序完成8次,這個 byte 的資料就解出來囉。

 

因為總共有 5 bytes,所以

: 40bits@ ( -- n1 n2 n3 n4 n5)
  5 for 8bits@ next
;

依序接收並解碼 5 bytes 的資料逐一放入堆疊中,完成。

所以執行 DHT@ 指令就可以從 1-wire 中要求 DHT 傳送並接收協議好的,5 bytes 的資料。

 

DHT11 的濕度,溫度資料格式

接下來就是這5個 Bytes 資料的解碼囉。前面有提到了, DHT11 跟 DHT22 硬體層的傳送協定是一樣的,最終都會送5個 bytes 出來。但這5個 bytes 的「意思」不一樣。

DHT11 的格式是: [濕度整數位數字] [濕度小數位數字] [溫度整數位數字] [溫度小數位數字] [CheckSum檢查碼] 共五個數字

其中 [CheckSum檢查碼] = [濕度整數位數字] + [濕度小數位數字] + [溫度整數位數字] + [溫度小數位數字],用來查核前面四個數字有無傳輸錯誤。如果不一致,那就代表傳送不穩定,有資訊於傳送過程中丟失囉。

所以,當接收到 67 0 31 0 98 這五組數字,代表

濕度: 67.00 RH%

溫度: 31.00 C

CheckSum = 67 + 0 + 31 + 0 = 98 和第五個數字一致,所以傳輸成功。

前面也有提過, DHT11 的解析度只有 1% RH 跟 1C 的整數解析度的,所以第二個代表濕度的小數位的數字跟第四個代表溫度的小數位的數字,將永遠為零。

所以,解碼的程式碼

: >DHT11 ( RHint RHdec Tint Tdec Checksum -- RH Temp)
   nip  over -  >r    ( RHint RHdec T R: checksum')
   nip  over r> -
   0= abort" Error: CheckSum not match!!"  
;

Tdec 是溫度小數位,直接 nip 丟掉,留下整數位的溫度 Tint。 然後 CheckSum 跟 Tint 的整數位相減。

RHdec 是濕度小數位,直接 nip 丟掉,留下整數位的濕度 RHint。然後 CheckSum 繼續跟 RHint 的整數位相減。

這時候如果傳輸都正確的話,經過兩次相減 CheckSum 應該變成零囉,如果不是零代表傳輸有錯誤,發出錯誤訊息並 Abort 指令的執行。

 

DHT22 的濕度,溫度資料格式

接下來是 DHT22 的資料格式,比較複雜些。所以直接用規格書的範例來解說囉。

DHT22 format.png

一樣是5個 Bytes: [RH-MSB] [RH-LSB] [T-MSB] [T-LSB] [CheckSum]

CheckSum 依舊為  [CheckSum] =  [RH-MSB] + [RH-LSB] + [T-MSB] + [T-LSB] ,用來查核傳送過程中有無錯誤發生。

不過要留意的喲, CheckSum 只有 1 byte,所以最多只到 255 喲,超過 255 進位的位元資料是會被捨去的。

濕度 = 1/10 * [RH-MSB]*256 + [RH-LSB] ,就是兩個 byte 形成一個 16 bits 的單整數啦,然後一位隱形的小數點。

所以 [0000 0010] [1000 1100]   -->  652 意思為 65.2 % RH 的相對濕度

 

溫度 = 1/10 * [T-MSB]*256 + [T-LSB] ,就是兩個 byte 形成一個 16 bits 的單整數啦,然後一位隱形的小數點。

但是,但是, DHT22 可以感測到 -40 - 0 之間的零下溫度喲。所以 MSB 的最左邊那個 bit 代表正負號。所以當是負的溫度時,要把最左的那個 bit 先弄掉,這樣轉出來的整數才會是對的。

所以 [1000 0000] [0110 0101] = - [0000 0000] [0110 0101] = -101  --> -10.1 C 的溫度

所以,解碼的程式碼

: >DHT22 ( RH.H RH.L T.H T.L Checksum -- RH Temp)
   >r   2dup + >r  
   swap 8 lshift or  >r  ( RH.H RH.L R: T CS1 CS)
   2dup + >r             ( RH.H RH.L R: CS2 T CS1 CS)
   swap 8 lshift or      ( RH R: CS2 T CS1 CS)
   r> r> swap            ( RH T CS2 R: CS1 CS)
   r> +                  ( RH T CS3 R: CS)
   256 u/mod drop
   r> =
   abort" Error: CheckSum not match!!"
   
   $7fff over and  swap ?negate
;

這段程式碼比較多一些堆疊操作,可讀性比較低些。這時候 FORTH 程式設計員常用的技巧就是放上大量的堆疊前後變化的註解。透過這些註解後,其實可讀性也沒那麼糟,日後還是非常容易維護你的程式碼。

就逐步的將四個 bytes 的數字加起來,用來查驗 CheckSum 用。中間會透過 >r 暫時,暫存到返回堆疊。需要的時候再 r> 從返回堆疊搬回來運算。

CheckSum 最後階段都加好,計算好囉, 256 u/mod drop 來讓它不要超過 256,才來好跟收到的 CheckSum 相比較,不一致的話就發出錯誤訊息並 Abort 指令的執行。

8 lshift or 則是將 [MSB] 往左移八位元後跟 [LSB] 用 or 運算進行合併成一個單整數。

最後一個重點是,因為溫度可能有負的,這時候單整數的最左邊 bit 會是 1。所以 $7fff over and 將這個礙眼的 bit 去掉。 當這個 bit 是 1 的時候,2的補數系統會認為是負數。所以 swap ?negate ,當這個數字是負數的時候,把剛剛數字正確的正整數變成正確2的補數的「負整數」,這樣就完工啦。

 

所以,完整 DHT11 取值程式碼

: DHT11@ ( -- RH T)
    DHT@  >DHT11
    10 * >r  10 * r>
;

DHT@ 來跟 DHT感測器透過 1-wire 通訊要資料,然後將資料轉成正確濕度跟溫度順便檢查 CheckSum 有無錯誤。然後為了跟後續 DHT22 格式一致,將溫濕度都乘上10倍。(一位小數的意思)

 

完整 DHT22 取值程式碼

: DHT22@ ( -- RH T)
    DHT@  >DHT22
;

DHT@ 來跟 DHT感測器透過 1-wire 通訊要資料,然後將資料轉成正確濕度跟溫度順便檢查 CheckSum 有無錯誤。

 

列印有帶正負號,一位小數的整數

: .[xx.x]  dup s>d <# # [char] . hold #s rot sign #> type ;

 

最後,不斷取值列印。

 

: DHT11
   cr
   begin
     DHT11@
     ." Temperature = "       .[xx.x] ." C , "
     ." Relative Humidity = " .[xx.x] ." %"    cr
     2000 ms
   again
;


: DHT22
   cr
   begin
     DHT22@
     ." Temperature = "       .[xx.x] ." C , "
     ." Relative Humidity = " .[xx.x] ." %"    cr
     2000 ms
   again
;

 

執行結果

DHT11 的結果

DHT11 Result.png

只要故意一拔掉感測器,立刻因為脈波不對而 Abort 掉。真的是運作完美! 😭

然後這是什麼爛感測器,台灣的夏天什麼時候曾經可以讓你有機會相對濕度 33% RH 的喲! 🤬

HipstamaticPhoto-649171190.131693.JPG

 

DHT22 的結果

DHT22 Result.png

運作很完美的啦!超級感動的哩!! 😬

相對濕度 65.4% RH ,這個還差不多一點!! 

HipstamaticPhoto-649170805.926089.JPG

 

測試影片

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Frank Lin(@ohiyooo)分享的貼文

 

 

 

原始程式列表

 

\
\  DHT11 DHT22 1-wire Control Code - Flash FORTH
\     Frank Lin 2021.07.27
\

 

marker --dio--

\
\ bit masks
\


%00000001 constant bit0
%00000010 constant bit1
%00000100 constant bit2
%00001000 constant bit3
%00010000 constant bit4
%00100000 constant bit5
%01000000 constant bit6
%10000000 constant bit7


\
\ Atmega328 Digital I/O Registers
\

#37 constant PortB
#40 constant PortC
#43 constant PortD

 

: Pin_Def ( mask Port "Name" --)
    2constant
;


\
\  Arduino Uno with ATmega328 Pin definations
\


flash

bit0 PortD  Pin_Def Pin0
bit1 PortD  Pin_Def Pin1
bit2 PortD  Pin_Def Pin2
bit3 PortD  Pin_Def Pin3
bit4 PortD  Pin_Def Pin4
bit5 PortD  Pin_Def Pin5
bit6 PortD  Pin_Def Pin6
bit7 PortD  Pin_Def Pin7

bit0 PortB  Pin_Def Pin8
bit1 PortB  Pin_Def Pin9
bit2 PortB  Pin_Def Pin10
bit3 PortB  Pin_Def Pin11
bit4 PortB  Pin_Def Pin12
bit5 PortB  Pin_Def Pin13

bit0 PortC  Pin_Def Pin14
bit1 PortC  Pin_Def Pin15
bit2 PortC  Pin_Def Pin16
bit3 PortC  Pin_Def Pin17
bit4 PortC  Pin_Def Pin18
bit5 PortC  Pin_Def Pin19


\
\   Digital I/O Access Codes
\


: >OUTPUT ( mask port --)   \ set the direction of digital I/O to output
   1-     ( DDR register)
   mset   ( set to High = OUTPUT)
;

: <INPUT  ( mask port --)   \ set the direction of digital I/O to input
   1-     ( DDR register)
   mclr   ( set to Low = INPUT)
;

: PULLUP ; immediate       \ dummy for syntax sweeter

: ->High ( mask port --)   \ put digital I/O to High
   mset
;

: ->Low  ( mask port --)   \ put digital I/O to Low
   mclr
;

: Pin@ ( mask port -- status)   \ read the state of digital I/O, 0=false
   2-     ( Pin register)
   mtst   ( read the state)
;

 

 

marker --dht--


Pin2 Pin_Def DHTPin


\
\ DIO speed test
\

: t1 ticks Pin2 $ffff for 2dup Pin@ 0= if then next 2drop ticks swap - . ;

\
\ result: 355 ms / 65535 = 5.417 uS
\


: t2 ticks $ffff for DHTPin Pin@ if then next ticks swap - . ;

\
\  result: 293.5 ms / 65535 = 4.4785 uS
\

\
\ DHT signal:
\   start: 50uS Low
\   signal 1:      70 uS Pulse High  = 70 / 4.4785 = 15.6 
\   signal 0: 26 - 28 uS Pulse High  = 27 / 4.4785 =  6.02


: delay for next ;

\
\ 1 delay will take 94ms / 65535 = 1.4343 uS
\


: wait (  --)     \ wait until pulse-high
   begin DHTPin Pin@ until ;
   
   
: signal@  ( --  true=1/false=0)
   25
   for DHTPin Pin@ 0=
       if  r> 15 <  exit  ( length > 10)
       then
   next
   false abort" Error! Signal not match with expectation!"
;


: 8bits@ ( --  Data)
   0  ( data)
   8 for
        wait 
        signal@ if 1 r@ lshift or then
     next
;

: 40bits@ ( -- n1 n2 n3 n4 n5)
  5 for 8bits@ next
;

\
\  Start Signal
\   18mS Low, to active communication  
\   then 20 - 40uS High
\   then wait DHT sends 80uS Low, 80uS High
\   then receive 40bits data transmition from DHT
\

\
\ 20uS = 20/1.434 ~ 14 delay
\ 82uS = 82/1.434 ~ 57 delay
\

: start! ( --)
   DHTPin >OUTPUT
   DHTPin ->Low
     20 ms
   DHTPin ->High
     10 delay  ( ~ 14uS)
   DHTPin <INPUT
   
;

: DHT@ ( -- n1 n2 n3 n4 CheckSum)
   start!  
   14 delay ( ~ 20uS)
   wait
   57 delay ( ~ 82uS)
   40bits@
;


: >DHT11 ( RHint RHdec Tint Tdec Checksum -- RH Temp)
   nip  over -  >r    ( RHint RHdec T R: checksum')
   nip  over r> -
   0= abort" Error: CheckSum not match!!"  
;
   

: >DHT22 ( RH.H RH.L T.H T.L Checksum -- RH Temp)
   >r   2dup + >r  
   swap 8 lshift or  >r  ( RH.H RH.L R: T CS1 CS)
   2dup + >r             ( RH.H RH.L R: CS2 T CS1 CS)
   swap 8 lshift or      ( RH R: CS2 T CS1 CS)
   r> r> swap            ( RH T CS2 R: CS1 CS)
   r> +                  ( RH T CS3 R: CS)
   256 u/mod drop
   r> =
   abort" Error: CheckSum not match!!"
   
   $7fff over and  swap ?negate
;

: DHT11@ ( -- RH T)
    DHT@  >DHT11
    10 * >r  10 * r>
;

: DHT22@ ( -- RH T)
    DHT@  >DHT22
;


: .[xx.x]  dup s>d <# # [char] . hold #s rot sign #> type ;


: DHT11
   cr
   begin
     DHT11@
     ." Temperature = "       .[xx.x] ." C , "
     ." Relative Humidity = " .[xx.x] ." %"    cr
     2000 ms
   again
;


: DHT22
   cr
   begin
     DHT22@
     ." Temperature = "       .[xx.x] ." C , "
     ." Relative Humidity = " .[xx.x] ." %"    cr
     2000 ms
   again
;

   
   
   

   
   

   

 
   

   

arrow
arrow
    創作者介紹
    創作者 ohiyooo2 的頭像
    ohiyooo2

    早安,苦命工程師的胡言亂語

    ohiyooo2 發表在 痞客邦 留言(0) 人氣()