Несколько датчиков температуры с Raspberry Pi

19

Я видел множество примеров использования одного датчика температуры с Raspberry Pi, однако, как я могу мультиплексировать 5-6 датчиков температуры с Raspberry Pi? Я хочу читать температуру из нескольких источников одновременно.

Могу ли я просто назначить выводы GPIO на Raspberry Pi для чтения с каждого датчика, по сути, реплицируя одну и ту же конфигурацию для одного датчика, или мне нужен какой-нибудь мультиплексор, к которому все датчики будут подключаться по очереди, который будет передавать данные параллельно к малиновому пи?

jc303
источник
1
Из таблицы данных : «Каждый DS18B20 имеет уникальный 64-битный последовательный код, который позволяет нескольким DS18B20 работать на одной шине 1-Wire.». Попробуйте прочитать таблицу данных (не волнуйтесь, если вы не все понимаете).
Гербен

Ответы:

18

Учитывая, что ваш датчик является DS18B20, и это 1-проводная схема, а 1-проводная - это протокол, который может выполнять множественные адресации на одной и той же шине, и что 1-проводный модуль ядра температуры может считывать до 10 температурных датчиков. на том же автобусе. (проверьте строку 49 исходного кода драйвера ).

Если вы просто подключите 10 ваших датчиков к одним и тем же 3 контактам (3v3, GND и 1-проводному контакту IO - это номер 4 на разъеме (это жестко запрограммировано в драйвере!), И вы будете читать их выходы из / sys / bus / w1 / devices / 28 * / w1_slave, где 28 * - это индивидуальный уникальный однопроводный адрес. Проверьте превосходное учебное пособие adafruit . Не забудьте, что резистор 4K7 вытягивает контакт данных (номер 4 - ТОЛЬКО ОДИН!) Так как внутренний подтягивающий сигнал Pi дает примерно 50 КБ, а это слишком много для датчика, вам понадобится этот дополнительный компонент.

Вы должны просто убедиться, что вы не пытаетесь использовать паразитическую силу. Если вы подключите 3 контакта всех устройств, все будет в порядке.

Марко Поли
источник
Привет, я в настоящее время нахожусь в процессе создания регистратора температуры с 10 датчиками для некоторых DS18B20, у меня есть в значительной степени то, что вы говорите выше, за исключением бита паразитной мощности: You should just make sure you are not trying to use parasitic power.что вы подразумеваете под этим? Нужно ли использовать внешний источник питания вместо 3,3 В от контакта 1 на GPIO Pi? Или это паразитная сила, если я использую только GND + Data, а не 3V3? - он отказался от горячей ссылки на ваше имя пользователя :-(
Джим
2
@Jim Паразитное питание - это функция DS18B20, благодаря которой к шине подключаются только выводы GND и IO, а не VCC. Марко Поли говорит, что вы не должны запускать его в этом режиме, вместо этого подключите все 3 провода от DS18B20 к Pi. Вам не понадобится внешний источник питания.
NoChecksum
Привет, что касается вашего комментария, this is hardcoded in the driverозначает ли это, что подключение датчиков температуры к другому выводу GPIO (или нескольким выводам GPIO) не будет работать?
Bprodz
4

Для справки приведем небольшой фрагмент кода Python, который побьет 1-проводной GPIO и вернет показания температуры для первого датчика. Это должно быть достаточно просто изменить, чтобы вернуть временные значения для всех подключенных датчиков в виде списка или чего-то подобного.

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
ropable
источник
для запуска нужно время импорта подпроцесса импорта
Пол Андерсон
2

Разговор по однопроводной шине может быть болезненным. Говорите ли вы с 1 датчиком или 100, вам нужно подумать о времени. Я написал код для DS18B20 несколько лет назад, но он в сборке. Если это пригодится, здесь:

;***************************************************************
;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). Просто загрузите модули, и температура будет считана из файла, с помощью команды чтения файла в формате reagular. Вам не нужно вручную реализовывать протокол, если вы решите использовать готовые модули.
Марко Поли
2

Если интересно, вот руководство, которое я написал для использования датчика температуры DS18B20 (который, как указано выше, может быть связан с любым количеством выводов GPIO на Pi) с Raspberry Pi и некоторым кодом Pyhton, который отправляет его на 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-битный серийный номер. Когда вы обращаетесь к нему с датчиком, он возвращает данные только от этого датчика. Смотрите (этот учебник) [ learn.adafruit.com/… для использования их на пи
TheDoctor
0

Отвечать:

Как я могу мультиплексировать 5-6 датчиков температуры на Raspberry Pi?

Вы можете получить дополнительные модули, которые имеют несколько шин для подключения к пи.
Это видео сравнивает их скорости: https://www.youtube.com/watch?v=YbWidNBycls. В конечном итоге он использует перекомпилированное ядро ​​для достижения множественного взаимодействия GPIO с несколькими датчиками. Он не опубликовал свои результаты о том, как он получил это. Но можно мультиплексировать его, вместо того чтобы использовать только один контакт.

Обновить. Он опубликовал сейчас. Он подключил 81 датчик к 9 отдельным GPIO и смог получить все температуры менее чем за 3 секунды: https://www.youtube.com/watch?v=JW9wzbp35w8

raspi-ниндзя
источник
0

идеальным способом считывания нескольких датчиков является использование датчиков I2C.

это единственный способ объединить несколько датчиков в цепочку или использовать аналоговые датчики, но они будут использовать много аналоговых выводов, а i2c будет использовать только 2 линии. Допустим, вы используете Pi2 / 3, а затем я предложу приобрести шляпу Pi Raspberry с портом I2C, чтобы вы могли соединить все ваши устройства i2c с Pi в течение нескольких секунд, и она убедится, что ваше оборудование работает правильно.

Теперь у вас есть Pi с I2C-адтертером, позволяющим перемещаться по сенсорной части. TI, AD, NXP, Freescale и многие другие компании производят датчик температуры с I2C, но вы хотите подключить более одного датчика, чтобы было два варианта.

  1. получите 6 разных датчиков I2C с разными адресами I2C, если у вас два датчика с одинаковым адресом, это не сработает.

  2. Вы можете получить датчики с адресной линией и просто изменить адрес, и вы можете подключить их к Pi без какого-либо конфликта адресов. Я рекомендую использовать этот датчик TMP 100. Я предпочитаю этот, потому что он имеет 2 адресные линии с поддержкой плавающей адресной линии, так что вы можете подключить 6 датчиков к одной линии i2c.

Преимущество использования одних и тех же датчиков состоит в том, что вам не нужно читать 6 таблиц данных, чтобы написать свой код, вам нужно изучить одну таблицу данных и написать код по-своему. если все ваши датчики одинаковы, то у вас будет лучший результат для сравнения.

брюс
источник