เซ็นเซอร์อุณหภูมิหลายตัวพร้อม Raspberry Pi


19

ฉันได้เห็นตัวอย่างมากมายสำหรับการใช้เซ็นเซอร์อุณหภูมิหนึ่งเดียวกับ Raspberry Pi อย่างไรก็ตามฉันจะคูณเซ็นเซอร์อุณหภูมิ 5-6 ให้กับ Raspberry Pi ได้อย่างไร ฉันต้องการอ่านอุณหภูมิจากหลาย ๆ แหล่งพร้อมกัน

ฉันสามารถกำหนดพิน GPIO บน Raspberry Pi ให้อ่านจากเซ็นเซอร์แต่ละตัวได้โดยการทำซ้ำการกำหนดค่าเดียวกันสำหรับเซ็นเซอร์ตัวเดียวหรือฉันต้องการมัลติเพล็กเซอร์บางอย่างที่เซ็นเซอร์ทั้งหมดจะเสียบเข้าไปแล้วส่งข้อมูลแบบขนาน กับราสเบอร์รี่ Pi?


1
จากแผ่นข้อมูล : "DS18B20 แต่ละตัวมีรหัสซีเรียล 64 บิตที่ไม่ซ้ำกันซึ่งช่วยให้ DS18B20 หลายตัวทำงานบนบัส 1-Wire เดียวกัน" ลองอ่านแผ่นข้อมูล (ไม่ต้องกังวลหากคุณไม่เข้าใจทุกอย่าง)
Gerben

คำตอบ:


18

ระบุว่าเซ็นเซอร์ของคุณเป็น DS18B20 และเป็นวงจร 1 สายและ 1 สายเป็นโปรโตคอลที่สามารถทำงานหลายอย่างบนบัสเดียวกันนั้นและโมดูลเคอร์เนลอุณหภูมิ 1 สายสามารถอ่านเซ็นเซอร์อุณหภูมิได้มากถึง 10 ตัว บนรถบัสเดียวกัน (ตรวจสอบบรรทัดที่ 49 ของซอร์สโค้ดไดรเวอร์ )

