Wiele czujników temperatury z Raspberry Pi

19

Widziałem wiele przykładów używania jednego czujnika temperatury z Raspberry Pi, jednak jak mogę multipleksować 5-6 czujników temperatury z Raspberry Pi? Chcę odczytać temperaturę z kilku źródeł jednocześnie.

Czy mogę po prostu przypisać styki GPIO na Raspberry Pi do odczytu z każdego czujnika, zasadniczo replikując tę ​​samą konfigurację dla jednego czujnika, czy też potrzebuję jakiegoś multipleksera, do którego podłączałyby się wszystkie czujniki, a następnie przesyłałoby dane równolegle do Raspberry Pi?

jc303
źródło
1
Z arkusza danych : „Każdy DS18B20 ma unikalny 64-bitowy kod szeregowy, który pozwala wielu DS18B20 działać na tej samej magistrali 1-Wire”. Spróbuj przeczytać arkusz danych (nie martw się, jeśli nie wszystko zrozumiesz).
Gerben,

Odpowiedzi:

18

Biorąc pod uwagę, że twoim czujnikiem jest DS18B20 i jest to obwód 1-przewodowy, a ten 1-drut jest protokołem, który może wykonywać wiele adresów na tej samej magistrali i że moduł 1-przewodowego jądra temperatury może odczytać aż 10 czujników temperatury w tym samym autobusie. (sprawdź wiersz 49 kodu źródłowego sterownika ).

