树莓派获取温度

前言

通过树莓派获取室内温度


一、树莓派是什么

树莓派(Raspberry Pi)是一款基于 Linux 的单片机电脑。树莓派虽小,但五脏俱全和普通电脑无异。普通电脑能做的大部分事情,在树莓派上都能做,而树莓派以其低能耗、移动便携性、GPIO 等特性,很多在普通电脑上难以做好的事情,用树莓派却是很适合的。
树莓派

二、获取温度

1.思路

找到温度文件,然后通过文件IO读取文件的温度。先找到/sys/bus/w1/devices/文件夹,对其使用文件夹操作,打开该文件夹,查看文件夹当中的文件,使用strstr(字符串查找函数)找到以"28-"开头的文件。找到该文件后,将文件名加到 /sys/bus/w1/devices/之后,再加上/w1_slave就得到了文件的完整路径。
然后通过这个获取到的路径打开文件,对文件进行读取操作。注意从文件中读取到的数据都是字符,用strstr找到以"t="开头的字符可以得到温度,但是此时获取到的温度依然是字符串,需要使用atof()将字符转换为数值(浮点数),再将得到的结果除以1000就得到了温度。

2.代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
           
#define BUFSIZE 1024
              
int main(int argc, char *argv[])
{
    char            path[64] = "/sys/bus/w1/devices/";  //存放文件路径
    char            path_28[32];  //存放查找到的文件“28—”
    char            buf[BUFSIZE];  //缓冲区,存放从文件中读取的数据
    char           *ptr;  //存放”t=“的首地址
    int             fd = -1;  //文件描述符
    int             rv = -1;  //读取文件后的结果返回值
    int             found = -1;  //是否找到文件”28-“
    DIR            *diro;  //存放打开文件夹的返回值
    struct dirent  *diread;  //存放读文件夹的返回值
    float           temp;  //存放温度值
                            
    //判断打开文件夹是否成功
    if ((diro = opendir(path)) == NULL)  
    {
        //当返回值为空时,表示打开文件夹失败,错误原因的代号会存到 errno中,使用strerror可以将错误代号转换为字符串显示
        printf("opendir failure: %s\n", strerror(errno));
    }
                              
    while ((diread = readdir(diro)) != NULL)  //打开文件成功,循环读取文件夹中的文件,直到读完为止
    {
        if (strstr(diread->d_name,"28-"))  //判断读到的文件以”28-“开头
        {
            strcpy(path_28, diread->d_name);  //将文件名存到数组path_28中
            found=1;  //将found置为1表示文件已找到
        }
    }
    closedir(diro);
 
    if (found != 1)  //文件未找到
    {
        printf("Can not found ds18b20 in %s\n", path);
        return -1;
    }

    //使用strncrt函数得到文件路径
    strncat(path, path_28, sizeof(path));  //将文件名加到数组path中
    strncat(path, "/w1_slave", sizeof(path));  //将 /w1_slave 加到数组path中
 
    if ((fd = open(path, O_RDONLY)) < 0)  //以只读方式打开,fd<0则打开失败
    {
        printf("Open file  %s failure:%s\n", path, strerror(errno));
        goto cleanup;
    }
 
    if ((rv = read(fd, buf, sizeof(buf))) < 0)  //读取文件数据,rv<0,读取失败
    {
        printf("Read data from %s failure: %s\n", strerror(errno));
        goto cleanup;
    }

    ptr = strstr(buf, "t=") + 2;  //在buf数组中找到"t="的地址,并将地址加2得到温度字符的首地址
 
    if (!ptr)  //为获取到温度
    {
        printf("Get temperature failure!\n");
        goto cleanup;
    }
 
    temp=atof(ptr)/1000;  //将温度字符转换为数值,再将结果除以1000得到温度
    printf("ds18b20 get temperature: %.4f ℃\n",temp);  //输出4位小数的温度
   
    cleanup:
        close(fd);
 
    return 0;
}

三、结果

1.使用命令查看温度

使用cat命令查看 /sys/bus/w1/devices/28-41731f7c0ff/w1_slave 文件可以得到当前温度

iot11@Public_RPi:~/siyu $ cat /sys/bus/w1/devices/28-041731f7c0ff/w1_slave
c8 00 4b 46 7f ff 0c 10 39 : crc=39 YES
c8 00 4b 46 7f ff 0c 10 39 t=12500

2.代码运行结果

c8 00 4b 46 7f ff 0c 10 39 t=12500
iot11@Public_RPi:~/siyu $ gcc ds18b20.c
iot11@Public_RPi:~/siyu $ ./a.out      
ds18b20 get temperature: 12.5000

版权声明:本文为qq_44991159原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。