Linux服务器下基于树莓派+DS18b20的温度的实时获取

目录

树莓派

DS18B20

项目实现的简单介绍

代码示例

基本API介绍及其详解

运行结果


 


  • 树莓派

Raspberry Pi(中文名为“树莓派”,简写为RPi,(或者RasPi / RPI) [1]  是为学习计算机编程教育而设计),只有信用卡大小的微型电脑,其系统基于Linux。  随着Windows 10 IoT的发布,我们也将可以用上运行Windows的树莓派。 自问世以来,受众多计算机发烧友和创客的追捧,曾经一“派”难求。别看其外表“娇小”,内“心”却很强大,视频、音频等功能通通皆有,可谓是“麻雀虽小,五脏俱全”。

  • DS18B20

DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。 [1]  DS18B20数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有LTM8877,LTM8874等等。

主要根据应用场合的不同而改变其外观。封装后的DS18B20可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。

  • 项目实现的简单介绍

  1. 由于DS18B20是遵循单线协议(oneline), 1-wire 单总线是Maxim 全资子公司 Dallas 的一项专有技术。与目前多数标准串行数据通信方式,如SPI/I2C/MICROWIRE 不同,它采用单根信号线,既传输时钟,又传输数据,而且数据传输是双向的。它具有节省 I/O 口线资源、结构简单、成本低廉、便于总线扩展和维护等诸多优点。1-wire 单总线适用于单个主机系统,能够控制一个或多个从机设备。当只有一个从机位于总线上时,系统可按照单节点系统操作;而当多个从机位于总线上时,则系统按照多节点系统操作。

  2. 为什么我们要用文件I/O来实现温度获取呢???

因为DS18B0会把他获取到的温度数据存放在一个文件中,而且DS18B20会有一个专门的产品序列号,类似于我们的身份证号,所以我们会用strstr函数来查找这个唯一的序列号,也就找到唯一的文件例如:strstr(direntp->d_name,"28-")。

废话不多说,先撸代码

  • 代码示例

#ifndef   __DS18B20_H__
#define   __DS18B20_H__
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <stdlib.h>
#define	BUF_SIZE      1024
#define	CHIP_SIZE     100

#define	DIR_PATH_SIZE 100

#endif

int ds18b20_get_temperature(float *tmp);//基于DS18B20温度获取实现函数

int main (int argc, char **argv)
{
    float        value;

    if((ds18b20_get_temperature(&value))<0)
    {
	    printf("Get temperature failure: %s\n",strerror(errno));
    }
    printf("T = %.2f\n",value);
    return 0;
} 

int ds18b20_get_temperature(float *tmp)
{
    if(tmp == NULL)
    {
	    printf("Failure : %s",strerror(errno));
	    return 0;
    }
    int             fd = -1;
    int             rv =  0;
    char            buf[BUF_SIZE];
    char            chip[CHIP_SIZE];
    char            DIR_PATH[DIR_PATH_SIZE] ="/sys/bus/w1/devices/";  //DS18B20的温度实时存储文件
    char            *ptr = NULL;
    int             find = 0;
    DIR             *dirp = NULL;
    struct dirent   *direntp = NULL;
    if((dirp = opendir(DIR_PATH))==NULL)
    {
        printf("Open %s failure %s\n\a",DIR_PATH,strerror(errno));
        return -1;
    }
    while((direntp= readdir(dirp))!=NULL)
    {
        if(strstr(direntp->d_name,"28-"))  //查找字串
        {
            memset(chip,0,sizeof(chip));
            strncpy(chip,direntp->d_name,sizeof(chip));
            find = 1;
            break;
        }
    }
    if(!find)
    {
        puts("No such devices\a");
        goto cleanup;
        return -2;
    }

    closedir(dirp);

    strncat(DIR_PATH,chip,sizeof(DIR_PATH)); 
    strncat(DIR_PATH,"/w1_slave",sizeof(DIR_PATH));

    if((fd = open(DIR_PATH,O_RDONLY))<0)
    {
        printf("open %s failure %s\a\n",DIR_PATH,strerror(errno));
        goto cleanup;
        return -3;
    }
    memset(buf,0,sizeof(buf));
    lseek(fd,0,SEEK_SET);
    if((rv = read(fd,buf,sizeof(buf)))<0)
    {
        printf("Read %s failure %s\n\a",DIR_PATH,strerror(errno));
        goto cleanup;
        return -4;
    }
    ptr = strstr(buf,"t=")+2;
    if(!ptr)
    {
        puts("Gte value failure\a\n");
        return -5;
    }
    *tmp = atof(ptr)/1000;  //字符串转化位float的数据
cleanup:
    close(fd);


}
  • 基本API介绍及其详解

  1. oepndir( )
    #include <sys/types.h>
    #include <dirent.h>
    DIR *opendir(const char *name);  //打开指定的文件目录
  2. readdir( )
    #include <dirent.h>
    struct dirent *readdir(DIR *dirp);  //read open 函数打开的目录文件
    
  3. strstr( )
    #include <string.h>
    char *strstr(const char *haystack, const char *needle); 在haystack从查找needle的子串
  4. strcpy()
    #include <string.h>
    void *memset(void *s, int c, size_t n);  //将s的这段内存初始化位c值,我们一般把c值设为,最后n位这段内存的大小
  5. strncpy/strcpy

    #include <string.h>
    char *strcpy(char *dest, const char *src); //这个函数一般不安全,容易导致内存溢出
    char *strncpy(char *dest, const char *src, size_t n); //这个函数有最后的字节数限制,不会导致内存溢出,
  6. closedir
    #include <sys/types.h>
    #include <dirent.h>
    int closedir(DIR *dirp); //关闭打开的文件句柄
  7. strncat

    #include <string.h>
    
    char *strcat(char *dest, const char *src);  //同样这个函数也不安全,存在内存溢出的问题
    char *strncat(char *dest, const char *src, size_t n);//将dest连接在src之后,n的大小回限制内存溢出的问题
    
  8. atof

    #include <stdlib.h>
    double atof(const char *nptr); //将字符串转化为float
    
  9. 至于一些其他的进本系统调用函数大家可以看看我的这篇文章(https://blog.csdn.net/qq_44045338/article/details/104587274),我就不一一例举了。

  • 运行结果

     
发布了47 篇原创文章 · 获赞 37 · 访问量 3700

猜你喜欢

转载自blog.csdn.net/qq_44045338/article/details/104868895