Jeśli po prostu podłączysz 10 czujników do tych samych 3 pinów (3v3, GND i 1-żyłowy pin IO - który jest pinem 4 na złączu (jest to zakodowane w sterowniku!) I odczytasz ich wyjścia z / sys / bus / w1 / devices / 28 * / w1_slave gdzie 28 * to indywidualny unikalny adres 1-przewodowy. Sprawdź doskonały poradnik adafruita . Nie zapomnij o oporniku 4K7 wyciągającym pin danych (numer 4 - TYLKO JEDEN!) , ponieważ wewnętrzne podniesienie pi daje około 50 KB, a to za dużo dla czujnika, więc będziesz potrzebować tego dodatkowego komponentu.

Powinieneś tylko upewnić się, że nie próbujesz użyć pasożytniczej mocy. Jeśli podłączysz 3 piny wszystkich urządzeń, wszystko powinno być w porządku.

Marco Poli
źródło
Hej, jestem obecnie w trakcie projektowania 10-czujnikowego rejestratora temperatury z niektórymi DS18B20, mam prawie to, co mówisz powyżej, z wyjątkiem pasożytniczego bitu mocy: You should just make sure you are not trying to use parasitic power.Co przez to rozumiesz? Czy muszę korzystać z zewnętrznego źródła zasilania zamiast 3,3 V z pinu 1 w GPIO Pi? Czy może jest to pasożytnicza moc, jeśli używam tylko danych GND +, a nie 3V3? - odmówił linku do twojej nazwy użytkownika :-(
Jim
2
@Jim Pasożytnicze zasilanie to cecha DS18B20, dzięki której do magistrali podłączane są tylko piny GND i IO, a nie VCC. Marco Poli mówi, że nie należy go uruchamiać w tym trybie, zamiast podłączać wszystkie 3 przewody z DS18B20 do Pi. Nie będziesz potrzebować zewnętrznego zasilacza.
NoChecksum
Cześć, jeśli chodzi o Twój komentarz, this is hardcoded in the driverczy to oznacza, że ​​podłączenie czujników temperatury do innego pinu GPIO (lub wielu pinów GPIO) nie będzie działać?
Bprodz
4

Dla odniesienia, oto krótki fragment Pythona do bitbang 1-przewodowego GPIO i zwrócenia odczytu temperatury pierwszego czujnika. Powinno być wystarczająco proste, aby zmodyfikować, aby zwracać temperatury dla wszystkich podłączonych czujników jako listę lub coś podobnego.

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
zrywalny
źródło
potrzebuje czasu importu importu podprocesów, aby uruchomić
Paul Anderson
2

Rozmawianie przez 1-żyłowy autobus może być bolesne. Bez względu na to, czy rozmawiasz z 1 czujnikiem, czy z 100, musisz pomyśleć o czasie. Kilka lat temu napisałem kod do DS18B20, ale jest on w asemblerze. Jeśli ma to jakiekolwiek zastosowanie, tutaj:

;***************************************************************
;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
Dr P Bacon
źródło
3
Raspberry pi ma już moduł jądra dla 1-przewodowego i inny specjalnie dla 1-przewodowych czujników temperatury (w tym de DS18B20). Wystarczy załadować moduły, a temperatura zostanie odczytana z pliku za pomocą komendowego odczytu pliku. Nie musisz ręcznie implementować protokołu, jeśli zdecydujesz się na użycie gotowych modułów.
Marco Poli,
2

Jeśli jesteś zainteresowany, oto przewodnik, który napisałem o używaniu czujnika temperatury DS18B20 (który, jak wspomniano powyżej, może być połączony z dowolną liczbą pinów GPIO na Pi) z Raspberry Pi i kodem Pyhton, który umieszcza go na Usługa RESTful, która agreguje i wyświetla temperatury na wykresach i diagramach w witrynie internetowej. Cały kod publiczny na określonym koncie GitHub. http://macgyverdev.blogspot.se/2014/01/weather-station-using-raspberry-pi.html

Johan Norén
źródło
1

Jakiego rodzaju czujnika temperatury używasz? Jeśli masz coś w rodzaju DS18B20, możesz połączyć do 18446744073709551615 czujników, jeśli masz ich tyle.

Doktor
źródło
Czujnik rzeczywiście jest typu DS18B20, jednak czy możesz wyjaśnić, co należy rozumieć przez łańcuch, a jeśli to możliwe, wskaż źródło, w którym można wdrożyć taką technikę. Jak rozróżnić wejścia czujników, gdyby były powiązane? Muszę nabyć i wyjściowy wykres temperatury czujnik 1, czujnik temperatury 2 .... czujnik temperatury n.
jc303,
2
@JadCooper każdy czujnik ds18b20 ma 16-bitowy numer seryjny. Kiedy adresujesz czujnik, zwraca dane tylko z tego czujnika. Zobacz (ten samouczek) [ learn.adafruit.com/ ... jak używać ich na pi
TheDoctor
0

Odpowiedzieć:

jak mogę multipleksować 5-6 czujników temperatury z Raspberry Pi?

Istnieją dodatkowe moduły, które można uzyskać, które mają kilka magistrali do podłączenia do pi.
Ten film porównuje ich prędkości: https://www.youtube.com/watch?v=YbWidNBycls W końcu używa przekompilowanego jądra, aby osiągnąć wiele komunikacji GPIO z wieloma czujnikami. Nie opublikował swoich wyników na temat tego, jak je uzyskał. Ale można go multipleksować zamiast używać tylko jednego pinu.

Aktualizacja. Wysłał teraz. Podłączył 81 czujników do 9 osobnych GPIO i był w stanie uzyskać wszystkie temperatury w mniej niż 3 sekundy: https://www.youtube.com/watch?v=JW9wzbp35w8

raspi-ninja
źródło
0

idealnym sposobem na odczyt wielu czujników jest użycie czujników I2C.

jest to jedyny sposób, aby połączyć wiele czujników razem lub możesz użyć czujników analogowych, ale one zajmą wiele analogowych pinów, ale i2c użyje tylko 2 linii. Powiedzmy, że używasz Pi2 / 3, a następnie zasugeruję, aby uzyskać kapelusz Raspberry Pi, który ma port I2C, abyś mógł połączyć wszystkie urządzenia i2c z Pi w ciągu kilku sekund i upewni się, że twój sprzęt jest poprawny.

teraz masz Pi z adapterem I2C, który pozwala poruszać się po części czujnika. TI, AD, NXP, freescale i wiele innych firm produkuje czujnik temperatury z I2C, ale chcesz podłączyć więcej niż jeden czujnik, więc są dwie opcje.

  1. uzyskaj 6 różnych czujników I2C o różnych adresach I2C, jeśli masz dwa czujniki o tym samym adresie, to nie będzie działać.

  2. możesz uzyskać czujniki z linią adresową i po prostu zmienić adres, a także połączyć je za pomocą Pi bez konfliktu adresu. zasugeruję użycie tego czujnika TMP 100. Wolę ten, ponieważ ma on 2 linie adresowe z obsługą pływającej linii adresowej, dzięki czemu można podłączyć 6 czujników za pomocą jednej linii i2c.

zaletą korzystania z tych samych czujników jest to, że nie musisz czytać 6 arkusza danych, aby napisać kod, musisz przestudiować jeden arkusz danych i napisać kod w prosty sposób. jeśli wszystkie czujniki są takie same, będziesz mieć lepsze wyniki do porównania.

Bruce
źródło