[imx6ull]文件IO-温度传感器采样


又是我们一线协议(1-Wire)温度采样的老朋友DS18B20传感器,之前在单片机和树莓派当中我们都有用到,这次我们通过IGKBoard来进行温度采样。

一、 DS18b20传感器介绍

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

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

二、DS18B20硬件连接

1.DS18B20引脚

DS18B20主要连接时三个引脚:

  • GND:接地引脚需要连接到GND扩展引脚上。
  • DQ:DQ为DS18B20的数据通信引脚,需要连接在具有一线协议的GPIO引脚上。
  • VDD:因为DS18B20传感器的工作电压为3~5.5V,所以改引脚连到3.3V或5V供电引脚上。
    在这里插入图片描述

2.连接开发板

在IGKBoard开发板上的引脚中,物理引脚 #7 (GPIO1_IO18) 在Linux系统启动时如果启用了 w1 overlay 后,它将会默认作为 DS18B20 传感器的一线协议接口使用。

在这里插入图片描述

所以可以如下这样连接:
在这里插入图片描述
注意:忽略掉我的那根红色杜邦线

三、驱动配置

首先,因为我们的DQ引脚连接在了IGKBoard开发板扩展接口的#7引脚上,而我们所需用着个引脚来做DS18B20的一线协议支持,所以我们需要修改对应的config配置文件:

cd /run/media/mmcblk1p1

vi config.txt

注意:如果没有config.txt文件则自己新建

添加如下:

# Enable extra overlays
dtoverlay_extra=w1

如果已有则dtoverlay_extra直接在后面添加,用空格隔开。

重启后可用如下命令来查看驱动是否已经成功加载:

dmesg | grep 1-wire

在这里插入图片描述

四、源代码与运行测试

首先我们需要知道如何去获取我们的温度值,在我们的/sys/bus/w1/devices/下可以找到我们的DS18B20温度传感器相关文件如下:

root@igkboard:~# cd /sys/bus/w1/devices/
root@igkboard:/sys/bus/w1/devices# ls
28-082250269950  w1_bus_master1

082250269950为DS18B20芯片的产品序列号,温度就在/sys/bus/w1/devices/28-082250269950/w1_slave中,所以我们写一个程序ds18b20.c来获取温度。

源代码:ds18b20.c

/*********************************************************************************
 *      Copyright:  (C) 2023 Deng Yonghao<dengyonghao2001@163.com>
 *                  All rights reserved.
 *
 *       Filename:  ds18b20.c
 *    Description:  This file IGKBoard use DS18B20 to get temperature.
 *                 
 *        Version:  1.0.0(2023年03月13日)
 *         Author:  Deng Yonghao <dengyonghao2001@163.com>
 *      ChangeLog:  1, Release initial version on "2023年03月13日 21时48分32秒"
 *                 
 ********************************************************************************/

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

int ds18b20_get_temperature(float *temp);

int main(int argc, char **argv)
{
	float		temp;//温度值有小数位用浮点型
	int			rv;

	rv = ds18b20_get_temperature(&temp);
	if(rv<0)
	{
		printf("ERROR: de18b20 get temperature failure, return value: %d", rv);
		return -1;
	}
	/*由于℃是非ASCII打印字符,所以用'C代替*/
	printf("ds18b20 get temperature: %f 'C\n", temp);

	return 0;
}

int ds18b20_get_temperature(float *temp)
{
	int				fd = -1;//open()打开文件的文件描述符
	int             found = 0;//是否找到DS18B20的标志,默认为0
	int             rv = 0;//函数返回值,默认设置为0表示成功返回
	
	char            chip_sn[32];//DS18B20 芯片序列号文件名
	char			buf[128];//read()读数据存储buffer
	char			*ptr =NULL;//字符指针,用来字符串处理

	DIR				*dirp = NULL;//opendir()打开的文件夹句柄
	struct dirent	*direntp = NULL;//readdir()读文件夹内容时的目录项
	char		w1_path[64]="/sys/bus/w1/devices/";//一线协议设备的路径
	//const char      *w1_path[64]="/sys/bus/w1/devices/";//一线协议设备的路径


	/*进行函数参数的合法性检测,通过 $temp 传入一个空指针,下面的代码就有可能出现段错误*/
	if( !temp )
    {
        return -1;
    }

	/*打开 "/sys/bus/w1/devices/" 文件夹*/
	dirp=opendir(w1_path);
	if( !dirp )
	{
		printf("open floder %s failure: %s\n", w1_path, strerror(errno));
		return -2;
	}
	/*通过direntp->d_name寻找每个文件或文件夹,知道找到包含“28-”的文件,然后将文件名保存至chip_sn中,并将found设为1,然后跳出循环*/
	while( NULL != (direntp=readdir(dirp)) )
	{
		if( strstr(direntp->d_name, "28-"))
		{
			strncpy(chip_sn, direntp->d_name, sizeof(chip_sn));
			found = 1;
			break;
		}
	}
	
	/*文件夹打开用完后要关闭*/
	closedir(dirp);

	/*判断是否找到对应的文件*/
	if( !found )
	{
		printf("Can not find ds18b20 chipset in %s\n", w1_path);
		return -3;
	}

	/*合成完整路径:/sys/bus/w1/devices/28-xxxxx/w1_slave到w1_path中*/
	strncat(w1_path, chip_sn, sizeof(w1_path)-strlen(w1_path));
	strncat(w1_path, "/w1_slave", sizeof(w1_path)-strlen(w1_path));

	/*打开DS18B20采样文件*/
	if( (fd=open(w1_path, O_RDONLY)) < 0)
	{
		printf("open %s failure: %s\n", w1_path, strerror(errno));
		return -4;
	}

	/*清空buffer*/
	memset(buf, 0, sizeof(buf));
	
	/*读取文件中的内容将会触发DS18B20温度传感器采样,然后这里读取文件内容到buf中*/
	if(read(fd, buf, sizeof(buf)) < 0)
	{
		printf("read data from fd=%d failure %s\n", fd, strerror(errno));
		rv = -5;
		goto cleanup;
	}

	/*采样温度值是在字符串"t="后面,这里我们从buf中找到"t="字符串的位置并保存到ptr指针中*/
	ptr=strstr(buf, "t=");
	if( !ptr )
	{
		printf("ERROR: Can not find t= string\n");
		rv = -6;
		goto cleanup;
	}
	
	/*因为此时ptr是指向 "t="字符串的地址(即't'的地址),那跳过2个字节(t=)后面的就是采样温度值*/
	ptr += 2;

	*temp = atof(ptr)/1000;
	//printf("temperature: %f\n", *temp);

cleanup:
	close(fd);
	return rv;
}

我们通过交叉编译后下载到开发板中,如何赋予权限后运行测试如下:
在这里插入图片描述


总结

本章中我们通过DS18B20传感器来采样,并通过程序找到对应传感器通过一线协议采样的温度值,然后通过程序将获取的温度输出。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邓永豪

打赏一下,好运来敲门!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值