跳轉到內容

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)
華夏公益教科書