本文介紹如何使用 Python 控制樹莓派與多種感測器互動,包含超音波、時間飛行 (ToF)、RFID 和溫度感測器。程式碼範例示範瞭如何讀取感測器資料,並利用 guizero 和 Tkinter 等 GUI 函式庫將資料顯示在螢幕上。此外,文章也說明如何將感測器資料記錄到 CSV 檔案中,方便後續分析。程式碼中使用了一些常見的 Python 函式庫,例如 RPi.GPIO、SimpleMFRC522 和 VL53L1X,讀者需要根據實際使用的感測器安裝對應的函式庫。文章也提到了如何設定樹莓派的 SPI 和 I2C 介面,以及如何連線感測器到樹莓派。

使用超音波和時間飛行感測器進行距離測量

距離測量是一種常見的應用,尤其是在機器人和自動化系統中。這裡,我們將介紹兩種距離測量方法:超音波感測器和時間飛行感測器。

超音波感測器

超音波感測器是一種使用高頻聲波來測量距離的裝置。它的工作原理是向物體發射高頻聲波,然後測量聲波反射回來的時間。根據聲波的速度和反射時間,可以計算出物體的距離。

以下是超音波感測器的工作流程:

  1. 觸發:Raspberry Pi 將 GPIO 輸出設定為高電平,觸發超音波感測器發射高頻聲波。
  2. 延遲:聲波發射後,會有一個短暫的延遲時間。
  3. 回聲:當聲波反射回來時,超音波感測器的回聲輸出會設定為高電平。
  4. 距離計算:根據聲波的速度和反射時間,可以計算出物體的距離。

超音波感測器的優點是低成本和易於使用,但是它的準確度受到溫度、壓力和相對濕度的影響。

時間飛行感測器

時間飛行感測器是一種使用光來測量距離的裝置。它的工作原理是向物體發射光束,然後測量光束反射回來的時間。根據光速和反射時間,可以計算出物體的距離。

以下是時間飛行感測器的工作流程:

  1. 發射:時間飛行感測器發射光束向物體。
  2. 反射:光束反射回來,時間飛行感測器測量反射時間。
  3. 距離計算:根據光速和反射時間,可以計算出物體的距離。

時間飛行感測器的優點是高準確度和不受環境因素影響,但是它的成本較高。

範例程式碼

以下是使用 Python 和 gpiozero 函式庫來控制超音波感測器的範例程式碼:

import gpiozero
from gpiozero import DistanceSensor

# 初始化超音波感測器
sensor = DistanceSensor(echo=17, trigger=23)

while True:
    # 讀取距離
    distance = sensor.distance * 100
    
    # 輸出距離
    print("Distance: {:.2f} cm".format(distance))

時間飛行感測器程式碼

  flowchart TD
    A[初始化] --> B[設定 I2C]
    B --> C[讀取距離]
    C --> D[輸出距離]

圖表翻譯:

上述流程圖描述了時間飛行感測器的工作流程。首先,初始化時間飛行感測器,然後設定 I2C 通訊協定。接下來,讀取距離並輸出結果。

使用ToF感測器進行距離測量

簡介

本文將介紹如何使用ToF(Time of Flight)感測器進行距離測量。ToF感測器是一種非接觸式距離測量技術,透過發射雷射脈衝並測量其反射回的時間來計算距離。

硬體需求

  • Pimoroni Breakout Garden系統或其他相容的ToF感測器
  • Raspberry Pi
  • 4條公母跳線

連線ToF感測器

  1. 將ToF感測器連線到Raspberry Pi的I2C介面。
  2. 如果使用Pimoroni Breakout Garden系統,請確保感測器正確地插入到系統中。
  3. 如果使用跳線,請按照以下連線方式:
    • VCC pin of the VL53L1X to 3V on the Raspberry Pi
    • GND pin of the VL53L1X to GND on the Raspberry Pi
    • SDA pin of the VL53L1X to GPIO 2 (SDA) on the Raspberry Pi
    • SCL pin of the VL53L1X to GPIO 3 (SCL) on the Raspberry Pi

啟用I2C和安裝軟體

  1. 啟用Raspberry Pi的I2C功能,按照Recipe 9.3進行。
  2. 安裝VL53L1X的軟體:
    • $ sudo pip3 install smbus2
    • $ sudo pip3 install vl53l1x

