Raspberry Piを備えた複数の温度センサー


19

Raspberry Piで1つの温度センサーを使用する例はたくさんありますが、5-6個の温度センサーをRaspberry Piに多重化するにはどうすればよいですか?複数のソースから同時に温度を読み取りたいです。

Raspberry PiのGPIOピンを各センサーから読み取るように割り当てるだけで、基本的に1つのセンサーの同じ構成を複製できますか、それともすべてのセンサーがプラグインされてデータを並行して送信するようなマルチプレクサが必要ですか?ラズベリーパイに?


1
データシートから:「各DS18B20には一意の64ビットシリアルコードがあり、これにより、複数のDS18B20を同じ1-Wireバス上で機能させることができます。」データシートを読んでみてください(すべてを理解していなくても心配しないでください)。
ガーベン

回答:


18

センサーがDS18B20であり、それが1線式回路であり、1線式が同じバスで複数のアドレス指定を実行できるプロトコルであり、1線式温度カーネルモジュールが最大10個の温度センサーを読み取れることを考えると同じバスで。(ドライバーのソースコードの 49行目を確認してください)。

10個のセンサーを同じ3ピン(3v3、GND、およびコネクターのピン番号4である1線IOピン(これはドライバーにハードコーディングされています!)に接続するだけで、/からの出力を読み取ります) sys / bus / w1 / devices / 28 * / w1_slaveここで、28 *は個々の一意の1ワイヤアドレスですadafruitの優れたチュートリアルを確認してください。4K7 抵抗器がデータピンをプルアップすることを忘れないでください(番号4-1つだけ!) 、Piの内部プルアップにより約50Kが得られるため、センサーには大きすぎるため、この追加コンポーネントが必要になります。

寄生電力を使用しようとしていないことを確認してください。すべてのデバイスの3つのピンを接続すれば、問題ありません。


