文章目录

  • 1. DS18B20温度传感器
  • 2. DS18B20安装及配置
  • 3.基础代码逻辑分析
    • 3.1 逻辑分析
    • 3.2 阶段代码示例
  • 4. 代码及运行结果
    • 4.1 全部代码
    • 4.1 运行结果

1. DS18B20温度传感器

  DS18B20是比较常用到的温度传感器,采用单总线控制。是美国DALLAS半导体公司继DS1820之后最新推出的一种改进型智能温度传感器。
  这里对于它就不进行过多的讲解,主要讲解如何在树莓派上用它来获取温度。详细资料参考:DS18B20介绍。

2. DS18B20安装及配置

  DS18B20的接线连接参照下图,VCC接3.3v的引脚,GND接地,DQ线连在GPIO04上。

  接好线之后,我们要配置内核启动后自动加载一线协议驱动,在命令行键入sudo raspi-config,依次选择如下选项,就可以使能内核以一线协议(1-wire)驱动模块。

  然后命令行键入vim /boot/config.txt,并在最后一行添加 dtoverlay=w1-gpio-pullup,gpiopin=4。(这里的4就是pin7,应该是采用BCM GPIO的标准)。
  随后sudo reboot重启系统,键入 lsmod | grep w1 检查系统是否已经自动加载一线协议的驱动模块。

  我们知道Linux下“一切皆文件”,DS18B20的文件就在“/sys/bus/w1/devices/”下

  这个叫“28-041731f7c0ff”的文件夹是我用的这个DS18B20的产品序列号,然后在这个文件夹里面的“w1_slave”里就存放着实时的温度,我们可以看一看

  前面那些数据我们不管他,可以看到“t=11250”,这个就是我这个设备上的实时温度(11.25℃)。了解到这些之后,我们来捋一捋代码里面要用什么样的方式来读取这个温度,并显示出来。

3.基础代码逻辑分析

3.1 逻辑分析

  如果我们人为的想要在树莓派上读取温度,我们需要转到相应路径下去,查看相应的文件即可,但是我们编写程序的时候,为了得到更广泛的适用性,并不能直接简单粗暴地用read()去读取相应路径下的文件,因为每个DS18B20的产品序列号不一样,那么温度保存文件的路径也就会不一样。

  因为序列号不同的缘故,我们的代码需要逐步实现如下功能:

step1. 用opendir()和readdir()的组合,打开每个设备都一样的默认路径(/sys/bus/w1/devices/),并读取路径下的内容。

step2. 找出默认路径下“28-”开头的的文件夹,并将其名称保存到一个缓存区中,然后用这个缓存区的内容来更新目标路径。

step3. 用open()和read()读取目标路径的内容,找出其中“t=”的部分,并记录下来。随后便可以简单粗暴的一个printf()将实时温度打印到标准输出上。

3.2 阶段代码示例

  依照上面的思路,我们可以先做出前两部分寻找目标路径的代码,这里我用了strstr()来找以“28-”开头的文件夹。还用了strncat()来更新目标文件路径。

strstr()的作用是判断前者字符串中是否包含有后者字符串的内容,若包含,返回其第一次出现的首地址,若无则返回NULL
strncat()的作用是在一个字符串的后面加上另一个字符串,并且能保证前者的剩余空间足够放下后者。

if((dir = opendir(path)) == NULL )                            //打开文件夹并判断成败{printf("Open directory failed: %s", strerror(errno));    //失败打印提示return -1;}while((direntp = readdir(dir)) != NULL)                        //读取文件夹内容,用direntp保存其地址{/***************************步骤1和步骤2的假想分割线********************************/if(strstr(direntp->d_name, "28"));                        //用if循环找“28-”开头的文件夹{strcpy(dstfile, direntp->d_name);                    //将目标路径文件夹保存到缓冲区flag = 1;                                          //成功找到“28-”开头的文件夹的标志,}}closedir(dir);                                //关闭文件夹if(flag != 1)                                               //利用标志判断有没有成功找到“28-”开头的文件夹{printf("Can not found the temperature file.\n");       return -2;}strncat(path, dstfile, sizeof(path));                //给默认路径加上找到的“28-”开头的文件夹strncat(path, "/w1_slave", sizeof(path));          //继续加上需要打开的文件“w1_slave”,这样就完成了目标路径的更新

  简单介绍一下opendir()、readdir() 和 closedir() 这几个函数的使用,他们的原型和介绍如下:

#include <sys/types.h>             //opendir()的头文件
#include <dirent.h>                   //opendir()的头文件
DIR *opendir(const char *name);   //打开参数name指定的目录,并返回DIR*类型的目录流,类似于文件描述符#include<sys/types.h>                 //readdir()的头文件
#include <dirent.h>                       //readdir()的头文件
struct dirent *readdir(DIR *dir);       //读取某个文件夹里的内容,保存到结构体dirent里,返回该结构体的地址struct dirent                        //readdir返回的结构体内容
{ino_t d_ino;                   // 此目录进入点的inodeff_t d_off;                  // 目录文件开头至此目录进入点的位移signed short int d_reclen;       // 文件的的长度, 不包含NULL 字符unsigned char d_type;          // 文件类型 har d_name[256];                // 文件名(这里我们只关心这个!)
};#include<sys/types.h>           //closedir()的头文件
#include <dirent.h>               //closedir()的头文件
closedir(DIR *dir);             //类似cloes,简单粗暴,用完就关

  有了目标路径,那接下来就好办了,用一套open()、read() 和 close() 的组合就能很简单的读出来,同样用strstr()来找到文件中“t=”开头的字符串首地址,但是我们在打印温度的时候需要将这个地址向后偏移两个字节,去掉“t=”

if((fd = open(path, O_RDONLY)) < 0 )             //根据目标路径以只读的形式打开文件,同样加上错误判断{printf("Open temperature file failed: %s\n", strerror(errno));     //出错提醒return -3;}if((rv = read(fd, buf, sizeof(buf))) < 0)          //读取文件内容,并保存在buf里{printf("Read temperature data failed: %s\n", strerror(errno));return -4;}close(fd);if((ptr = strstr(buf, "t=")) != NULL)            //strstr()找到温度存放的地址,并保存起来{tem = atof(ptr+2)/1000;                     //这里加2是将地址偏移两个字节,跳过文件中的“t=”,只保留有用的温度数据printf("The temperature in LingYun Studio is %f now.\n", tem);       //简单粗暴,快哉!}else{printf("Can not read the temperature data: %s.\n", strerror(errno));    //buf里面没有读取到温度数据,就会报错return -5;}

4. 代码及运行结果

4.1 全部代码

  给上面的代码加上头文件,并声明相关参数,就可以得到完整的代码:

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>#define PATH   "/sys/bus/w1/devices/"        //宏定义默认路径
#define BUF_SIZE     128
#define PATH_SIZE    100int main(int argc, char **argv[])
{char           path[PATH_SIZE] = PATH;        //局部变量保存默认路径DIR             *dir;                       //opendir的返回类型,用来指定打开的文件夹struct dirent   *direntp;                   //readdir返回的结构体指针,用来指向打开文件夹的内容char           dstfile[48];                //目标路径缓存区int            flag = -1;                 //初始化文件夹读取成败标志int               fd = -1;                   //初始化文件描述符int               rv = -1;                   //初始化文件读取返回值char            buf[BUF_SIZE];              //实时温度缓冲区double         tem = 0.00;                    //初始化实时温度数据 char            *ptr = NULL;               //初始化实时温度缓冲区指针if((dir = opendir(path)) == NULL )                         //打开文件夹并判断成败{printf("Open directory failed: %s", strerror(errno));    //失败打印提示return -1;}while((direntp = readdir(dir)) != NULL)                        //读取文件夹内容,用direntp保存其地址{if(strstr(direntp->d_name, "28"));                      //找到“28-”开头的文件夹{strcpy(dstfile, direntp->d_name);                    //将目标路径文件夹保存到缓冲区flag = 1;                                          //成功找到“28-”开头的文件夹的标志,}}closedir(dir);                                //关闭文件夹if(flag != 1)                                               //利用标志判断有没有成功找到“28-”开头的文件夹{printf("Can not found the temperature file.\n");       return -2;}strncat(path, dstfile, sizeof(path));                //给默认路径加上找到的“28-”开头的文件夹strncat(path, "/w1_slave", sizeof(path));          //继续加上需要打开的文件“w1_slave”,这样就完成了目标路径的更新if((fd = open(path, O_RDONLY)) < 0 )               //根据目标路径以只读的形式打开文件,同样加上错误判断{printf("Open temperature file failed: %s\n", strerror(errno));     //出错提醒return -3;}if((rv = read(fd, buf, sizeof(buf))) < 0)          //读取文件内容,并保存在buf里{printf("Read temperature data failed: %s\n", strerror(errno));return -4;}close(fd);if((ptr = strstr(buf, "t=")) != NULL)            //strstr()找到温度存放的地址,并保存起来{tem = atof(ptr+2)/1000;                     //这里加2是讲地址便宜两个字节,跳过文件中的“t=”,只保留有用的温度数据printf("The temperature in LingYun Studio is %f now.\n", tem);       //简单粗暴,快哉!}else{printf("Can not read the temperature data: %s.\n", strerror(errno));    //buf里面没有读取到温度数据,就会报错return -5;}return 0;                            // ending
}

4.1 运行结果

  编译后运行就可以得到如下结果:

树莓派下DS18B20获取实时温度相关推荐

  1. DS18B20温度传感器在树莓派下获取实时温度

    目录 1. DS18B20温度传感器的介绍 2.代码流程分析 2.1获取实时温度值 2.2获取温度值存放路径 2.3用到的库函数 3.完整代码 4.输出结果 1. DS18B20温度传感器的介绍 DS ...

  2. 树莓派与DS18B20获取环境温度(Linux)

    树莓派与DS18B20获取环境温度(Linux) 前言 一.硬件准备 1.1 树莓派4B 1.2 DS18B20温湿度传感器 1.4 项目展示效果 二.软件准备 2.1 Vim(Linux) 2.2 ...

  3. STM32+MAX6675利用io口模拟SPI获取实时温度数据程序及代码

    STM32+MAX6675利用io口模拟SPI获取实时温度数据程序及代码 本文采用的芯片为STM32F103RCT6 温度芯片为MAX6675 因为芯片的spi口只有3个,有部分需要外接W25Q128 ...

  4. STM32+MAX6675利用SPI获取实时温度数据程序及代码

    之前写的STM32+MAX6675利用io口模拟SPI获取实时温度数据程序及代码 本文采用的芯片为STM32F103RCT6 温度芯片为MAX6675 模拟spi之前写过 里面的部分代码摘取的正点原子 ...

  5. linux 下如何获取 cpu 温度

    直接读取系统信息 可以通过读取如下路径中的数据来获取cpu的温度信息,不过读取的数据没有经过处理. cpu0: cat /sys/class/thermal/thermal_zone0/temp cp ...

  6. max6675 c语言程序,STM32+MAX6675利用SPI获取实时温度数据程序及代码

    标签: 本文采用的芯片为STM32F103RCT6 温度芯片为MAX6675 模拟spi之前写过 里面的部分代码摘取的正点原子的函数库:sys.uart.delay等文件 原理图 max6675.h ...

  7. python获取cpu温度_如何获得树莓派CPU实时温度值

    [前言] 任何的电子设备在工作过程中必定会产生发热的现象,而不控制好设备的温度的话,很有可能会损坏设备,或者照成设备的性能下降,本文将通过学习如何读取树莓派CPU温度值,方便后期对树莓派做一些相应的控 ...

  8. 如何获得树莓派CPU实时温度值

    如何获得树莓派CPU实时温度值 [前言] 任何的电子设备在工作过程中必定会产生发热的现象,而不控制好设备的温度的话,很有可能会损坏设备,或者照成设备的性能下降,本文将通过学习如何读取树莓派CPU温度值 ...

  9. Java免费获取实时汇率API

    最近在做项目,涉及到实时汇率的获取,查了很多方法.下面写下自己获取实时汇率的心得,希望帮到有需要的人. 我使用的是聚合数据,免费的货币汇率API https://www.juhe.cn/docs/ap ...

最新文章

  1. 还不会用 K8s 集群控制器?那你会用冰箱吗?(多图详解)
  2. jquery.easing.js(转)
  3. 找出数组中前K大的值
  4. 约瑟夫问题C语言加注释,用链表实现约瑟夫环【有注释,有很多注释】
  5. 第四次作业 孙保平034 李路平029
  6. ROS----小乌龟之你追我赶
  7. thinkphp多表查询两表有重复相同字段解决方法
  8. prime算法-最小生成树
  9. 在 Windows XP Embedded 中使用 Enhanced Write Filter (EWF)[微软影子系统]
  10. 如何用python 巡检华为交换机?
  11. c语言使用三种方法计算圆周率,求用三种方法计算圆周率(C语言)
  12. 11种服务器编程语言对比(附游戏服务器框架) 2020.06
  13. 微信聊天记录的图片在哪查看
  14. 条件与循环Phython
  15. Unity制作出《超级马里奥》的2D和3D混合效果
  16. nginx实现对css,js文件缓存
  17. 仿soul交友盲盒1.0全开源源码/完整盲盒交友系统源码
  18. 了解Oracle历史
  19. 六级高频词汇——Group06
  20. Java三种多线程实现睡眠排序

热门文章

  1. 又一所985大学改考408!中国海洋大学计算机专硕
  2. Ftp下载文件超时处理
  3. 《Web安全之机器学习入门》笔记:第九章 9.4 支持向量机算法SVM 检测DGA域名
  4. 人工神经网络与神经网络,对人工神经网络的理解
  5. C# 待用户确认对话框(确定/取消)
  6. 我,大专毕业2年,从前端转型大数据开发,薪资涨了10K!
  7. 如何查看、复制caj、PDF文件文本内容
  8. QN8035 FM收音机芯片 驱动程序
  9. SAP FICO 如何看一个总账科目的修改记录?
  10. Facade 门面 —— Mediator 调停者