树莓派 DS18B20 探测温度

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

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

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

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

从上面结果可以看到,温度值为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 <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <time.h>
#include <fcntl.h>

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++;程序执行下面的语句。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值