【C语言】树莓派(Raspberry Pi)+DS18B20 获取当前温度_(1)在raspbian中,使用c语言程序获取到树莓派cpu的温度值 ①方法参考 树莓派 rasp

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

在开始之前,要使能树莓派内核的单总线协议驱动模块(1-Wire)
具体操作如下

sudo raspi-config

在这里插入图片描述
在这里插入图片描述
单总线的接口默认是GPIO 4(BCM),使用默认接口的话可以忽略下面更换引脚的操作
若想更换自己选择的端口,则需要在 /boot/config.txt 文件的最后那行中加上 “,gpiopin=你想要的端口”。

vim /boot/config.txt

在最后一行添加以下内容,这里的 gpiopin = 4 是采用BCM GPIO的标准。
如果是模块化的DS18B20,则添加以下内容【因为模块中已包含上拉电阻】

dtoverlay=w1-gpio, gpiopin=4

如果是单独的一个DS18B20芯片【也就是普通直插三极管的样子】

dtoverlay=w1-gpio-pullup, gpiopin=4

在这里插入图片描述
最后重启系统

sudo reboot

确认系统有自动加载单总线协议的驱动模块:

lsmod | grep w1

以下为正常加载
在这里插入图片描述

二、实现过程

配置好单总线的驱动协议模块后,将DS18B20接上树莓派

Raspberry PiDS18B20
3.3VVCC
GNDGND
4 (BCM)DQ

接上树莓派后,可以在 /sys/bus/w1/devices/ 目录下找到一个28-xxxxxx的文件夹(xxxxxxx为该DS18B20芯片的序列号)
该文件夹存放 DS18B20 的数据信息
DS18B20测量的温度数据存放在该文件夹的 w1_slave 文件中。
在这里插入图片描述
从图中看出,这时DS18B20测量的温度值为 31.562 ℃

1、找该DS18B20芯片的设备文件夹

  • ①、打开 “/sys/bus/w1/devices/” 这个文件夹,并让dirp指向该文件夹
  • ②、从该文件夹中,逐个找 “ 文件名中包含有 28- 的文件 ”
  • ③、找到则将文件夹名复制给字符数组 dir_name
  • ③、找不到则报错,退出函数
char 			 path[50] = "/sys/bus/w1/devices/";

//打开文件夹"/sys/bus/w1/devices/"
if ((dirp = opendir(path)) == NULL)
{
	printf("ERROR: Open Directory '%s' Failure: %s\n", path, strerror(errno));
	return -1;
}
printf("Open Directory '%s' Successfully\n", path);

//在文件夹中找DS18B20的文件夹28-xx
while ((direntp = readdir(dirp)) != NULL)
{
	if (strstr(direntp->d_name, "28-") != NULL)
	{
		strncpy(dir_name, direntp->d_name, strlen(direntp->d_name));
		printf("Find file: %s\n", dir_name);
		found = 1;
		break;
	}
}
closedir(dirp);

//找不到该文件夹
if (found == -1)
{
	printf("ERROR: Can not find DS18B20 in %s\n", path);
	return -2;
}

2、拼接文件夹和文件名到path中

  • ①、拼接文件夹和文件名到path中,得到一个完整的文件路径【绝对路径】
  • /sys/bus/w1/devices/28-3c01e0761972/w1_slave
//将文件夹名和文件名分别拼接到path上 
strncat(path, dir_name, strlen(dir_name));
strncat(path, "/w1\_slave", sizeof(path)-strlen(path));

3、打开w1_slave文件

  • ①、上一步骤得到 w1_slave 文件的绝对路径后,便可使用系统调用函数 open() 直接打开文件w1_slave
  • ②、因为只需要读该文件中的内容,所以我们以只读的形式(O_RDONLY)打开即可
  • ③、打开成功后,便会返回一个指向该文件的文件描述符fd
  • 在运行最终代码的时候,会看到 fd=3 ,是因为
  • 操作系统默认会打开 0、1、2 这三个文件描述符
  • 0:标准输入【默认是键盘】
  • 1:标准输出【默认是屏幕】
  • 2:标准出错【默认是屏幕】
  • 而新建的文件描述符 fd,是当前可用的文件描述符中最小的非负整数,所以这里的 fd 为 3