測試程式

以下是測試程式(ch_13_tof.py)的範例:

import VL53L1X, time

tof = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x29)
tof.open()
tof.start_ranging(1)  # Start range 1=Short 2=Medium 3=Long

while True:
    mm = tof.get_distance()  # Grab the range in mm
    print("mm=" + str(mm))
    time.sleep(1)

討論

VL53L1X ToF感測器是一種低功耗的紅外線雷射和接收器,透過I2C通訊協定進行距離測量。其工作原理與超音波距離測量類別似,但使用雷射脈衝代替超音波訊號。該感測器可以用於各種應用,包括機器人、自動駕駛等。

參考資料

  • Recipe 13.18:使用超音波進行距離測量
  • VL53L1X的資料表

使用Raspberry Pi的觸控介面

您想要為您的Raspberry Pi提供觸控介面。

解決方案

使用Adafruit Capacitive Touch HAT(圖13-27)。觸控感應器非常有趣,適合教育用途。您可以將任何導電物體連線到感應器,包括水果。一個流行的專案是使用鱷魚夾構建一個水果鍵盤,將各種水果和蔬菜連線到板上的感應端子。然後,當您觸控不同的水果時,會產生不同的聲音。

Adafruit Capacitive Touch HAT使用Raspberry Pi的I2C介面。您還需要安裝SPI工具,因此,如果您尚未安裝,請按照配方9.3和配方9.5進行安裝。

要安裝HAT的Python函式庫,請執行以下命令:

$ sudo pip3 install adafruit-circuitpython-mpr121

注意:第一次執行此命令時,我收到了錯誤訊息,但只需執行命令第二次即可正確安裝。

要測試觸控HAT,請執行以下程式(ch_13_touch.py):

import time
import board
import busio
import adafruit_mpr121

i2c = busio.I2C(board.SCL, board.SDA)
mpr121 = adafruit_mpr121.MPR121(i2c)

while True:
    if mpr121[0].value:
        print("Pin 0 touched!")

當您觸控標籤為0的觸控板時,您應該會看到以下輸出:

$ python3 ch_13_touch.py
Pin 0 touched!
Pin 0 touched!

您可以直接觸控連線板或使用鱷魚夾將板連線到一塊水果,如圖13-27所示。

討論

Adafruit Capacitive Touch HAT具有12個觸控接點。如果您只需要幾個觸控接點,您可以使用Pimoroni Explorer HAT Pro,它具有四個鱷魚夾相容接點(圖13-28)。

要使用Explorer HAT Pro的觸控接點,請先按照配方9.17安裝HAT的函式庫。

除了側面設計用於鱷魚夾的四個端子外,還有四個觸控開關,標籤為1到4,也使用觸控介面。

參考資料

更多資訊可在Adafruit Touch HAT檔案和Explorer HAT Pro檔案中找到。

圖表翻譯:

  flowchart TD
    A[開始] --> B[安裝SPI工具]
    B --> C[安裝Python函式庫]
    C --> D[執行測試程式]
    D --> E[觸控板輸出]

此圖表展示了使用Adafruit Capacitive Touch HAT的步驟,從安裝SPI工具到執行測試程式並獲得觸控板輸出。

使用RC-522 RFID讀寫器與Raspberry Pi進行RFID標籤讀取

所需材料

  • RC-522 RFID讀寫器
  • Raspberry Pi
  • 七條母對母跳線(見「原型設計裝置和套件」)
  • 可選:MonkMakes Clever Card Kit(包含RC-522讀寫器、RFID標籤、教學手冊等)

連線RC-522與Raspberry Pi

圖13-29顯示了RC-522與Raspberry Pi的連線。RC-522使用Raspberry Pi的SPI介面,因此需要按照食譜9.5進行設定。

表13-1列出了連線RC-522與Raspberry Pi所需的連線,包括建議的線色以便於識別。

線色RC-522引腳Raspberry Pi引腳
橙色SDAGPIO8
黃色SCKSCKL / GPIO11
白色MOSIMOSI / GPIO10
綠色MISOMISO/GPIO9
IRQ引腳未使用
藍色GNDGND
灰色RSTGPIO25
紅色3.3V3.3V

