Raspberry Pi 树莓派连接温度传感器DS18B20
来源:互联网 发布:vmware ubuntu 安装 编辑:程序博客网 时间:2024/06/10 16:56
来源:http://www.waveshare.net/study/article-607-1.html
DS18B20是一个比较常用的温度传感器,采用单总线控制,以前用单片机编程控制时严格按照单总线的时序控制,今天来看看在linux系统下如何控制DS18B20,体验一下在linux世界,一切都是文件。
一、修改配置文件
1
sudo vi /boot/config.txt
(注:运行sudo raspi-config实际上也是修改这个文件,例如设置Advanced Options -> I2C 启动i2C内核驱动,就是修个dtparam=i2c_arm=on 这一行)
在/boot/config.txt文件后面添加下面这一句,这一句就是树莓派添加Device Tree设备,dtoverlay=w1-gpio-pull表示添加单总线设备,gpioin=4默认管脚为4,如果DS18B20接到其他管脚则需要修改这个值,Pioneer 600扩展板DS18B20默认接到4,故不用修改。(注:管脚为BCM编号)
1
dtoverlay=w1-gpio-pull,gpioin=4
在/boot/overlays/README中有关于树莓派Device Tree的详细介绍,在其中我们找到下面关于w1-gpio-pullup设备的介绍如下图。
二、查看模块是否启动
重启树莓派是设置生效,运行lsmod命令,如果发现红色方框的两个模块说明模块已启动。
如果没有发现,也可以运行如下命令加载模块
1
sudo modprobe w1_gpio
2
sudo modprobe w1_therm
三、 读取温度
如果没有问题,在/sys/bus/w1/devices中发现一个28-XXXX开头的文件夹,这个就是DS18B20的ROM,每个DS18B20都一样,在这个文件夹中读取w1_slave文件则会返回当前温度值。操作如下图:
1
sudo modprobe w1-gpio
2
sudo modprobe w1-therm
3
cd /sys/bus/w1/devices
4
cd 28-00000xxx
5
cat w1_slave
返回数据中,第一行最后的YRS表示CRC校验成功,数据有效。第二行最后t=30500表示当前温度为30.5摄氏度。
如果接多个DS18B20,将会看到多个28-xxxx的文件,分别对应各个DS18B20。
四、软件编程
1、sysfs
01
#
include
<stdio.h>
02
#
include
<stdlib.h>
03
#
include
<unistd.h>
04
#
include
<fcntl.h>
05
#
include
<dirent.h>
06
#
include
<string.h>
07
#
include
<time.h>
08
09
int main(int argc, char *argv[])
10
{
11
char path[50] =
"/sys/bus/w1/devices/"
;
12
char rom[20];
13
char buf[100];
14
DIR *dirp;
15
struct dirent *direntp;
16
int fd =-1;
17
char *temp;
18
float value;
19
20
system(
"sudo modprobe w1-gpio"
);
21
system(
"sudo modprobe w1-therm"
);
22
if
((dirp = opendir(path)) == NULL)
23
{
24
printf(
"opendir error\n"
);
25
return
1;
26
}
27
28
while
((direntp = readdir(dirp)) != NULL)
29
{
30
if
(
strstr
(direntp->d_name,
"28-00000"
))
31
{
32
strcpy(rom,direntp->d_name);
33
printf(
" rom: %s\n"
,rom);
34
}
35
}
36
closedir
(dirp);
37
38
strcat(path,rom);
39
strcat(path,
"/w1_slave"
);
40
while
(1)
41
{
42
if
((fd = open(path,O_RDONLY)) < 0)
43
{
44
printf(
"open error\n"
);
45
return
1;
46
}
47
48
if
(read(fd,buf,sizeof(buf)) < 0)
49
{
50
printf(
"read error\n"
);
51
return
1;
52
}
53
54
temp =
strchr
(buf,
't'
);
55
sscanf(temp,
"t=%s"
,temp);
56
value = atof(temp)/1000;
57
printf(
" temp : %3.3f °C\n"
,value);
58
59
sleep(1);
60
}
61
return
0;
62
}
编译并执行,结果如图
1
gcc –Wall ds18b20.c –o ds18b20
2
sudo ds18b20
注:(1)system("sudo modprobe w1-gpio");system("sudo modprobe w1-therm");在程序的开头运行了一下modprobe命令
(2) dirp = opendir(path) 打开/sys/bus/w1/devices/文件路径
(3)direntp = readdir(dirp) 读取当前路径下的文件或文件夹
(4)strstr(direntp->d_name,"28-00000")
查找28-00000开头的文件,strstr为字符串操作函数,上面这条语句表示文件名字是否包含字符串“28-00000”,如果匹配则返回第一次匹配的地址,没有搜索到则返回NULL.
(5)strcpy(rom,direntp->d_name); strcpy为字符串复制函数。,将包含28-00000的文件名复制到rom字符串
(6)strcat(path,rom);strcat(path,"/w1_slave"); strcat为字符串连接函数,此时path的值为/sys/bus/w1/devices/28-00000xxxx/w1_slave
(7)fd = open(path,O_RDONLY); read(fd,buf,sizeof(buf)) 打开文件并读取数据
(8)temp = strchr(buf,'t'); 查找字符‘t’第一次出现的位置,
(9)sscanf(temp,"t=%s",temp); sscanf函数是从一个字符串中读进与指定格式相符的数据,此处为从第二行数据中扫描出温度值
(10) value = atof(temp)/1000; atof函数把字符串转化为浮点数。
2、python
01
import os
02
import
glob
03
import time
04
05
os.system(
'modprobe w1-gpio'
)
06
os.system(
'modprobe w1-therm'
)
07
08
base_dir =
'/sys/bus/w1/devices/'
09
device_folder =
glob
.
glob
(base_dir +
'28*'
)[0]
10
device_file = device_folder +
'/w1_slave'
11
def read_rom():
12
name_file=device_folder+
'/name'
13
f = open(name_file,
'r'
)
14
return
f.readline()
15
16
def read_temp_raw():
17
f = open(device_file,
'r'
)
18
lines = f.readlines()
19
f.close()
20
return
lines
21
22
def read_temp():
23
lines = read_temp_raw()
24
while
lines[0].strip()[-3:] !=
'YES'
:
25
time.sleep(0.2)
26
lines = read_temp_raw()
27
equals_pos = lines[1].find(
't='
)
28
if
equals_pos != -1:
29
temp_string = lines[1][equals_pos+2:]
30
temp_c = float(temp_string) / 1000.0
31
temp_f = temp_c * 9.0 / 5.0 + 32.0
32
return
temp_c, temp_f
33
34
print(
' rom: '
+ read_rom())
35
while
True:
36
print(
' C=%3.3f F=%3.3f'
% read_temp())
37
time.sleep(1)
运行程序,运行结果如图
1
sudo python ds18b20.py
注:(1)程序的开头运行了一下modprobe命令
(2) device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
定义设备文件夹和设备文件,glob.glob(base_dir + '28*'))函数为获得base_dir路径下所有28开头的文件。
(3)while lines[0].strip()[-3:] != 'YES': 判断w1-value第一行的最后三个字符是否为‘YES‘
(4)equals_pos = lines[1].find('t=') 查找第二行中‘t=’出现的位置
(5) temp_string = lines[1][equals_pos+2:] 取温度数据
总结:对比上面两个两个程序,我们可以发现python程序更加简单方便。
- Raspberry Pi 树莓派连接温度传感器DS18B20
- tq2440连接到温度传感器DS18B20
- Raspberry Pi: SSH连接Raspberry Pi
- ds18b20温度传感器
- DS18B20温度传感器
- ds18b20温度传感器
- 温度传感器 DS18B20
- 安装树莓派 Raspberry PI
- Raspberry Pi 树莓派入门
- Raspberry Pi 树莓派入门
- 树莓派 Raspberry Pi
- Raspberry Pi 树莓派
- Raspberry Pi 树莓派
- Raspberry Pi 树莓派入门
- 树莓派(Raspberry Pi 3)
- 树莓派(Raspberry Pi 3)
- 树莓派(Raspberry Pi 3)
- 树莓派(Raspberry Pi 3)
- es6 let和const
- hdu 4638 离线+树状数组
- Eclipse的Servers视图中无法添加Tomcat6/Tomcat7
- 23种设计模式-Abstract Factory(抽象工厂)设计模式
- Java常见面试题及答案 21-30(集合类)
- Raspberry Pi 树莓派连接温度传感器DS18B20
- 0005_Longest Palindromic Substring
- Qt精彩实例3
- JS之document
- 内存分配机制
- shiro与app利用token进行交互的解决方案
- 算法导论 练习题 4.4-5
- android代码 获取本次通话时间
- html中解决div不定宽度设置水平居中的方案