一起玩轉樹莓派(9)——DS18B20測溫模塊應用
關於使用樹莓派測量溫度,我們之前在學習模數轉換的相關博客中已經有過應用。其實除了使用傳統的AD採集溫度數據外,我們也可以通過樹莓派中的單總線技術結合DS18B20傳感器來更加方便精準的測量環境溫度。
一、認識DS18B20模塊與單總線通信
DS18B20是一種改進型的智能溫度傳感器。與傳統的熱敏電阻相比,其可以直接讀出被測量的溫度,並且能夠根據實際應用場景中的要求進行簡單的編程。無論是讀取數據還是寫入數據,DS18B20都只需要一條接口線,因此其使用的是單總線的通訊協議。DS18B20模塊的主要優勢在於其抗干擾能力強,精度高,無需複雜的軟件處理可以直接輸出溫度數據。本次實驗,我們使用的DS18B20模塊如下圖所示:
可以看到此模塊有3個引腳,除了電源引腳和接地引腳外,剩下的一個就是用來輸出溫度數據的引腳。
單總線通信被稱爲one-wire通信,因此又常常被簡稱爲1w總線通信。首先我們需要先開始樹莓派的1w總線通信功能,打開樹莓派的Raspberry Configuration菜單,在Interfaces選項中將1-Wire功能開啓,如下圖所示。
如果我們是通過無交互頁面的終端登錄的樹莓派,也可以通過修改配置文件來開啓1-Wire功能,在樹莓派Linux系統的根目錄下,找到如下路徑的文件:
/boot/config.txt
在其中添加如下一行文本即可:
dtoverlay=w1-gpio
需要注意,添加之後需要重啓樹莓派。需要注意,1-Wire功能默認將使用樹莓派的BCM編碼爲GPIO4的引腳作爲通信引腳,如何我們要進行自定義,可以在剛纔的配置文件中進行指定,如下:
dtoverlay=w1-gpio,gpiopin=18
其表示要使用BCM編碼爲GPIO18的引腳作爲通信引腳。
做完了上面的操作後,我們可以在樹莓派終端中使用如下指令查看單總線是否啓動成功:
$ lsmod
終端輸出效果如下:
可以看到,如果有顯示w1_gpio和wire兩個部分,則表示單總線已經啓動成功,分別在終端執行如下兩條命令:
$ modprobe w1-gpio
$ modprobe w1-therm
如果終端沒有輸出任何信息,則表示單總線已經初始化完成,此時實際上我們已經可以讓DS18B20進行工作了。
二、通過DS18B20模塊獲取環境溫度
通過前面的操作,我們已經完成了基本的準備工作,將DS18B20連接到樹莓派,引腳對應如下:
DS18B20 | 樹莓派 |
---|---|
+ | 3.3V |
- | GND |
out | BCM編碼爲GPIO4的引腳 |
之後我們從樹莓派的終端進入如下目錄:
/sys/bus/w1/devices
在此目錄下,我們可以看到有兩個文件,如下圖所示:
其中以28-xxx開頭的文件夾中的文件記錄的就是1w單總線輸入的數據,需要注意,讀者操作時,此文件夾的名稱和筆者可能並不完全一樣,其表示傳感器設備的編號,大家這裏只需要找到28-xx開頭的文件夾即可。在此文件夾中,有一個名爲w1_slave的文件,此文件中記錄的就是傳感器的溫度數據,我們可以打開看看,內容如下:
d2 01 55 05 7f 7e 81 66 59 : crc=59 YES
d2 01 55 05 7f 7e 81 66 59 t=29125
其中,大部分數據我們都無需關心,其最後的t=29125就是當前的環境溫度,將其轉換爲攝氏溫度,直接除以1000即可,例如上面的數據表明當前的環境溫度是29.125攝氏度。
目前爲止,我們已經可以非常輕鬆的獲取DS18B20模塊提供的溫度數據了,但是查看的方式非常不智能,其實我們可以通過Python程序來不停的讀取此數據文件,解析出其中的溫度數據,之後無論是做記錄還是進行其他元件控制都會非常方便。編寫示例代碼如下:
#coding:utf8
import os,time
# 傳感器編號
name = "28-020692455d61"
# 設備記錄數據的文件地址
device_file ='/sys/bus/w1/devices/' + name + '/w1_slave'
# 讀取文件數據
def read_temp_raw():
f = open(device_file,'r')
lines = f.readlines()
f.close()
return lines
# 解析溫度數據
def read_temp():
lines = read_temp_raw()
# 此行默認不是'YES' 表明未讀取到有效數據
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
# 循環繼續讀
lines = read_temp_raw()
# 找到第2行的't='的位置
equals_pos = lines[1].find('t=')
# 將溫度數據取出
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string)/1000.0
return temp_c
while True:
print('%fC'%read_temp())
time.sleep(1)
在樹莓派中運行上面代碼,可以看到控制檯輸出的當前溫度數據,如下圖所示:
三、講在後面
本篇博客,我們介紹瞭如何使用one-wire單總線進行外設數據的讀取,DS18B20只是作爲示例,拋磚引玉,通過樹莓派的1w總線,我們還可以連接更多的外設實現更加有創意的東西,大家開動腦筋,盡情玩耍吧!
專注技術,懂的熱愛,願意分享,做個朋友
QQ:316045346