1. 程式人生 > 其它 >通過樹莓派獲取溫度(基於檔案I/O的簡單應用)

通過樹莓派獲取溫度(基於檔案I/O的簡單應用)

技術標籤:APUE

樹莓派DS18B20獲取溫度

1 專案背景介紹

1.1專案想法

DS18B20是常用的數字溫度感測器,其輸出的是數字訊號,具有體積小,硬體開銷低,抗干擾能力強,精度高的特點,剛好拿實驗室的樹莓派來做一下獲取溫度的小專案。
當樹莓派配置好DS18B20數字溫度感測器後,該溫度資訊通常儲存在下面路徑中,我們只需要讀取檔案中的溫度即可:

/sys/bus/w1/devices/
28-XXXXXXXX/w1_slave

檢視路徑檔案下溫度資料:
在這裡插入圖片描述

1.2流程描述

1 呼叫opendir()和readdir()來開啟讀取檔案路徑(預設檔案路徑“/sys/bus/w1/devices/”)
在這裡我們注意到為什麼不是全部路徑 (/sys/bus/w1/devices/28-XXXXXXXX/w1_slave) 而是隻擷取到 (/sys/bus/w1/devices/),這是因為“28-XXXXX”是產品序列號,如果我們換了一個DS18B20進行獲取溫度,產品序列號XXXXX改變,那此路徑就不能用了,而這一產品序列號XXXXX目錄無論變成什麼永遠在(/sys/bus/w1/devices/)路徑下,所以我們只打開讀取路徑到這裡

2 尋找“28-”開頭的檔案,將其存入緩衝區
接下來在(預設檔案路徑“/sys/bus/w1/devices/”)下通過strstr()函式找到“28-”打頭的檔案,並且存入緩衝區,方便更改

3 呼叫closedir()關閉檔案**

4 通過strncat連結檔案路徑
呼叫strncat將(預設檔案路徑“/sys/bus/w1/devices/”)和存入緩衝區的(“28-XXXXX”)連線起來,然後再呼叫strncat()將“/w1_slave”路徑連線起來,此時需要讀取資料的路徑就完整了,進行實時獲取產品序列號的檔案目錄,以便實時讀取溫度

5 呼叫open()l和read()來開啟檔案,讀取檔案,找到溫度(t=)打頭的資料


利用strstr()再匹配(“t=”)打頭的資料

6 呼叫close()關閉檔案

7 將資料進行處理然後列印即可
將獲得的字元型別資料轉換成單精度型別資料,只打印資料,不列印“t=”

2 專案程式碼介紹

2.1檔案I/O的API函式

open()

 int open(const char *path, int oflag, ... /*mode_t mode*/);

open()系統呼叫用來開啟一個檔案,並且返回一個檔案描述符(fd),並且該檔案描述符是當前程序最小,並未使用的檔案描述符數值,即3,因為0是標準輸入,1是標準輸出,2是標準出錯。
引數: path: 要開啟的檔案、裝置的路徑
oflag: 由多個選項進行“或”運算構造oflag引數 。
必選: O_RDONLY (只讀)、 O_WRONLY(只寫)、 O_RDWR(讀寫)
可選: O_APPEND 每次寫時都追加到檔案的尾端。
O_CREAT 檔案不存在則建立它,使用該選項需要第三個引數mode
O_TRUNC 如果檔案存在,而且為只寫或讀寫成功開啟,則將其長度擷取為0;
O_NONBLOCK 如果path是一個FIFO、塊裝置、字元特殊檔案則此選項為檔案的本次開啟和後續的I/O操作
設定非阻塞模式方式。
O_EXEC、O_SEARCH、O_CLOEXEC、O_NOCTTY…
mode: oflag帶O_CREAT選項時可以用來建立檔案,這時必須帶該引數用來指定建立檔案的許可權模式,如066。 否則不
需要。使用示例程式碼:

int fd; 
fd = open(“text.txt”, O_RDWR|O_CREAT|O_TRUNC, 0666);
fd = open(“text.txt”, O_WRONLY|O_APPEND);

read()

ssize_t read(int fd, void*buf, size_t nbytes);

read()函式是用來開啟檔案描述符對應的檔案中讀取資料放到buf指向的記憶體空間中去,最多不要超過nbytes個位元組,這裡的nbytes一般指的是buf剩餘空間的大小。如果read成功,則返回實際讀到的位元組數(由nbtyes或讀懂到檔案尾決定,其中EOF巨集用來判斷是否到了檔案尾),如果返回值小於0則表示出錯,如哦嘗試讀取一個沒有許可權讀取的檔案時就會拋錯。

close()

int close(int fd);

該函式用來關閉一個開啟的檔案描述符,關閉一個檔案時還會釋放該程序載入該檔案上的所有記錄鎖。當一個程序終止時,核心將會自動關閉它所開啟的檔案。

opendir()

DIR *opendir(const char *pathname)

readdir()

closedir()

2.2專案程式碼