树莓派 DS18B20 探测温度

一、DS18B20模块与树莓派的连接

树莓派 DS18B20 探测温度_第1张图片

二、使能内核一线协议驱动模块

该传输采用一线协议传输模式

配置内核启动后自动加载一线协议驱动

树莓派 DS18B20 探测温度_第2张图片

树莓派 DS18B20 探测温度_第3张图片

树莓派 DS18B20 探测温度_第4张图片

从上面结果可以看到,温度值为24.375℃

三、编程思路

在"/sys/bus/w1/devices/"下寻找是否有以"28-"开头的序列号,若有,将其和其下的"/w1_slave"放到之前定义的路径数组w1_path下,

再用文件操作函数打开文件获取温度。

四、C程序读取DS18B20温度源码

linlan@raspberrypi:~/ds18b20 $ vim ds18b20.c 

/**********************************************************************

    > File Name: ds18b20.c

    > Author: linlan

    > Created Time: Tue 18 Sep 2018 15:33:12 UTC

***********************************************************************/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int ds18b20_get_temperature(float * temp);

int main(int argc,char *argv[])
{
        float temp;

        if(ds18b20_get_temperature(&temp)<0)
        {   
            printf("Error:ds18b20 get temperature failure.\n");
            return 1;
        }   

        printf("Ds18b20 get temperature is %f\n",temp);

        return 0;
}

int ds18b20_get_temperature(float * temp)
{

        char buf[256];
        char w1_path[200] = "/sys/bus/w1/devices/";
        DIR * dirp;
        char serial_number[100];
        struct dirent * direntp;
        char * p;
        int fd = -1;
        int found = 0;
        float value;


        if(!temp)
        {
                return -1;
        }


       if((dirp = opendir(w1_path)) == NULL)
       {

               printf("Opendir failure:%s.\n",strerror(errno));

               return -2;
       }


       while((direntp = readdir(dirp)) != NULL)
       {

            if(strstr(direntp->d_name,"28-"))
            {


                strncpy (serial_number,direntp->d_name,sizeof(serial_number));

                found = 1;

            }
       }
closedir(dirp);


       if (!found)
       {

            printf("Can't find ds18b20 in %s.\n",w1_path);

            return -3;

       }


       strncat(w1_path,serial_number,sizeof(w1_path));
       strncat(w1_path,"/w1_slave",sizeof(w1_path));

       if((fd = open(w1_path,O_RDONLY)) < 0)
       {

               printf("open %s error:%s\n",w1_path,strerror(errno));

               return -4;

       }


       if((read(fd,buf,sizeof(buf)))< 0)
       {
               printf("read %s error:%s\n",w1_path,strerror(errno));

               return -5;

       }


       p = strstr(buf,"t=");

       if(!p)
       {
               printf("Can not get the temperature.\n");

               return -6;

       }


       p = p+2;

       *temp = atof(p)/1000;

       return 0;
}




编译、连接、运行,结果显示

linlan@raspberrypi:~/ds18b20 $ gcc ds18b20.c  -o ds18b20
linlan@raspberrypi:~/ds18b20 $ ./a.out
Ds18b20 get temperature is 24.625000

五、问题与解决方案

while((direntp = readdir(dirp)) != NULL)
       {

            if(strstr(direntp->d_name,"28-"))
            {


                strncpy (serial_number,direntp->d_name,sizeof(serial_number));

                found = 1;

            }
       }

开始while语句使用的if语句,编译没有报错,但结果显示如图

原因:利用strstr找子串时,需要将文件遍历,所有目录中都查找一遍看是否有出现"-28"。

while和if的区别

while循环语句,可以执行多次,if是条件语句,只是单次执行。

while(表达式) 语句组; 计算表达式,若为真,执行语句,并重复该过程,直到为假时,执行下一条语句。 

例如:while(k>0)i++;表示只要k>0,就执行i++;直到等到k<=0时,不执行i++;程序执行下面的语句。

 

你可能感兴趣的:(c++,编程)