Capteurs de température multiples avec un Raspberry Pi

19

J'ai vu de nombreux exemples d'utilisation d'un capteur de température avec le Raspberry Pi, cependant, comment puis-je multiplexer des capteurs de température 5-6 sur un Raspberry Pi? Je veux lire la température de plusieurs sources simultanément.

Puis-je simplement assigner les broches GPIO du Raspberry Pi pour lire à partir de chaque capteur, reproduisant essentiellement la même configuration pour un capteur, ou ai-je besoin d'une sorte de multiplexeur auquel tous les capteurs se connecteraient à leur tour qui enverrait des données en parallèle au Raspberry Pi?

jc303
la source
1
De la fiche technique : "Chaque DS18B20 possède un code série 64 bits unique, qui permet à plusieurs DS18B20 de fonctionner sur le même bus 1-Wire.". Essayez de lire la fiche technique (ne vous inquiétez pas si vous ne comprenez pas tout).
Gerben

Réponses:

18

Étant donné que votre capteur est un DS18B20 et qu'il s'agit d'un circuit à 1 fil et que 1 fil est un protocole qui peut effectuer plusieurs adressages sur ce même bus et que le module de noyau de température à 1 fil peut lire jusqu'à 10 capteurs de température sur le même bus. (vérifiez la ligne 49 du code source du pilote ).

Si vous connectez simplement 10 de vos capteurs aux mêmes 3 broches (3v3, GND et la broche IO à 1 fil - qui est la broche numéro 4 sur le connecteur (elle est codée en dur dans le pilote!)) Et vous lirez leurs sorties à partir de / sys / bus / w1 / devices / 28 * / w1_slave où le 28 * est l'adresse individuelle unique à 1 fil. Consultez l' excellent tutoriel d' adafruit . N'oubliez pas la résistance 4K7 tirant la broche de données (numéro 4 - UNE SEULE!) , car le pull up interne du Pi vous donne environ 50K, et c'est trop pour le capteur, vous aurez donc besoin de ce composant supplémentaire.

Vous devez simplement vous assurer que vous n'essayez pas d'utiliser la puissance parasite. Si vous connectez les 3 broches de tous les appareils, ça devrait aller.

Marco Poli
la source
Hé là, je suis actuellement en train de concevoir un enregistreur de température à 10 capteurs avec certains DS18B20, j'ai à peu près ce que vous dites ci-dessus, sauf pour le bit de puissance parasite: You should just make sure you are not trying to use parasitic power.que voulez-vous dire par là? Dois-je utiliser une alimentation externe au lieu du 3,3 V de la broche 1 sur le GPIO du Pi? Ou est-ce une puissance parasite si j'utilise uniquement des données GND + et non le 3V3? - il a refusé de créer un lien direct vers votre nom d'utilisateur :-(
Jim
2
@Jim Alimentation parasite est une caractéristique du DS18B20 par laquelle vous connectez uniquement des broches GND et IO au bus, pas VCC. Marco Poli dit que vous ne devriez pas l'exécuter dans ce mode, mais plutôt connecter les 3 fils du DS18B20 au Pi. Vous n'aurez pas besoin d'une alimentation externe.
NoChecksum
Bonjour à propos de votre commentaire, this is hardcoded in the drivercela signifie-t-il que la connexion de capteurs de température à une broche GPIO différente (ou à plusieurs broches GPIO) ne fonctionnera pas?
Bprodz
4

Pour référence, voici un court extrait de Python pour bitbang le GPIO 1 fil et renvoyer la lecture de température pour le premier capteur. Il devrait être assez simple à modifier pour renvoyer les températures de tous les capteurs connectés sous forme de liste ou quelque chose de similaire.

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
cordée
la source
besoin d'importer le temps d'importation du sous-processus pour s'exécuter
Paul Anderson
2

Parler sur un bus à 1 fil peut être douloureux. Que vous parliez à 1 capteur ou à 100, vous devrez penser au timing. J'ai écrit du code pour le DS18B20 il y a quelques années, mais il est dans Assembly. Si c'est utile, ici:

;***************************************************************
;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
la source
3
Le Raspberry pi possède déjà un module de noyau pour 1 fil et un autre spécifiquement pour les capteurs de température à 1 fil (qui inclut de DS18B20). Il suffit de charger les modules et la température est lue à partir d'un fichier, avec une commande de lecture de fichier réactif. Vous n'avez pas besoin d'implémenter manuellement le protocole, si vous choisissez d'utiliser les modules prêts.
Marco Poli
2

