「ノーブランド品 温湿度センサーモジュール DHT11 [並行輸入品]」(送料込で280円)が届いたので動作確認してみました。
DHT11のマニュアルによると温湿度の精度は下記のとおりでそれ程精度は高くありません。
Temperature
- Resolution: 16Bit
- Repeatability: ±0.2℃
- Range: At 25℃ ±2℃
Relative humidity
- Resolution: 16Bit
- Repeatability: ±1% RH
- Accuracy: At 25℃ ±5% RH
Resolutionが16Bitとなっていますが下位バイトはゼロに固定されていますw
また、電源の範囲が「DC 3.5~5.5V」となっていて微妙な値(3.3Vには対応していない)です。試しに3.3Vで動かしてみたらデータは読み取れましたが温度と湿度が5Vの場合と結構違う値になったので5Vで動作確認しました。
特に湿度側は読込む度に値が変動することがあるのである程度平均(または中央値)を取って表示したほうがいいかも知れません。今回は基本動作の確認が目的なので平均は取っていません。
マイコンとのインターフェースは1wire方式で(但し電源と信号線は分離されている)、low側が50usでhigh側の時間は0:26-28us,1:70usとして1bit分のデータを送信しています。
数十マイクロ秒レベルの処理は流石にGAME言語では難しいので例によってインターフェース部分はアセンブラ(アセンブリ言語)で処理しました。
high側の時間をカウントしてbitの0/1判定すればいいだけなので簡単です(無応答の場合のタイムオーバー処理等は省略しています)。
アセンブラソースは次のとおりです。hexファイルは ここ からどうぞ
/*************************************
DotLed driver(MAX7219) and DHT11 I/F
made by skyriver at 2015/12/14
*************************************/
.title "DotMatrixLed and DHT11 I/F"
.include "p24fj64ga002.inc"
.equ F_CPU,16 ; CPU clock/2[MHz]
.equ TMP_MASTER_HI,20000 ; master pulse(usec)
.equ LOOP_PARA,256
.equ DO_BIT,0
.equ CK_BIT,1
.equ CS_BIT,2
.equ DHT_BIT,3
.equ WR_PORT,LATA
.equ RD_PORT,PORTA
.equ RD_TRIS,TRISA
.section .text_Ap,code,address( 0x8000 )
bra LedDrvWr
; read temperature and humidity from DHT11
; W4 <- read data(5 bytes) save area
; humidity(high), humidity(low), temp(high), temp(low), CheckSum
TmpDrv:
push W3
push W5
bclr WR_PORT,#DHT_BIT
bclr RD_TRIS,#DHT_BIT ; set output(low)
mov #(TMP_MASTER_HI / LOOP_PARA ),W0
0: repeat #(F_CPU * LOOP_PARA - 1) ; master pulse width
nop
dec W0,W0
bra NZ,0b
bset RD_TRIS,#DHT_BIT ; set input
repeat #(F_CPU * 210 - 1) ; wait 210 us
nop
mov #(50 * F_CPU / 4),W5 ; set threshold(50us)
mov #5,W2 ; set byte counter
1: mov #8,W1 ; set bit counter
2: clr W0
3: btss RD_PORT,#DHT_BIT
bra 3b ; wait until high
4: inc W0,W0
btsc RD_PORT,#DHT_BIT
bra 4b ; wait until low
cp W0,W5
rlc.b W3,W3
dec W1,W1
bra NZ,2b
mov.b W3,[W4++]
dec W2,W2
bra NZ,1b
pop W5
pop W3
return
; write to LED driver(MAX7219)
; W4 <- data
LedDrvWr:
bclr WR_PORT,#CS_BIT
mov #16,W0 ; set counter
0: sl W4,W4
btss SR,#C
bclr WR_PORT,#DO_BIT
btsc SR,#C
bset WR_PORT,#DO_BIT
bset WR_PORT,#CK_BIT
dec W0,W0
bclr WR_PORT,#CK_BIT
bra NZ,0b
return
.end
|
温湿度センサーのI/Fができたので前回のドットマトリックスLEDを3個カスケード接続したものを表示デバイスとして利用して GAME言語を使って簡単な温湿度計を作ってみました。
3秒間隔で温度と湿度を交互に表示します。この程度のものであればGAME言語を使えば簡単にできてしまいます^^
因みにLEDドライバ及びDHT11の接続は次のとおりです。
■LEDドライバ(電源:5V)
- DIN : RA0(2pin)
- CLK : RA1(3pin)
- LOAD(CS) : RA2(9pin)
■DHT11(電源:5V)
- I/O : RA3(10pin)
★2015/12/15 追記
データ受信時の波形を貼っておきます。マイコンからのスタート信号立上げ[1]直後にDHT11が1周期160usの矩形波を出力してからビットデータの送信が開始されます。
上記アセンブラ処理ではスタート信号立上げ[1]後、210us待ってビットデータ信号のlow部分[2]を捕らえ、信号が立上るのを待ち、highレベルの時間をカウントしています。
GAME言語のソースは次のとおりです。
1' temperature display by skyriver 2015/12/14 10 D=&+5 P=D+3 TA=$2C0 LA=$2C4 CS=4 20 LA:0)=0 TA:0)=$F8 30 #=10000 40' write to driver GorA<-address B<-data 50 A=G*256+B >=$8000 ] 60 A=A*256+B >=$8000 >=$8000 >=$8000 LA:0)=LA:0)|CS ] 999' initialize MAX7219 1000' set no decode mode 1010 A=9 B=0 !=60 1020' set scan limit 0-7 1030 A=11 B=7 !=60 1040' set intencity 1050 A=10 B=4 !=60 1060' set shutdown mode(normal operation) 1070 A=12 B=1 !=60 1080' set Test mode(normal) 1090 A=15 B=0 !=60 1100 ] 1999' write array pattern 2000 G=1,8 B=P:G+D:2)-1) !=50 B=P:G+D:1)-1) !=50 B=P:G+D:0)-1) !=50 LA:0)=LA:0)|CS @=G+1 ] 2999' read temperature 3000 A=& >=$8002 3010 ] 4999' pattern data 5000' 0,1 5010+ 00 7E C1 B1 8D 83 7E 00-00 00 00 82 FF 80 00 00 5020' 2,3 5030+ 00 86 C1 A1 91 89 86 00-00 42 81 81 89 89 76 00 5040' 4,5 5050+ 00 30 28 24 22 FF 20 00-00 4F 89 89 89 89 71 00 5060' 6,7 5070+ 00 7E 89 89 89 89 72 00-00 01 01 C1 31 0D 03 00 5080' 8,9 5090+ 00 76 89 89 89 89 76 00-00 06 89 49 29 19 06 00 5100' C,% 5110+ 04 0A 04 00 7C 82 82 44-04 4A 24 10 08 24 52 20 5120' E,r 5130+ 00 FF 89 89 89 89 81 00-00 00 F8 10 08 08 00 00 6999' hex2bin transfer(nibble) 7000 O=O-"0" ;=O>9 O=O-"A"+"0"+10 7010 ] 7999' set display pattern 8000 R== Q=0 8010 @ 8020 ;=R:3)<>"+" R=R+R:0) #=8090 8030 R=R+4 8040 @ 8050 O=R:1) !=7000 P:Q)=O*16 O=R:2) !=7000 P:Q)=P:Q)+O 8060 R=R+3 Q=Q+1 8070 @=(R:0)=0) 8080 R=R+1 8090 @=(R:0)=0) 8100 ] 10000 !=1000 !=8000 S=0 10010 @ 10020 ¥=300 !=3000 10030 ;=A:4)<>(A:0)+A:1)+A:2)+A:3)) D:0)=12*8 D:1)=13*8 D:2)=D:1) #=10070 10040 VAL=A:0) D:2)=11*8 10050 ;=S=0 VAL=A:2) D:2)=10*8 10060 D:0)=VAL/10*8 D:1)=%(0)*8 10070 !=2000 10080 S=S^1 10090 @ "" @=(¥=0) 10100 @=(0) |
[TOP] [ 前へ ] 連載記事 [ 次へ ]