หากคุณเพียงแค่เชื่อมต่อเซ็นเซอร์ 10 ตัวของคุณเข้ากับ 3 พินเดียวกัน (3v3, GND และ 1-wire IO pin - ซึ่งเป็นพินหมายเลข 4 บนขั้วต่อ (นี่คือฮาร์ดโค้ดในไดรเวอร์!) และคุณจะอ่านผลลัพธ์จาก / sys / bus / w1 / devices / 28 * / w1_slave โดยที่ 28 * เป็นที่อยู่เฉพาะ 1 สายของแต่ละบุคคลตรวจสอบการสอนที่ยอดเยี่ยมของ adafruit อย่าลืมตัวต้านทาน 4K7 ดึงตัวต้านทานข้อมูลขึ้นมา (หมายเลข 4 - หนึ่งเดียว!) เนื่องจาก pull up ภายในของ Pi ให้คุณประมาณ 50K และนั่นมากเกินไปสำหรับเซ็นเซอร์ดังนั้นคุณจะต้องการส่วนประกอบพิเศษนี้

คุณควรตรวจสอบให้แน่ใจว่าคุณไม่ได้พยายามใช้พลังพยาธิ หากคุณเชื่อมต่อ 3 ขาของอุปกรณ์ทั้งหมดคุณควรจะปรับ


สวัสดีตอนนี้ฉันอยู่ในขั้นตอนการออกแบบเครื่องบันทึกอุณหภูมิ 10 เซ็นเซอร์ด้วย DS18B20 บางอันฉันก็มีสิ่งที่คุณพูดข้างต้นยกเว้นบิตกาฝาก: You should just make sure you are not trying to use parasitic power.คุณหมายถึงอะไร ฉันต้องใช้แหล่งจ่ายไฟภายนอกแทน 3.3V จาก pin1 บน GPIO ของ Pi หรือไม่ หรือเป็นกาฝากหากฉันใช้ GND + Data ไม่ใช่ 3V3 เท่านั้น - มันปฏิเสธที่จะลิงค์ไปยังชื่อผู้ใช้ของคุณ :-(
Jim

2
@Jim Parasitic power เป็นคุณสมบัติของ DS18B20 โดยที่คุณเชื่อมต่อเฉพาะ GND และ IO pin กับบัสไม่ใช่ VCC Marco Poli บอกว่าคุณไม่ควรใช้มันในโหมดนี้แทนที่จะเชื่อมต่อสายทั้ง 3 สายจาก DS18B20 กับ Pi คุณไม่จำเป็นต้องใช้แหล่งจ่ายไฟภายนอก
NoChecksum

สวัสดีเกี่ยวกับความคิดเห็นของคุณthis is hardcoded in the driverนั่นหมายความว่าการเชื่อมต่อเซ็นเซอร์วัดอุณหภูมิกับ GPIO อื่น (หรือ GPIO หลายขา) จะไม่ทำงานหรือไม่
Bprodz

4

สำหรับการอ้างอิงนี่เป็นตัวอย่างสั้น ๆ ของ Python เป็น bitbang ของ GPIO 1 สายและส่งคืนค่าอุณหภูมิอ่านสำหรับเซ็นเซอร์ตัวแรก ควรตรงไปตรงมาพอที่จะปรับเปลี่ยนเพื่อส่งกลับ temps สำหรับเซ็นเซอร์ที่เชื่อมต่อทั้งหมดเป็นรายการหรือสิ่งที่คล้ายกัน

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

ต้องใช้เวลาในการนำเข้ากระบวนการย่อยเพื่อนำเข้า
Paul Anderson

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) เพียงแค่โหลดโมดูลและอุณหภูมิจะถูกอ่านจากไฟล์ที่มีคำสั่งอ่านไฟล์ reagular คุณไม่จำเป็นต้องใช้โปรโตคอลด้วยตนเองหากคุณเลือกที่จะใช้โมดูลสำเร็จรูป
Marco Poli

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 ได้อย่างไร

มีการเพิ่มโมดูลที่คุณจะได้รับที่มีรถบัสหลายคันเพื่อเชื่อมต่อกับ pi
วิดีโอนี้เปรียบเทียบความเร็วของพวกเขา: https://www.youtube.com/watch?v=YbWidNBycls เขาลงเอยด้วยการใช้เคอร์เนลที่คอมไพล์ใหม่เพื่อให้ได้ GPIO หลายการสื่อสารกับเซ็นเซอร์หลายตัว เขาไม่ได้โพสต์ผลลัพธ์ว่าทำอย่างไร แต่มันเป็นไปได้ที่จะมัลติเพล็กซ์แทนที่จะใช้เพียงขาเดียว

ปรับปรุง เขาโพสต์ตอนนี้ เขาเชื่อมต่อเซ็นเซอร์ 81 ตัวกับ GPIO แยก 9 ตัวและสามารถรับอุณหภูมิทั้งหมดได้ภายใน 3 วินาที: https://www.youtube.com/watch?v=JW9wzbp35w8


0

วิธีที่เหมาะในการอ่านเซ็นเซอร์หลายตัวคือใช้เซ็นเซอร์ I2C

นี่เป็นวิธีเดียวที่คุณสามารถรวมเซ็นเซอร์หลายตัวเข้าด้วยกันหรือคุณสามารถใช้เซ็นเซอร์อะนาล็อก แต่พวกเขาจะใช้หมุดอะนาล็อกจำนวนมาก แต่ i2c จะใช้เพียง 2 บรรทัด สมมติว่าคุณกำลังใช้ Pi2 / 3 จากนั้นฉันจะแนะนำให้ใช้หมวกราสเบอร์รี่ Piซึ่งมีพอร์ต I2C เพื่อให้คุณสามารถเชื่อมต่ออุปกรณ์ i2c ทั้งหมดของคุณกับ Pi ภายในไม่กี่วินาทีและจะทำให้แน่ใจว่าฮาร์ดแวร์ของคุณถูกต้อง

ตอนนี้คุณมี Pi ที่มีตัวแปลง I2C ให้ย้ายไปยังส่วนเซ็นเซอร์ TI, AD, NXP, freescale และ บริษัท อื่น ๆ จำนวนมากสร้างเซ็นเซอร์อุณหภูมิด้วย I2C แต่คุณต้องการเชื่อมต่อเซ็นเซอร์มากกว่าหนึ่งตัวเพื่อให้มีสองตัวเลือก

  1. รับเซ็นเซอร์ I2C ที่แตกต่างกัน 6 แบบด้วยที่อยู่ I2C ที่แตกต่างกันหากคุณมีเซ็นเซอร์สองตัวที่มีที่อยู่เดียวกันมันจะไม่ทำงาน

  2. คุณสามารถรับเซ็นเซอร์ที่มีบรรทัดที่อยู่และเพียงแค่เปลี่ยนที่อยู่และคุณสามารถเชื่อมต่อพวกเขาด้วย Pi โดยไม่ขัดแย้งกับที่อยู่ใด ๆ ฉันจะแนะนำให้ใช้เซ็นเซอร์ TMP 100นี้ฉันชอบอันนี้เพราะมันมี 2 บรรทัดที่อยู่ที่มีการสนับสนุนบรรทัดที่อยู่ลอยเพื่อให้คุณสามารถเซ็นเซอร์ hookup 6 กับ i2c หนึ่งบรรทัด

มีข้อดีของการใช้เซ็นเซอร์เดียวกันคือคุณไม่จำเป็นต้องอ่านแผ่นข้อมูล 6 แผ่นเพื่อเขียนรหัสของคุณคุณจะต้องศึกษาแผ่นข้อมูลหนึ่งแผ่นและเขียนรหัสอย่างง่าย หากเซ็นเซอร์ทั้งหมดของคุณเหมือนกันคุณจะได้ผลลัพธ์ที่ดีกว่าเมื่อเปรียบเทียบ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.