//打开w1\_slave文件
if ((fd = open(path, O_RDONLY)) < 0)
{
	printf("ERROR: Open file '%s' Failure: %s\n", path, strerror(errno));
	return -3;
}
printf("Open file '%s' fd[%d] Successfully\n", path, fd);

4、读w1_slave文件

  • ①、使用系统调用函数 read() 将 fd 所指向的文件的内容读到 buf 中,一次读 sizeof(buf) 字节大小
//从w1\_slave中读取内容
if ((rv = read(fd, buf, sizeof(buf))) < 0)
{
	printf("ERROR: Read data from file '%s' Failure: %s\n", path, strerror(errno));
	rv = -4;
	goto cleanup;
}
printf("Read %dB data from file '%s'\n", rv, path);

5、匹配数据并计算、赋值

  • ①、从 buf 中匹配 “t=”这个字符串,这时 strstr() 返回的是 “t” 所存放的地址
  • ②、要想最终获得的地址是数据的地址,则需要将该地址向右移 2 位,这时的地址就是数据的首地址
  • ③、这时候的数据还是字符串形式,我们使用 atof() 函数将数据转为double型,并/1000,即可得到正确的温度值了
//从buf里匹配"t=",并将ptr移到数据的首地址上
if ((ptr= strstr(buf, "t=") + 2) == NULL)
{
	printf("ERROR: Find data Failure: %s", strerror(errno));
	rv = -5;
	goto cleanup;
}

//将数据转为double型,除1000得到正常的十进制温度
\*temp = atof(ptr)/1000;

三、具体代码

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int Get\_DS18B20\_Temp(double \*temp);

/\*
 \* The main function
 \*/
int main(int argc, char \*\*argv)
{
	double	temp;
	
	if (Get\_DS18B20\_Temp(&temp) < 0)
	{
		printf("ERROR: DS18B20 Get Temperature Failure\n");


![img](https://img-blog.csdnimg.cn/img_convert/efeff059a672728a46b6a7bd74d67799.png)
![img](https://img-blog.csdnimg.cn/img_convert/45188b32abe21a4f5cd6aa69596fb32e.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**


[外链图片转存中...(img-0qijtIAy-1715689398602)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

  • 19
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
来实现该功能的程序该怎么写? 答:你可以尝试使用以下代码来实现此功能: ``` #include <stdio.h> #include <stdlib.h> #include <wiringPi.h> #include <linux/spi/spidev.h> #include <unistd.h> #include <stdint.h> #define MAXTIMINGS 85 #define DHTPIN 7 int dht11_dat[5] = { 0, 0, 0, 0, 0 }; void read_dht11_dat() { uint8_t laststate = HIGH; uint8_t counter = 0; uint8_t j = 0, i; dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0; pinMode(DHTPIN, OUTPUT); digitalWrite(DHTPIN, LOW); delay(18); digitalWrite(DHTPIN, HIGH); delayMicroseconds(40); pinMode(DHTPIN, INPUT); for (i = 0; i < MAXTIMINGS; i++) { counter = 0; while (digitalRead(DHTPIN) == laststate) { counter++; delayMicroseconds(1); if (counter == 255) { break; } } laststate = digitalRead(DHTPIN); if (counter == 255) { break; } if ((i >= 4) && (i % 2 == 0)) { dht11_dat[j / 8] <<= 1; if (counter > 16) { dht11_dat[j / 8] |= 1; } j++; } } if ((j >= 40) && (dht11_dat[4] == ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF))) { float temp = ((float)dht11_dat[2] * 9.0 / 5.0) + 32.0; printf("Temperature: %.1f F\n", temp); } else { printf("Data not good, skip\n"); } } int main(void) { if (wiringPiSetup() == -1){ exit(1); } printf("Raspberry Pi wiringPi DHT11 Temperature test program\n\n"); while (1) { read_dht11_dat(); delay(1000); } return 0; } ``` 在此代码,我们使用 DS18B20 温度传感器来读取温度,并将其转换为华氏温度。首先,我们需要读取传感器的数据。在 main 函数,我们使用了一个无限循环,每隔一秒钟读取一次温度传感器。在 read_dht11_dat 函数,我们使用WiringPi 库来设置传感器引脚模式和读取传感器数据。最后,我们计算温度并输出到终端。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值