So-net無料ブログ作成
English Version

PIC24FJ64GAでGAME言語(その8) [PIC]

 前回書いたドットマトリックスLEDもそうなのですが、Amazon で中国製の格安モジュールを見つけるとつい買ってしまいますね w
 「ノーブランド品 温湿度センサーモジュール 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ファイルは ここ からどうぞ

 DHT11 and LED driver I/F(アセンブラ)
/*************************************
  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レベルの時間をカウントしています。

DHT11信号波形例



 GAME言語のソースは次のとおりです。

 温湿度計サンプル(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] [ 前へ ] 連載記事 [ 次へ ]
nice!(0)  コメント(0)  トラックバック(1) 
共通テーマ:趣味・カルチャー

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 1