Si vous êtes intéressé, voici un guide que j'ai écrit pour utiliser un capteur de température DS18B20 (qui, comme indiqué ci-dessus, peut être enchaîné avec autant que vous le souhaitez en utilisant la même broche GPIO sur le Pi) avec un Raspberry Pi et du code Pyhton qui le publie sur un Service RESTful qui agrège et affiche les températures dans des graphiques et des diagrammes sur un site Web. Tout code public sur le compte GitHub spécifié. http://macgyverdev.blogspot.se/2014/01/weather-station-using-raspberry-pi.html

Johan Norén
la source
1

Quel type de capteur de température utilisez-vous? Si vous avez quelque chose comme un DS18B20, vous pouvez chaîner jusqu'à 18446744073709551615 capteurs, si vous en aviez autant.

Le docteur
la source
Le capteur est en effet de type DS18B20, cependant pouvez-vous préciser ce que l'on entend par chaînage, et si possible, indiquer une source pour la mise en œuvre d'une telle technique. Comment différencier les entrées de capteur si elles étaient enchaînées? Je dois acquérir et la sortie du graphique capteur de température 1, capteur de température 2 .... capteur de température n.
jc303
2
@JadCooper chaque capteur ds18b20 contient un numéro de série 16 bits. Lorsque vous adressez un capteur à cela, il renvoie des données provenant uniquement de ce capteur. Voir (ce tutoriel) [ learn.adafruit.com/… pour les utiliser sur le pi
TheDoctor
0

Répondre:

comment multiplexer des capteurs de température 5-6 sur un Raspberry Pi?

Il existe des modules supplémentaires que vous pouvez obtenir qui ont plusieurs bus pour se connecter au pi.
Cette vidéo compare leurs vitesses: https://www.youtube.com/watch?v=YbWidNBycls Il finit par utiliser un noyau recompilé pour réaliser plusieurs GPIO communiquant avec plusieurs capteurs. Il n'a pas publié ses résultats sur la façon dont il l'a obtenu. Mais il est possible de le multiplexer au lieu d'utiliser une seule broche.

Mise à jour. Il a posté maintenant. Il a connecté 81 capteurs à 9 GPIO distincts et a pu obtenir toutes les températures en moins de 3 secondes: https://www.youtube.com/watch?v=JW9wzbp35w8

raspi-ninja
la source
0

la façon idéale de lire plusieurs capteurs est d'utiliser des capteurs I2C.

c'est la seule façon de chaîner plusieurs capteurs ensemble ou d'utiliser des capteurs analogiques, mais ils prendront beaucoup de broches analogiques mais i2c n'utilisera que 2 lignes. disons que vous utilisez Pi2 / 3, alors je vous proposerai d'obtenir un chapeau Raspberry Pi qui a un port I2C afin que vous puissiez connecter tous vos appareils i2c avec Pi en quelques secondes et il s'assurera que votre matériel est correct.

vous avez maintenant le Pi avec un adaptateur I2C laissez bouger la partie capteur. TI, AD, NXP, freescale et beaucoup d'autres sociétés fabriquent des capteurs de température avec I2C mais vous voulez connecter plus d'un capteur, il y a donc deux options.

  1. obtenez 6 différents capteurs I2C différents avec différentes adresses I2C différentes, si vous avez deux capteurs avec la même adresse, cela ne fonctionnera pas.

  2. vous pouvez obtenir des capteurs avec une ligne d'adresse et simplement changer d'adresse et vous pouvez les connecter avec Pi sans aucun conflit d'adresse. je vais suggérer d'utiliser ce capteur TMP 100, je préfère celui-ci car il a 2 lignes d'adresse avec un support de ligne d'adresse flottante afin que vous puissiez brancher 6 capteurs avec une ligne i2c.

il y a un avantage à utiliser les mêmes capteurs, car vous n'avez pas à lire 6 fiches techniques pour écrire votre code, vous devrez étudier une fiche technique et écrire le code à sa manière. si tous vos capteurs sont identiques, vous aurez de meilleurs résultats à comparer.

Bruce
la source