我已經看到了很多示例,其中將一個溫度傳感器與Raspberry Pi一起使用,但是如何將5-6個溫度傳感器復用到Raspberry Pi?我想同時從多個來源讀取溫度。
我可以簡單地分配Raspberry Pi上的GPIO引腳以從每個傳感器讀取,本質上是為一個傳感器複製相同的配置,還是我需要某種多路復用器來插入所有傳感器,然後插入可以將數據並行發送到Raspberry Pi?
我已經看到了很多示例,其中將一個溫度傳感器與Raspberry Pi一起使用,但是如何將5-6個溫度傳感器復用到Raspberry Pi?我想同時從多個來源讀取溫度。
我可以簡單地分配Raspberry Pi上的GPIO引腳以從每個傳感器讀取,本質上是為一個傳感器複製相同的配置,還是我需要某種多路復用器來插入所有傳感器,然後插入可以將數據並行發送到Raspberry Pi?
假設您的傳感器是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的內部上拉給您大約50K,這對於傳感器來說太大了,因此您將需要這個額外的組件。
您應該確保不使用寄生電源。如果連接所有設備的3個引腳,就可以了。
作為參考,這是一段簡短的Python代碼,用於對1-wire GPIO進行位連接並返回第一個傳感器的溫度讀數。修改起來應該很簡單,以列表或類似的形式返回所有連接的傳感器的溫度。
import子進程,timedef read_onewire_temp():'''讀取/ sys / bus / w1 / devices / 28-* / w1_slave如果CRC校驗錯誤,請等待並重試(最多20次)。以浮點數返回溫度;如果讀取失敗,則返回None。 '''crc_ok =錯誤嘗試= 0 temp =無則不是crc_ok並嘗試< 20:#Bitbang 1-wire接口。 s = subprocess.check_output('cat / sys / bus / w1 / devices / 28-* / w1_slave',shell = True).strip()lines = s.split('\ n')line0 = lines [0]。 split()如果line0 [-1] =='YES':#CRC檢查良好。 crc_ok =真實的line1 = lines [1] .split()temp = float(line1 [-1] [2:])/ 1000#兩次嘗試之間大約睡眠20毫秒。 time.sleep(0.02)嘗試+ = 1返回溫度
通過1線總線通話可能會很痛苦。無論您要與1個傳感器還是100個傳感器通信,都需要考慮時序。幾年前,我為DS18B20寫了一些代碼,但它是在彙編中。如果有什麼用,請在這裡:
; *********************************** ************************************;標題:溫度記錄器;描述:每兩秒鐘輪詢一次溫度並返回一個值; degC以及坡度(上升,下降,穩定); *********************************** ********************************屏幕EQU $ F684;系統EquatesPortA EQU $ 0000DDRA EQU $ 0002;程序ExatesTxPin EQU%00000001RxPin EQU%00000010IntPin EQU %10000000; CommandsSkipROM EQU $ CCConvert EQU $ 44ReadPad EQU $ BE; ConstantsASCII_0 EQU 48Poll_D EQU 2000; MacrosTxOn宏;發送1線線路低MOVB#TxPin,DDRA MOVB#$ 00,PortA endmTxOff宏;釋放1線線路使其返回高電平。 MOVB#$ 00,DDRA endm; -------------------------------------; Main; --- ---------------------------------- ORG $ 0D00;清除寄存器並初始化端口開始:MOVB#$ 00,DDRA主:LDD#$ 00 JSR初始化LDAA #SkipROM JSR寫入LDAA#轉換JSR寫入JSR等待JSR初始化LDAA #SkipROM JSR寫入LDAA #ReadPad JSR寫入JSR讀取;讀取前8位TFR A,B JSR讀;讀取第二個8位;將字節轉換為BCD LSRB LSRB LSRB LSRB STD TempNew PSHA PSHB LDAB#6 MUL TBA PULB ABA CLRBConv_Lp:SUBA#10 BMI Conv_Dn INCB BRA Conv_LpConv_Dn:ADDA#10 TFR A,Y PULA ABA TFR Y,B;將BCD字節轉換為ASCII並存儲在臨時寄存器LDX #Temp ADDA#ASCII_0 STAA 0,X INX
ADDB#ASCII_0 STAB 0,X LDX #OutUp;打印'當前溫度是'JSR Echo LDX #Temp;打印ASCII字節JSR Echo;比較存儲的溫度與先前存儲的溫度,並打印“上升”,“下降”或“穩定” LDD TempNew SUBD TempOld BGT上升BEQ同一LDX #Fall BRA EchDirRising:LDX #Rise BRA EchDirSame:LDX #SteadyEchDir:JSR Echo;等待2秒LDX #Poll_DBla_Lp:JSR Del1ms DBNE X,Bla_Lp;將新溫度設置為舊溫度並循環LDD TempNew STD TempOld JMP Main SWI; ---------------------------------- ---;子例程; ------------------------------------- Init:TxOn;打開uDelay 500的針腳;為480us TxOff;關掉uDelay 70;等待100us,然後再讀取存在脈衝JSR Wait RTSWait:LDX#120Wait_Lp:JSR Del1ms DBNE X,Wait_Lp RTSWrite:PSHX PSHA LDX#8;字節中的8位Wr_Loop:BITA#%00000001 BNE Wr_S1;位置1,發送1 BEQ Wr_S0;位清零,發送0Wr_Cont:LSRA;移位輸入字節uDelay 100 DBNE X,Wr_Loop;將<移了8次?循環結束BRA Wr_EndWr_S1:TxOn;開啟6,關閉64 uDelay 6 TxOff uDelay 64 BRA Wr_ContWr_S0:TxOn;開啟60,關閉10 uDelay 60 TxOff uDelay 10 BRA Wr_ContWr_End:PULA PULX RTS讀取:PSHB LDAB#%00000001 CLRARd_Loop:TxOn;開啟6,關閉10 uDelay 6 TxOff uDelay 10 BRSET PortA,#RxPin,Rd_Sub1;高?將當前位添加到輸出byteRd_Cont:uDelay 155;延遲和移位.. 0?移位8次,結束LSLB BNE Rd_Loop BRA Rd_EndRd_Sub1:ABA
BRA Rd_ContRd_End:PULB RTSuDelay宏;延遲一個1us的多義字符(正好適用於elays > 1us的elay)PSHD LDD#\ 1 SUBD#1 LSLD \ @LOOP NOP DBNE D,\ @LOOP PULD endm; -------- -----------------------------;常規功能; ----------------- --------------------; delaysDel1us:RTSDel1ms:PSHA LDAA#252Del_ms:JSR Del1us JSR Del1us JSR Del1us CMPA $ 0000 CMPA $ 0000 NOP DECA BNE Del_ms CMPA $ 0000 NOP PULA RTS;回顯:PSHY PSHB LDAB 0,XEch_Lp:LDY屏幕JSR 0,Y INX LDAB 0,X CMPB#0 BNE Ech_Lp PULB PULY RTS中斷:SWI RTI; ---------- ---------------------------;變量; -------------------- ----------------- ORG $ 0800OutUp:DC.B'當前溫度為',0Rise:DC.B'和Rising',$ 0D,$ 0A,0穩定度:DC .B'and Steady',$ 0D,$ 0A,0Fall:DC.B'and Falling',$ 0D,$ 0A,0Temp:DS 2 DC.B 0TempOld:DS 2TempNew:DS 2
>
如果有興趣,這是我編寫的使用DS18B20溫度傳感器(如上文所述,可以使用Pi上的相同GPIO引腳與任意數量鏈接的鏈)的指南,並帶有Raspberry Pi和一些發布的Pyhton代碼將其存儲到一個RESTful服務中,該服務可在網站上匯總並顯示圖表中的溫度。所有代碼均在指定的GitHub帳戶上公開。 http://macgyverdev.blogspot.se/2014/01/weather-station- using-raspberry-pi.html
您使用哪種溫度傳感器?如果您有DS18B20之類的東西,那麼如果有那麼多傳感器,則可以鏈接多達18446744073709551615個傳感器。
回答:
我如何將5-6個溫度傳感器復用到Raspberry Pi?
有一些附加模塊,您可以得到
此視頻比較了它們的速度: https://www.youtube.com/watch?v=YbWidNBycls他最終使用了重新編譯的內核來實現與多個傳感器通信的多個GPIO。他尚未發佈如何獲得結果的結果。但是有可能多路復用而不是僅使用一個引腳。
更新。他已經發布了。他將81個傳感器連接到9個單獨的GPIO,並能夠在3秒內獲得所有溫度: https://www.youtube.com/watch?v=JW9wzbp35w8
讀取多個傳感器的理想方法是使用I2C傳感器。
這是將多個傳感器鏈接在一起或使用模擬傳感器的唯一方法,但是它們會佔用很多模擬引腳,但是i2c會僅使用2條線。讓我們說您正在使用Pi2 / 3,那麼我建議您使用具有I2C端口的 Raspberry Pi帽子,以便您可以在幾秒鐘內將所有i2c設備與Pi連接起來,確保您的硬件是正確的。
現在您已經有了帶有I2C適配器的Pi,讓其在傳感器部分上移動。 TI,AD,NXP,飛思卡爾和許多其他公司使用I2C製造溫度傳感器,但是您要連接一個以上的傳感器,因此有兩種選擇。
獲得6種不同的I2C具有不同I2C地址的傳感器,如果您有兩個具有相同地址的傳感器,它將無法正常工作。
您可以獲得帶地址線的傳感器,只需更改地址即可,然後將它們與Pi沒有任何地址衝突。我會建議使用此 TMP 100傳感器,我更喜歡使用它,因為它具有2條地址線和浮動地址線支持,因此您可以將6條傳感器與1條i2c線連接起來。
使用相同的傳感器的優點是,您不必閱讀6個數據表來編寫代碼,您將需要學習一個數據表並以簡單的方式編寫代碼。如果所有傳感器都相同,那麼您將獲得更好的比較結果。