树莓派从零开始快速入门第8讲——单总线(以DS18B20为例)

树莓派从零开始快速入门第8讲——单总线(以DS18B20为例)

一、前言

单总线也叫做一线总线(one-write),它只有1根信号线,既传输时钟又传输数据,而且数据传输是双向的,通过一问一答的形式实现两个设备之间的数据交互。具体的原理我就不细说了,感兴趣的同学可以自己去查阅相关的资料,今天我以DS18B20为例,讲一下树莓派的单总线的使用方法。

二、硬件连接

DS18B20引脚定义如下,根据引脚定义连接到树莓派上,我这里用的是一个扩展板,直接把传感器接上即可。

引脚 名称 说明
1 GND 供电电源负极
2 DQ 数据输入输出引脚(和MCU任意一个IO口相连,注意:这里需要有上拉电阻)
3 VCC 供电电源正极

注意:如果你的传感器是插件封装的,一定要分清楚正负,不然会烧坏的。判断方法(仅供参考):平的一面对着自己,左边的是GND,右边的是VCC,中间的是信号线。接上之后可以迅速上电然后断电,摸一下传感器,如果迅速发热并且非常烫说明接反了。

三、使能1-write接口

方法1:通过配置命令

sudo raspi-config    // 打开配置
sudo reboot          // 重启,如果之前没有使能,配置完之后要重启才能生效

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

方法2:在可视化界面的设置里面修改
在这里插入图片描述
在这里插入图片描述
注意:如果设备启动的时候是没有使能1-Write接口的,使能之后需要重启才能生效。

四、通讯测试

sudo modprobe w1-gpio
sudo modprobe w1-therm
cd /sys/bus/w1/devices
ls                       // 查询传感器的ID,如果什么都没有,可能是前面没有使能1-Write,或者使能了但是没有重启,也可能是硬件连接有问题
cd 28-xxxxxxx            // 28-xxxxxxx:18b20的ID,每个传感器的id都是不同的,根据自己的输入,如果查询的ID里面不是28开头而是00开头的,那应该不是ds18b20
cat w1_slave

在这里插入图片描述
在这里插入图片描述

五、编写代码并运行

1、方式1

基于w1thermsensor库驱动DS18B20,w1thermsensor库集成了多款传感器的驱动(DS18S20、DS1822、DS18B20、DS28EA00、DS1825/MAX31850K)。
w1thermsensor Github 链接:https://github.com/timofurrer/w1thermsensor

示例代码:

from w1thermsensor import W1ThermSensor
sensor = W1ThermSensor(W1ThermSensor.THERM_SENSOR_DS18B20, "00000cb51493")  #00000cb51493:是ds18b20的id,根据自己的id输入(注意不要把“28-”也复制进来)
temp = sensor.get_temperature()
print(temp)

注:该代码基于w1thermsensor库驱动,使用w1thermsensor库之前先要安装这个库,命令如下:

sudo apt-get install python3-pip               // python3 pip安装管理器依赖包
sudo apt-get install python3-w1thermsensor     // w1thermsensor库

在这里插入图片描述
查询要读取的ds18b20的id。
可以通过第四步的通讯测试查,也可以用下面的命令查。

cd /etc
ls /sys/bus/w1/devices

在这里插入图片描述
示例代码1运行结果:
在这里插入图片描述

2、方式2

这个方法其实就是基于第四点的通讯测试,把手动输入的命令写在脚本上运行。
示例代码:

#!/usr/bin/python
# -*- coding:utf-8 -*-
import os
import glob
import time

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
def read_rom():
	name_file=device_folder+'/name'
	f = open(name_file,'r')
	return f.readline()

def read_temp_raw():
	f = open(device_file, 'r')
	lines = f.readlines()
	f.close()
	return lines

def read_temp():
	lines = read_temp_raw()
	while lines[0].strip()[-3:] != 'YES':
		time.sleep(0.2)
		lines = read_temp_raw()
	equals_pos = lines[1].find('t=')
	if equals_pos != -1:
		temp_string = lines[1][equals_pos+2:]
		temp_c = float(temp_string) / 1000.0
		temp_f = temp_c * 9.0 / 5.0 + 32.0
		return temp_c, temp_f

print(' rom: '+ read_rom())
while True:
	print(' C=%3.3f  F=%3.3f'% read_temp())
	time.sleep(1)

示例代码运行结果:
在这里插入图片描述

六、结束语

DS18B20是一款很简单的单总线传感器,我觉得以此为例去学习和了解单总线是一个非常好的选择。
关于树莓派和单片机的一些个人见解:
树莓派快速入门系列教程,刚刚进入基础编程的教学,为了避免大家进入思维的误区,在这里我想说说我对树莓派的一些看法。树莓派是一个微型的电脑,在运算能力方面是比单片机要强的,在编程上树莓派更偏向应用层的开发,也可以理解为电脑软件的开发。而单片机的话更多的是做底层外设驱动的开发,应用层主要也是以控制为主,不会说用单片机去做一个非常复杂的数据运算或者处理大量的数据。所以,树莓派的编程其实是有一点点脱离硬件的,就是我们可以不管底层的硬件是怎么实现数据采集和传输的,直接调用库函数,把数据拿到就行了,当然,有时间和精力的话是可以去研究一下硬件的原理和底层的实现。而单片机的开发很多时候会遇到一些没用过的芯片,我们就需要根据芯片的数据手册去开发一个驱动程序,然后再做应用层的开发,当然了,单片机也是可以跑操作系统的,比如FreeRTos、RT-thread等,跑操作系统的话和树莓派的编程就有些类似了,但毕竟跑系统的单片机还是少数。
总结起来就是一句话:树莓派编程能用库的就用库,底层怎么实现的不用管,我们是做大事的,不要花太多的时间在一些小事情上面。纯粹是个人的看法,勿喷,如果你有不同的见解,欢迎在评论区留言,谢谢!!!

好了,这一讲的内容就这么多了,如果对你有帮助,可以给个收藏,如果想了解更多树莓派的知识可以关注我,后续我会继续更新更多的教程。
树莓派入门系列教程:树莓派从零开始快速入门系列汇总

猜你喜欢

转载自blog.csdn.net/ShenZhen_zixian/article/details/119463320