注意,雖然RC-522引腳上標有SDA和SCL,好像它使用I2C介面,但在這個食譜中,它使用Raspberry Pi的SPI介面。

安裝軟體

首先,下載Clever Card Kit軟體,並安裝所有必要的軟體:

$ chmod +x mmcck.sh
$./mmcck.sh

重新啟動Raspberry Pi後,進入clever_card_kit目錄,執行01_read.py程式:

$ cd clever_card_kit/
pi@raspberrypi:~/clever_card_kit $ python3 01_read.py

將RFID標籤靠近RC-522讀寫器,程式將印出標籤的唯一編號。

程式碼

以下是01_read.py程式的程式碼:

import RPi.GPIO as GPIO
import SimpleMFRC522

這個程式使用RPi.GPIO和SimpleMFRC522函式庫來控制RC-522讀寫器並讀取RFID標籤。

圖表翻譯:

此圖表顯示了RC-522與Raspberry Pi的連線。

  flowchart TD
    A[RC-522] --> B[Raspberry Pi]
    B --> C[SPI介面]
    C --> D[GPIO8]
    D --> E[GPIO11]
    E --> F[GPIO10]
    F --> G[GPIO9]
    G --> H[GND]
    H --> I[3.3V]

內容解密:

此程式使用RPi.GPIO函式庫來控制Raspberry Pi的GPIO引腳,並使用SimpleMFRC522函式庫來控制RC-522讀寫器。當RFID標籤靠近RC-522讀寫器時,程式將印出標籤的唯一編號。

RFID 標籤讀寫技術

RFID(Radio Frequency Identification)是一種無線通訊技術,能夠識別和追蹤標籤或物體。以下是使用 Python 和 SimpleMFRC522 函式庫來讀寫 RFID 標籤的範例。

安裝所需函式庫

首先,需要安裝 RPi.GPIO 和 SimpleMFRC522 函式庫。可以使用 pip 來安裝:

pip install RPi.GPIO SimpleMFRC522

讀取 RFID 標籤

以下是讀取 RFID 標籤的範例程式碼:

import RPi.GPIO as GPIO
import SimpleMFRC522

reader = SimpleMFRC522.SimpleMFRC522()

print("將 RFID 標籤靠近讀取器")
try:
    while True:
        id, text = reader.read()
        print("ID:", id)
        print("文字:", text)
finally:
    print("清理 GPIO 引腳")
    GPIO.cleanup()

這個程式碼會不斷地讀取 RFID 標籤的 ID 和文字,直到程式結束。

寫入 RFID 標籤

以下是寫入 RFID 標籤的範例程式碼:

import RPi.GPIO as GPIO
import SimpleMFRC522

reader = SimpleMFRC522.SimpleMFRC522()

print("輸入新文字:")
new_text = input()

try:
    while True:
        print("將 RFID 標籤靠近讀取器")
        id, text = reader.read()
        print("ID:", id)
        print("原文字:", text)
        reader.write(new_text)
        print("寫入成功")
        break
finally:
    print("清理 GPIO 引腳")
    GPIO.cleanup()

這個程式碼會提示使用者輸入新文字,然後將其寫入 RFID 標籤。

內容解密:

上述程式碼使用 SimpleMFRC522 函式庫來讀寫 RFID 標籤。SimpleMFRC522 函式庫提供了一個簡單的 API 來讀寫 RFID 標籤,包括 read()write() 方法。read() 方法會傳回 RFID 標籤的 ID 和文字,而 write() 方法會將新文字寫入 RFID 標籤。

圖表翻譯:

以下是 RFID 標籤讀寫流程的 Mermaid 圖表:

  flowchart TD
    A[開始] --> B[讀取 RFID 標籤]
    B --> C[取得 ID 和文字]
    C --> D[寫入新文字]
    D --> E[寫入成功]
    E --> F[結束]

這個圖表展示了 RFID 標籤讀寫的流程,包括讀取 RFID 標籤、取得 ID 和文字、寫入新文字和寫入成功。

顯示感測器數值

問題描述

您有一個感測器連線到您的樹莓派(Raspberry Pi),並希望在螢幕上顯示一個大型的數字顯示,顯示感測器的讀數。

解決方案