ちょっと、私は現在、いくつかのDS18B20で10センサーの温度ロガーを作成する設計プロセスにいます。寄生電力ビットを除いて、上記で言っていることはほとんどYou should just make sure you are not trying to use parasitic power.あります。これはどういう意味ですか?PiのGPIOのpin1からの3.3Vの代わりに外部電源を使用する必要がありますか?または、3V3ではなくGND + Dataのみを使用する場合、寄生電力はありますか?-ユーザー名へのホットリンクを拒否しました:-(
Jim

2
@Jim寄生電力は、DS18B20の機能であり、これにより、VCCではなく、GNDおよびIOピンのみをバスに接続します。マルコポーリは、DS18B20sからPiに3本のワイヤをすべて接続する代わりに、このモードで実行すべきではないと言っています。外部電源は必要ありません。
NoChecksum

コメントに関して、this is hardcoded in the driver温度センサーを別のGPIOピン(または複数のGPIOピン)に接続しても機能しないということですか?
-Bprodz

4

参考のために、ここに1-wire GPIOをbitbangし、最初のセンサーの温度測定値を返すPythonの短いスニペットがあります。接続されたすべてのセンサーの温度をリストまたは同様のものとして返すように変更するのは、十分に簡単なはずです。

import subprocess, time

def read_onewire_temp():
    '''
    Read in the output of /sys/bus/w1/devices/28-*/w1_slave
    If the CRC check is bad, wait and try again (up to 20 times).
    Return the temp as a float, or None if reading failed.
    '''
    crc_ok = False
    tries = 0
    temp = None
    while not crc_ok and tries < 20:
        # Bitbang the 1-wire interface.
        s = subprocess.check_output('cat /sys/bus/w1/devices/28-*/w1_slave', shell=True).strip()
        lines = s.split('\n')
        line0 = lines[0].split()
        if line0[-1] == 'YES':  # CRC check was good.
            crc_ok = True
            line1 = lines[1].split()
            temp = float(line1[-1][2:])/1000
        # Sleep approx 20ms between attempts.
        time.sleep(0.02)
        tries += 1
    return temp

実行するにはインポートサブプロセスのインポート時間が必要です
ポールアンダーソン

2

1線式バスを介して話すのは苦痛です。1つのセンサーと話すのか100のセンサーと話すのかにかかわらず、タイミングについて考える必要があります。数年前にDS18B20用のコードをいくつか書きましたが、それはAssemblyにあります。使用する場合は、ここで:

;***************************************************************
;Title:     Temperature Logger
;Description:   Polls temperature every two seconds and returns a value
;       in degC as well as the slope (rising, falling, steady)
;***************************************************************
Screen  EQU $F684
;System Equates
PortA   EQU $0000
DDRA    EQU $0002
;Program Equates
TxPin   EQU %00000001
RxPin   EQU %00000010
IntPin  EQU %10000000
;Commands
SkipROM EQU $CC
Convert EQU $44
ReadPad EQU $BE
;Constants
ASCII_0 EQU 48
Poll_D  EQU 2000
;Macros
TxOn    macro    ; Send the 1-wire line Low
    MOVB    #TxPin,DDRA
    MOVB    #$00,PortA
    endm

TxOff   macro    ;Releases the 1-wire line letting it return to High.
    MOVB    #$00,DDRA
    endm


;-------------------------------------
;Main 
;-------------------------------------
    ORG $0D00

        ; Clear registers and initialise ports
Start:  MOVB    #$00, DDRA
Main:   LDD     #$00
        JSR     Init
        LDAA    #SkipROM
        JSR     Write
        LDAA    #Convert
        JSR     Write
        JSR     Wait
        JSR     Init
        LDAA    #SkipROM
        JSR     Write
        LDAA    #ReadPad
        JSR     Write
        JSR     Read    ; read first 8 bits
        TFR     A, B
        JSR     Read    ; read second 8 bits
        ; Convert bytes to BCD
        LSRB
        LSRB
        LSRB
        LSRB
        STD     TempNew
        PSHA
        PSHB
        LDAB    #6
        MUL
        TBA
        PULB
        ABA
        CLRB
Conv_Lp:SUBA    #10
        BMI     Conv_Dn
        INCB
        BRA     Conv_Lp
Conv_Dn:ADDA    #10
        TFR     A, Y
        PULA
        ABA
        TFR     Y, B
        ; convert BCD bytes to ASCII and store in temp register
        LDX     #Temp
        ADDA    #ASCII_0
        STAA    0, X
        INX
        ADDB    #ASCII_0
        STAB    0, X
        LDX     #OutUp  ; print 'The current temp is '
        JSR     Echo
        LDX     #Temp   ; print ASCII bytes
        JSR     Echo
        ; compare stored temp with previously stored and print 'rising', 'falling' or 'steady'
        LDD     TempNew
        SUBD    TempOld
        BGT     Rising
        BEQ     Same
        LDX     #Fall
        BRA     EchDir
Rising: LDX     #Rise
        BRA     EchDir
Same:   LDX     #Steady
EchDir: JSR     Echo
        ; wait 2 seconds
        LDX     #Poll_D
Bla_Lp: JSR     Del1ms
        DBNE    X, Bla_Lp
        ; set new temp as old temp and loop
        LDD     TempNew
        STD     TempOld
        JMP     Main
        SWI


;-------------------------------------
;Subroutines
;-------------------------------------
Init:   TxOn        ; turn pin on
        uDelay  500 ; for 480us
        TxOff       ; turn pin off
        uDelay  70  ; wait 100us before reading presence pulse
        JSR Wait
        RTS
Wait:   LDX #120
Wait_Lp:JSR Del1ms
        DBNE    X, Wait_Lp
        RTS

Write:  PSHX
        PSHA
        LDX     #8  ; 8 bits in a byte
Wr_Loop:BITA    #%00000001
        BNE     Wr_S1   ; bit is set, send a 1
        BEQ     Wr_S0   ; bit is clear, send a 0
Wr_Cont:LSRA    ; shift input byte
        uDelay  100
        DBNE    X, Wr_Loop  ; shifted < 8 times? loop else end
        BRA     Wr_End
Wr_S1:  TxOn    ; on for 6, off for 64
        uDelay  6
        TxOff
        uDelay  64
        BRA     Wr_Cont
Wr_S0:  TxOn    ; on for 60, off for 10
        uDelay  60
        TxOff
        uDelay  10
        BRA     Wr_Cont
Wr_End: PULA
        PULX
        RTS

Read:   PSHB
        LDAB    #%00000001
        CLRA
Rd_Loop:TxOn    ; on for 6, off for 10
        uDelay  6
        TxOff
        uDelay  10
        BRSET   PortA, #RxPin, Rd_Sub1  ; high? add current bit to output byte
Rd_Cont:uDelay  155 ; delay and shift.. 0? shifted 8 times, end
        LSLB
        BNE     Rd_Loop
        BRA     Rd_End
Rd_Sub1:ABA 
        BRA     Rd_Cont
Rd_End: PULB
        RTS

uDelay  macro    ;Delay a mutliple of 1us (works exactly for elays > 1us)
        PSHD
        LDD   #\1
        SUBD  #1
        LSLD
\@LOOP  NOP
        DBNE  D, \@LOOP
        PULD
        endm

;-------------------------------------
;General Functions
;-------------------------------------
; delays
Del1us: RTS

Del1ms: PSHA
        LDAA    #252
Del_ms: JSR     Del1us
        JSR     Del1us
        JSR     Del1us
        CMPA    $0000
        CMPA    $0000
        NOP
        DECA
        BNE     Del_ms
        CMPA    $0000
        NOP
        PULA
        RTS

; display text from address of X to \0
Echo:   PSHY
        PSHB
        LDAB    0, X
Ech_Lp: LDY Screen
        JSR 0, Y
        INX
        LDAB    0, X
        CMPB    #0
        BNE Ech_Lp
        PULB
        PULY
        RTS

Interrupt:
        SWI
        RTI

;-------------------------------------
;Variables
;-------------------------------------
    ORG   $0800
OutUp:  DC.B    'The current temperature is ', 0
Rise:   DC.B    ' and Rising', $0D, $0A, 0
Steady: DC.B    ' and Steady', $0D, $0A, 0
Fall:   DC.B    ' and Falling', $0D, $0A, 0
Temp:   DS  2
    DC.B    0
TempOld:DS  2
TempNew:DS  2

3
Raspberry piには、すでに1線式と1線式温度センサー専用のカーネルモジュール(de DS18B20を含む)が既にあります。モジュールをロードするだけで、温度がファイルから読み込まれ、ファイル読み込みコマンドが実行されます。ready-modulesを使用する場合、プロトコルを手動で実装する必要はありません。
マルコ・ポーリ

2

興味がある場合は、DS18B20温度センサー(上記のようにPiで同じGPIOピンを使用して必要な数だけチェーンすることができます)とRaspberry Piおよびそれを送信するいくつかのPyhtonコードを使用するために書いたガイドがありますWebサイト上のグラフと図に温度を集約して表示するRESTfulサービス。指定されたGitHubアカウントで公開されているすべてのコード。 http://macgyverdev.blogspot.se/2014/01/weather-station-using-raspberry-pi.html


1

どのような温度センサーを使用していますか?DS18B20のようなものがある場合、18446744073709551615のセンサーがあればそれをチェーンできます。


センサーは確かにDS18B20タイプですが、チェーンの意味を詳しく説明してください。可能であれば、そのような手法の実装のソースを示してください。センサー入力がチェーンされている場合、センサー入力をどのように区別しますか?グラフ温度センサー1、温度センサー2 ...温度センサーnの出力を取得する必要があります。
jc303

2
@JadCooperの各ds18b20センサーには16ビットのシリアル番号があります。nを使用してセンサーをアドレス指定すると、そのセンサーのみからデータが返されます。(このチュートリアル)[ learn.adafruit.com / ...をpiで使用する方法を参照してください
-TheDoctor

0

答える:

5-6温度センサーをRaspberry Piに多重化するにはどうすればよいですか?

piに接続するための複数のバスを持つ追加モジュールがあります。
このビデオでは、速度を比較しています:https : //www.youtube.com/watch?v=YbWidNBycls 彼は最終的に再コンパイルされたカーネルを使用して、複数のセンサーと通信する複数のGPIOを実現しています。彼は、彼がそれをどうやって手に入れたかについての結果を投稿していません。ただし、ピンを1つだけ使用する代わりに、多重化することもできます。

更新。彼は今投稿しています。彼は81個のセンサーを9個の個別のGPIOに接続し、3秒以内にすべての温度を取得できました:https : //www.youtube.com/watch?v=JW9wzbp35w8


0

複数のセンサーを読み取る理想的な方法は、I2Cセンサーを使用することです。

これは、複数のセンサーを連結するかアナログセンサーを使用できる唯一の方法ですが、多くのアナログピンを使用しますが、i2cは2行のみを使用します。Pi2 / 3を使用していると言えば、数秒以内にすべてのi2cデバイスをPiに接続し、ハードウェアが正しいことを確認できるように、I2Cポートを備えたraspberry Pi帽子を入手することをお勧めします。

これで、I2Cアダプターを備えたPiがセンサー部分に移動しました。TI、AD、NXP、フリースケール、および他の多くの企業がI2Cで温度センサーを製造していますが、2つ以上のセンサーを接続したいので、2つのオプションがあります。

  1. 異なるI2Cアドレスを持つ6つの異なるI2Cセンサーを取得します。同じアドレスを持つ2つのセンサーがある場合は動作しません。

  2. センサーをアドレスラインで取得し、アドレスを変更するだけで、アドレスの競合なしでPiに接続できます。このTMP 100センサーを使用することをお勧めします。フローティングアドレスラインをサポートする2つのアドレスラインがあるため、1つのi2cラインで6つのセンサーを接続できます。

同じセンサーを使用する利点は、6つのデータシートを読んでコードを書く必要がないことです。1つのデータシートを調べて、簡単にコードを書く必要があります。すべてのセンサーが同じである場合、比較するより良い結果が得られます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.