Багаторазові датчики температури з Raspberry Pi


19

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

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


1
З таблиці : "Кожен DS18B20 має унікальний 64-розрядний серійний код, який дозволяє декільком DS18B20s функціонувати на одній шині 1-Wire." Спробуйте прочитати таблицю (не хвилюйтесь, якщо ви все не розумієте).
Гербен

Відповіді:


18

Зважаючи на те, що ваш датчик - це DS18B20, і це 1-провідний ланцюг, і що 1-провід є протоколом, який може здійснювати багатократну адресацію на тій же шині, і що 1-провідний модуль ядра температури може зчитувати цілих 10 датчиків температури. на тому ж автобусі. (контрольний рядок 49 вихідного коду драйвера ).

Якщо ви просто підключите 10 своїх датчиків до тих самих 3-контактних штифтів (3v3, GND та 1-провідний IO-контакт - який є контактом № 4 на роз'ємі (це жорстко закодовано у драйвері!)), І ви прочитаєте їхні висновки з / sys / bus / w1 / devices / 28 * / w1_slave, де 28 * - це індивідуальна унікальна 1-провідна адреса. Перевірте відмінний підручник з adafruit . Не забудьте резистор 4K7 підтягнути контактний контакт (номер 4 - ТІЛЬКИЙ!) , оскільки внутрішнє підтягування Pi дає приблизно 50 К, а це занадто багато для датчика, тому вам знадобиться цей додатковий компонент.

Вам слід просто переконатися, що ви не намагаєтесь використовувати паразитарну силу. Якщо ви підключите 3 штифта всіх пристроїв, вам слід буде добре.


Гей, я зараз перебуваю в процесі проектування 10-ти сенсорного реєстратора температури з деякими DS18B20, я майже все зрозумів, що ви говорите вище, окрім біта паразитичної потужності: You should just make sure you are not trying to use parasitic power.Що ви маєте на увазі під цим? Чи потрібно використовувати зовнішній блок живлення замість 3,3 В від pin1 на Pi GPIO? Або паразитна сила, якщо я використовую лише дані GND +, а не 3V3? - він відмовився від гарячого посилання на ваше ім’я користувача :-(
Джим

2
@Jim Parasitic power - особливість DS18B20, завдяки якій до шини ви підключаєте лише штифти GND та IO, а не VCC. Марко Полі каже, що не слід запускати його в цьому режимі, а замість цього підключати всі 3 дроти від DS18B20s до 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

потрібен час імпорту імпортного підпроцесу
Пол Андерсон

2

Розмова через 1-провідний автобус може бути болючим. Незалежно від того, чи говорите ви з 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-провідних датчиків температури (що включає DS18B20). Просто завантажте модулі, і температура зчитується з файлу, за допомогою прямої команди зчитування файлів. Вам не потрібно вручну реалізовувати протокол, якщо ви вирішите використовувати готові модулі.
Марко Полі

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/… про використання їх на pi
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


0

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

це єдиний спосіб з'єднати декілька датчиків разом, або ви можете використовувати аналогові датчики, але вони будуть мати багато аналогових штифтів, але i2c буде використовувати лише 2 лінії. Дозвольмо сказати, що ви використовуєте Pi2 / 3, тоді я запропоную придбати малиновий капелюшок Pi, який має порт I2C, щоб ви могли протягом декількох секунд підключити всі свої пристрої i2c з Pi, і це переконається, що обладнання є правильним.

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

  1. отримайте 6 різних датчиків I2C з різною різною адресою I2C, якщо у вас є два датчики з однаковою адресою, це не буде працювати.

  2. ви можете отримати датчики з адресним рядком і просто змінити адресу, і ви можете з'єднати їх з Pi без будь-якого конфлікту адреси. Я запропоную використовувати цей датчик TMP 100, я вважаю за краще цей, оскільки він має 2 адреси адреси з плаваючою підтримкою плаваючої адреси, так що ви можете з’єднати 6 датчиків з одним рядком i2c.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.