跳转到内容

Wikijunior:树莓派/树莓派温度传感器

来自 Wikibooks,开放世界的开放书籍

Andrew Oakley 的教程
公有领域 2016 年 7 月 2 日
www.cotswoldjam.org

本教程将向您展示如何制作一个温度传感器,当温度过高时发出红色光,当温度过低时发出蓝色光。

Words you will see on the screen, or that you need to type in, are highlighted like this.

在每行结尾处,按 ↵ Enter

您的导师应该已经为您准备好了树莓派,并提供了一个包含组件的袋子。或者,您可以从以下网址下载文件:http://cotswoldjam.org/tutorials

电子元件

[编辑 | 编辑源代码]

温度传感器

[编辑 | 编辑源代码]

DS18B20 防水温度传感器。它的一端有三个引线,另一端有一个金属传感器。此版本防水,传感器可以浸入水中。还提供了一种更小、更便宜的非防水版本。

面包板

[编辑 | 编辑源代码]

迷你面包板。它有上下两部分。每个部分中每列的所有点都连接在一起,因此我们可以进行电气连接。

三个电阻。检查色带 – 两个相同的电阻为 220 欧姆(红红棕),另一个(带蓝色条纹)为 4700 欧姆。欧姆数越高,对电流的阻力越大。电阻可以以任何方向放置。

发光二极管(LED)

[编辑 | 编辑源代码]

红色和蓝色 LED。短引线是负极。灯泡边缘还有一个扁平面;这也会指示哪一侧是负极。LED 还需要一个小电阻来防止它们烧坏。我们将为每个 LED 使用一个 220 欧姆的电阻。

跳线。您应该有六根公对母跳线(一端是突出的,另一端是凹进的)和一根公对公跳线(两端都突出)。您的导线可能有许多不同的颜色。

将元件放置在面包板上,如下所示。

LED 的负极连接器(短引线,扁平面)在右侧,与 220 欧姆电阻位于同一列。

温度传感器有三个连接器

颜色用途位置
灰色(有时为绿色或黑色)负极或接地应位于左侧
黄色(有时为白色)数据应位于中间
红色(有时为棕色)正极应位于右侧

4700 欧姆电阻跨越温度传感器数据连接器(中间)和正极连接器(右侧)之间的列。

接下来,在温度传感器和树莓派的 GPIO 引脚之间连接三根公对母跳线。

  1. 接地(负极)连接到引脚 6 (GND)
  2. 数据(中间连接器)连接到引脚 7 (GPIO4)
  3. 3.3V(正极)连接到引脚 1

请注意,引脚编号(“板编号”)和 GPIO 编号(“BCM 编号” - Broadcom,处理器制造商)不同。

检查图表。

现在将 LED 和树莓派之间的跳线连接起来。

一根公对母跳线从蓝色 LED 的正极连接到引脚 16 (GPIO23)

另一根公对母跳线从红色 LED 的正极连接到引脚 18 (GPIO24)

一根公对公跳线跨越底部部分的电阻,最后,一根公对母跳线从底部部分的一个电阻连接到引脚 14 (GND)

配置树莓派以使用 1-Wire 传感器

[编辑 | 编辑源代码]

温度传感器使用 1-Wire 接口(正极和负极连接器,以及 1 个数据连接器)。我们需要打开 1-Wire。

从树莓派桌面,点击菜单 - 首选项 - 树莓派配置。

在配置程序中,点击顶部的接口选项卡。然后找到 1-Wire 行并点击启用。如果它已经启用,那就很好。如果它之前没有启用,系统会提示您重新启动机器 - 请确保重新启动。

第一个程序 – 读取温度

[编辑 | 编辑源代码]

从菜单中,选择编程 - Python 3。然后使用文件,新建窗口创建一个新程序并输入。或者,您可以使用文件,打开加载现成的程序,然后向侧面滚动并双击 python 文件夹,然后双击 temperature 文件夹,然后点击temp1.py并打开。

在输入程序时,请确保在行的开头放置所需的空格。例如,在temp=readtemp.readtemp()之前有两个空格。空格必须对齐。

import gpiozero, readtemp
from time import sleep

while True:
  temp=readtemp.readtemp()
  print ( "Temp: {}c".format(temp) )
  sleep(0.1)

通过选择“运行”菜单中的“运行模块”来运行程序。您应该会看到一些温度读数!尝试用手紧紧握住传感器来加热它。按住Ctrl键并按下C来停止程序。

import 教会计算机学习新事物,使用其他人编写的程序片段。我们用“库”这个词来描述它。gpiozero 是一个使 GPIO 引脚易于使用的库。readtemp 是一个使温度传感器易于使用的库。我们还从 time 库中导入 sleep 命令。

while True: 无限重复一个代码段(只要… 就一直执行!)

temp=readtemp.readtemp() 从传感器读取温度,并将摄氏度值存入名为 temp 的变量中。变量就像盒子,可以存放数字或文字。

print 将信息输出到屏幕上。在本例中,输出温度读数。

sleep 等待一段时间。我们在读数之间留出 0.1 秒的间隔。但是,读数也需要一段时间,因此循环不会运行得太快。