要解決這個問題,我們可以使用Python程式語言和相關的函式庫來讀取感測器的數值,並使用圖形化介面函式庫(如Tkinter)來顯示數值。

步驟1:安裝必要的函式庫

首先,您需要安裝必要的函式庫,包括tkinterRPi.GPIO。您可以使用以下命令安裝:

sudo apt-get install python3-tk
sudo apt-get install python3-rpi.gpio

步驟2:連線感測器

連線感測器到您的樹莓派。感測器的連線方式取決於感測器的型別和您的樹莓派的版本。

步驟3:讀取感測器數值

使用RPi.GPIO函式庫來讀取感測器的數值。以下是一個簡單的範例:

import RPi.GPIO as GPIO

# 設定GPIO模式
GPIO.setmode(GPIO.BCM)

# 設定感測器的GPIO腳位
sensor_pin = 17

# 讀取感測器的數值
def read_sensor():
    # 讀取感測器的數值
    value = GPIO.input(sensor_pin)
    return value

# 讀取感測器的數值
value = read_sensor()
print(value)

步驟4:顯示數值

使用tkinter函式庫來顯示數值。以下是一個簡單的範例:

import tkinter as tk

# 建立一個Tkinter視窗
root = tk.Tk()

# 建立一個標籤來顯示數值
label = tk.Label(root, text="Sensor Value: ", font=("Helvetica", 24))
label.pack()

# 更新標籤的文字
def update_label():
    value = read_sensor()
    label.config(text="Sensor Value: " + str(value))
    root.after(100, update_label)

# 啟動更新迴圈
update_label()

# 啟動Tkinter事件迴圈
root.mainloop()

完整程式碼

以下是完整的程式碼:

import RPi.GPIO as GPIO
import tkinter as tk

# 設定GPIO模式
GPIO.setmode(GPIO.BCM)

# 設定感測器的GPIO腳位
sensor_pin = 17

# 讀取感測器的數值
def read_sensor():
    # 讀取感測器的數值
    value = GPIO.input(sensor_pin)
    return value

# 建立一個Tkinter視窗
root = tk.Tk()

# 建立一個標籤來顯示數值
label = tk.Label(root, text="Sensor Value: ", font=("Helvetica", 24))
label.pack()

# 更新標籤的文字
def update_label():
    value = read_sensor()
    label.config(text="Sensor Value: " + str(value))
    root.after(100, update_label)

# 啟動更新迴圈
update_label()

# 啟動Tkinter事件迴圈
root.mainloop()

使用guizero函式庫顯示感測器資料

要將感測器資料顯示在視窗中,可以使用guizero函式庫。以下是使用guizero函式庫顯示ToF範圍儀資料的範例。

解決方案

首先,需要安裝guizero函式庫。如果尚未安裝,可以使用pip安裝:

pip install guizero

然後,建立一個新的Python指令碼,匯入必要的函式庫:

import VL53L1X
import time
from guizero import App, Text

初始化ToF範圍儀:

tof = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x29)
tof.open()
tof.start_ranging(1)

建立一個guizero應用程式:

app = App(width=300, height=150)

建立一個文字元件,用於顯示感測器資料:

reading_text = Text(app, size=100)

定義一個函式,用於更新感測器資料:

def update_reading():
    mm = tof.get_distance()
    reading_text.value = str(mm)

使用repeat方法,每隔1000毫秒更新一次感測器資料:

reading_text.repeat(1000, update_reading)

最後,啟動guizero應用程式:

app.display()

討論

這個範例使用ToF範圍儀,但也可以使用其他感測器。只要更改取得感測器資料的方法即可。

參考

關於格式化數字到小數點後的特定位數,請參考配方7.1。

關於在網頁瀏覽器中顯示感測器資料的範例,請參考配方16.2。

程式碼

以下是完整的程式碼:

import VL53L1X
import time
from guizero import App, Text

tof = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x29)
tof.open()
tof.start_ranging(1)

def update_reading():
    mm = tof.get_distance()
    reading_text.value = str(mm)

app = App(width=300, height=150)
reading_text = Text(app, size=100)
reading_text.repeat(1000, update_reading)
app.display()

