Linux下C語言獲取樹莓派DS18B20溫度(一)
阿新 • • 發佈:2021-01-28
技術標籤:基於Linux作業系統 中C語言的檔案操作linuxc語言指標
檔案和目錄檢索的學習
文章目錄
一、思路分析
首先我們需要獲得溫度資料是儲存在 “w1_salve” 這個檔案裡的。
檔案路徑和儲存形式如圖:
在這 28-041731f7c0ff 此資料夾名稱的含義是DS18B20的序列號。所以我們需要在提供的路徑下檢索關鍵詞 “28” ,進入到 28-041731f7c0ff 資料夾下,由上圖知,溫度的儲存形式: “t=10375” 表示此時溫度10.375℃。故 索“w1_slave”檔案內的 “t=” 即可得到溫度的在檔案內的存放位置。
一、具體程式碼
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
int main(int main,char *argv[])
{
char *ptr = NULL ;
DIR *dp;
struct dirent *direntp;
int found = 0;
int rv = -1;
int fd = -1;
char buf[100];
char temper_path[100] = "/sys/bus/w1/devices/";
char chip[20];
double temper_num;
dp = opendir(temper_path); //開啟目錄/sys/bus/w1/devices/
if(dp == NULL)
{
printf("open file error:%s\n",strerror (errno));
return -1;
}
printf("open file success,dp:%p\n",dp);
do{
direntp = readdir(dp);
printf("file name:%s\n",direntp->d_name); //讀取/sys/bus/w1/devices/ 此目錄下的檔名
if(strstr(direntp->d_name,"28")) //匹配檔名中包含 “28” 的檔名
{
strcat(chip,direntp->d_name);
found = 1;
printf("found = %d\n",found); //標誌位 表示:找到包含 “28” 的檔案
break;
}
}while(direntp != NULL);
closedir(dp);
if(!found)
{
printf("Not found");
return -2;
}
strncat(temper_path,chip,sizeof(temper_path));
strncat(temper_path,"/w1_slave",sizeof(temper_path));
//路徑拼接 /sys/bus/w1/devices/28-041731f7c0ff/w1_slave
fd = open(temper_path, O_RDONLY); //開啟w1_slave檔案
if(fd < 0)
{
printf("open file %s error:%s\n",temper_path,strerror(errno));
return -3;
}
rv = read(fd,buf,sizeof(buf)); //讀取檔案內容
if(rv < 0)
{
printf("read error:%s\n",strerror(errno));
return -4;
}
close(fd);
ptr = strstr(buf,"t="); //找到 t= 的地址位置
if(ptr == NULL)
{
printf("read temperature error\n");
return -5;
}
ptr+=2; //去掉 t=
temper_num = atof(ptr); //char型轉double型
temper_num = temper_num/1000;
printf("temperature is %3.3f ℃n", temper_num);
return 0;
}
執行結果:
二、函式分析
1.readdir()
標頭檔案:
#include <sys/types.h>
#include <dirent.h>
定義函式:struct dirent * readdir(DIR * dir);
函式說明:
readdir() 返回值:若成功,返回指標,指標指向下一個目錄進入點;若在目錄尾或出錯,返回NULL
結構dirent 定義如下:
struct dirent
{
ino_t d_ino; //d_ino 此目錄進入點的inode
ff_t d_off; //d_off 目錄檔案開頭至此目錄進入點的位移
signed short int d_reclen; //d_reclen _name 的長度, 不包含NULL 字元
unsigned char d_type; //d_type d_name 所指的檔案型別 d_name 檔名
char d_name[256]; //*dir 所指的檔案型別 d_name 檔名
};
總結
注意路徑的格式,標頭檔案。 char temper_path[100] = "/sys/bus/w1/devices/";
我當時是 “/sys/bus/w1/devices” 最後那裡沒有加 “/” ,導致不能找到檔案。
每個地方的返回值不同 可以用 echo $?讀到返回值。以此找到程式結束的位置。