第二个程序 – 点亮 LED

[编辑 | 编辑源代码]

更改程序,或加载 temp2.py 文件。

import gpiozero, readtemp
from time import sleep

cold=22
hot=32
blueled=gpiozero.PWMLED(23)
redled=gpiozero.PWMLED(24)
blueled.on()
redled.on()

while True:
  temp=readtemp.readtemp()
  
  hotness=(temp-cold)/(hot-cold)
  if hotness>1:
    hotness=1
  if hotness<0:
    hotness=0
    
  print ( "Temp: {}c - Hotness {}".format(temp,hotness) )
  blueled.value=1-hotness
  redled.value=hotness
  sleep(0.1)

通过选择“运行”菜单中的“运行模块”来运行程序。红色和蓝色 LED 将根据温度改变亮度!使用CTRL+C 停止程序,并尝试更改 cold 和 hot 的值。体温约为 37°C(98.6°F),冰块为 0°C(32°F),典型室温为 22 摄氏度(71.6 华氏度)。

gpiozero.PWMLED 告诉计算机我们连接了一个 LED,并且我们将使用脉冲宽度调制(PWM)来改变其亮度——以非常快的速度使其闪烁!

我们根据温度在冷和热之间设置亮度级别(热度)。

如果温度等于或高于热,则只有红色亮起(热度设置为 1)。如果温度等于或低于冷,则只有蓝色亮起(热度设置为 0)。如果温度介于两者之间,则蓝色和红色的亮度将根据温度变暗或变亮——这就是数学运算,即(temp-cold)除以(hot-cold)。尝试用铅笔或计算器计算一下!

因此,热度始终是介于 0(冷)和 1(热)之间的十进制数。我们对蓝色 LED 使用了一个巧妙的数学技巧来获得亮度的“反向”;1 减去热度。当热度为 0.8 时,蓝色 LED 的亮度为:1 − 0.8 = 0.2

高级程序员

[编辑 | 编辑源代码]

查看 readtemp.py 库以了解我们如何从温度传感器获取读数。找到文件 /sys/bus/w1/devices/28-something/w1_slave 并使用 cat 命令从终端输出读数。

修改 readtemp.py 库的代码以使用华氏度而不是摄氏度。

Cjam-temperature-tutorial.pdf

[编辑 | 编辑源代码]

本教程的原始 PDF 文件位于维基共享资源:Cjam-temperature-tutorial.pdf

readtemp.py

[编辑 | 编辑源代码]
# readtemp
# by Andrew Oakley 2016-07 Public Domain www.aoakley.com
# A module to read the temperature in Celcius from a DS18B20 thermometer
# connected via the 1-Wire interface on a Raspberry Pi
# You must enable dtoverlay=w1-gpio in /boot/config.txt
# or enable 1-Wire interface in Preferences - Raspberry Pi Configuration
# Default pin is GPIO4
# Connect ground & 3.3V, then connect data wire to GPIO4

import glob
from time import sleep

# Initialise the private global variable
_readtemp_device_file=""

# Find the thermometer file
def readtemp_init():
  global _readtemp_device_file
  base_dir = '/sys/bus/w1/devices/'
  glob_folder=glob.glob(base_dir + '28*')
  if len(glob_folder)<1:
    raise Exception("Cannot find DS18B20 thermometer")
  else:
    device_folder = glob_folder[0]
    _readtemp_device_file = device_folder + '/w1_slave'

# Read all the data from the thermometer
def _readtemp_raw():
  global _readtemp_device_file
  f = open(_readtemp_device_file, 'r')
  lines = f.readlines()
  f.close()
  return lines

# Extract the Celcius value from the thermometer data
def readtemp():
  if _readtemp_device_file == "":
    readtemp_init()

  lines = _readtemp_raw()
  tries = 0
  while lines[0].strip()[-3:] != 'YES' and tries<10:
    sleep(0.2)
    lines = _readtemp_raw()
    tries = tries+1
  if tries<10:
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
      temp_string = lines[1][equals_pos+2:]
      temp_c = float(temp_string) / 1000.0
      return temp_c
  else:
    raise Exception("Cannot get reading from DS18B20 thermometer")
import gpiozero, readtemp
from time import sleep

while True:
  temp=readtemp.readtemp()

  print ( "Temp: {}c".format(temp) )

  sleep(0.1)
import gpiozero, readtemp
from time import sleep

# Minimum and maximum temperatures
# Try changing these!
cold=22
hot=32

# Which pins are the LEDs connected to?
blueled=gpiozero.PWMLED(23)
redled=gpiozero.PWMLED(24)

# Turn on the LEDs
blueled.on()
redled.on()

while True:
  # Find the temperature
  temp=readtemp.readtemp()

  # Calculate a value between 0 and 1 representing hotness
  hotness=(temp-cold)/(hot-cold)
  if hotness>1:
    hotness=1
  if hotness<0:
    hotness=0
  print ( "Temp: {}c - Hotness {}".format(temp,hotness) )

  # Set the brightness of the LEDs
  blueled.value=1-hotness
  redled.value=hotness

  sleep(0.1)
华夏公益教科书