內容解密:

  • VL53L1X 是一個 Python 函式庫,用於存取 ToF 範圍儀。
  • guizero 是一個 Python 函式庫,用於建立圖形使用者介面。
  • App 是 guizero 中的一個類別,用於建立一個應用程式視窗。
  • Text 是 guizero 中的一個類別,用於建立一個文字元件。
  • repeat 方法用於每隔一段時間執行一次指定的函式。
  • get_distance 方法用於取得 ToF 範圍儀的距離資料。

圖表翻譯:

  flowchart TD
    A[初始化ToF範圍儀] --> B[建立guizero應用程式]
    B --> C[建立文字元件]
    C --> D[定義更新函式]
    D --> E[使用repeat方法更新感測器資料]
    E --> F[啟動guizero應用程式]

圖表說明:

  • 圖表顯示了程式碼的執行流程。
  • 從初始化ToF範圍儀開始,到啟動guizero應用程式結束。

使用Python程式記錄樹莓派CPU溫度

介紹

本文將介紹如何使用Python程式記錄樹莓派CPU的溫度,並將資料儲存到USB隨身碟上的CSV檔案中。這個程式可以讓您輕鬆地記錄和分析CPU溫度的變化。

程式碼

import os
import glob
import time
import datetime

# 設定記錄間隔(秒)
log_period = 10

# 找到USB隨身碟的路徑
logging_folder = glob.glob('/media/*')[0]

# 取得現在的日期和時間
dt = datetime.datetime.now()

# 設定記錄檔案的名稱
file_name = "temp_log_{:%Y_%m_%d}.csv".format(dt)
logging_file = logging_folder + '/' + file_name

# 定義讀取CPU溫度的函式
def read_temp():
    dev = os.popen('/opt/vc/bin/vcgencmd measure_temp')
    cpu_temp = dev.read()[5:-3]  # 移除字串頭尾的字元
    return cpu_temp

# 定義記錄CPU溫度的函式
def log_temp():
    temp_c = read_temp()
    dt = datetime.datetime.now()
    f = open(logging_file, 'a')  # 以附加模式開啟檔案
    line = '\n"{:%H:%M:%S}","{}"'.format(dt, temp_c)  # 格式化記錄內容
    f.write(line)  # 寫入檔案
    print(line)  # 輸出記錄內容

# 主程式
while True:
    log_temp()  # 記錄CPU溫度
    time.sleep(log_period)  # 等待下一次記錄

解釋

  1. 首先,程式會找到USB隨身碟的路徑,並設定記錄檔案的名稱。
  2. read_temp() 函式會讀取CPU溫度,並移除字串頭尾的字元。
  3. log_temp() 函式會記錄CPU溫度,並將資料寫入檔案中。
  4. 主程式會不斷地呼叫 log_temp() 函式,以記錄CPU溫度。

使用方法

  1. 將程式碼儲存到一個檔案中(例如 ch_13_temp_log.py)。
  2. 執行程式碼,程式會開始記錄CPU溫度。
  3. 您可以在USB隨身碟中找到記錄檔案(例如 temp_log_2023_03_16.csv)。

注意事項

  • 本程式需要樹莓派的CPU溫度感應器才能正常運作。
  • 您需要將USB隨身碟插入樹莓派才能記錄資料。
  • 您可以修改 log_period 變數來調整記錄間隔。

距離測量技術在自動化、機器人等領域應用廣泛,各種測量方案百花齊放。本文比較了超音波、時間飛行 (ToF) 和 RFID 等距離測量技術,並深入探討了它們的優缺點、應用場景以及程式碼實作。分析顯示,超音波技術成本低廉但易受環境影響,ToF 技術精確度高但成本較高,而 RFID 則更適用於物體識別和追蹤。技術限制方面,ToF 感測器易受強光幹擾,超音波感測器則受限於測量範圍和精確度。實務落地時,開發者需根據具體應用需求選擇合適的技術方案,並考量成本、精確度、環境因素等多重指標。展望未來,隨著感測器技術的持續發展,預計 ToF 技術的成本將逐步降低,應用場景將進一步拓展,而多感測器融合的解決方案也將成為趨勢,為更精確、可靠的距離測量提供有力支援。玄貓認為,深入理解各種測量技術的特性,並根據實際需求靈活選用,才能在快速發展的科技浪潮中保持競爭力。