本文介紹如何使用 Python 程式設計搭配樹莓派控制和讀取多種感測器資料,包含數位溫度感測器 DS18B20、三軸加速度計 MMA8452Q 以及整合多種感測器的 Sense HAT。文章將逐步說明硬體連線方式、軟體程式碼撰寫、資料處理與應用場景,讓讀者能快速上手並應用於實際專案中。其中包含 DS18B20 的單線介面設定、MMA8452Q 的 I2C 通訊設定、以及 Sense HAT 的磁力計資料讀取與應用。透過這些範例,讀者可以學習如何整合不同型別的感測器,並運用程式碼實作資料擷取、處理和應用。

使用 DS18B20 數位溫度感測器

問題

您想要使用精確的數位溫度感測器來測量溫度。

解決方案

使用 DS18B20 數位溫度感測器。這個裝置比 TMP36 (用於配方 13.9) 更準確,並使用數位介面,因此不需要 ADC 晶片。

雖然這個晶片的介面被稱為一線介面,但這只指的是資料引腳。您仍需要至少一根其他線來連線到一線裝置。

要製作這個配方,您需要以下元件:

*麵包板和跳線 (見「原型設計裝置和套件」) *DS18B20 溫度感測器 (見「積體電路」) *4.7kΩ 電阻器 (見「電阻器和電容器」)

將元件安裝在麵包板上,如圖 13-17 所示。確保 DS18B20 的方向正確。

最新版本的 Raspbian 核心已經支援 DS18B20 使用的一線介面,但您需要使用 Raspberry Pi 組態工具 (圖 13-18) 來啟用它。

開啟一個編輯器並貼入以下程式碼 (ch_13_temp_DS18B20.py):

import glob, time

base_dir = '/sys/bus/w1/devices/'

Mermaid 圖表:Sense HAT 感測器架構

  graph LR
    A[Raspberry Pi] -->|連線|> B[Sense HAT]
    B -->|內建|> C[溫度感測器]
    B -->|內建|> D[濕度感測器]
    B -->|內建|> E[氣壓感測器]
    C -->|讀取|> F[溫度資料]
    D -->|讀取|> G[濕度資料]
    E -->|讀取|> H[氣壓資料]

圖表翻譯:

這個 Mermaid 圖表展示了 Sense HAT 感測器的架構。Raspberry Pi 連線到 Sense HAT,Sense HAT 內建有溫度、濕度和氣壓感測器。這些感測器可以讀取各自的資料,並將其傳回給 Raspberry Pi。

讀取溫度感測器資料

簡介

在本文中,我們將探討如何使用Python指令碼讀取DS18B20溫度感測器的資料。這個感測器是一種廣泛使用的數字溫度感測器,能夠提供高精確度的溫度讀數。

設定感測器檔案路徑

首先,我們需要設定感測器檔案路徑。這個路徑通常位於 /sys/bus/w1/devices/ 目錄下,後面跟著感測器的ID號碼。

import glob

base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'

讀取原始資料

接下來,我們定義了一個函式 read_temp_raw(),用於讀取感測器的原始資料。這個函式開啟感測器檔案,讀取所有行,並將其儲存在 lines 變數中。

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

處理資料

然後,我們定義了一個函式 read_temp(),用於處理原始資料。這個函式首先呼叫 read_temp_raw() 函式,然後檢查第一行的最後三個字元是否為 “YES”。如果不是,它會等待0.2秒後重新讀取資料。

def read_temp():
    lines = read_temp_raw()
    while lines[0].strip()[-3:]!= 'YES':
        time.sleep(0.2)
        lines = read_temp_raw()

提取溫度值

如果第一行的最後三個字元是 “YES”,我們就可以提取溫度值了。溫度值儲存在第二行的 “t=” 之後的位置。我們使用 find() 方法找到 “t=” 的位置,然後提取溫度值。

    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

內容解密:

上述程式碼示範瞭如何使用Python讀取DS18B20溫度感測器的資料。首先,我們需要設定感測器檔案路徑,然後定義函式來讀取原始資料和處理資料。最後,我們可以提取溫度值並將其轉換為攝氏和華氏溫度。

圖表翻譯:

  flowchart TD
    A[設定感測器檔案路徑] --> B[讀取原始資料]
    B --> C[處理資料]
    C --> D[提取溫度值]
    D --> E[傳回攝氏和華氏溫度值]

圖表說明:

上述流程圖示範了讀取DS18B20溫度感測器資料的過程。首先,我們設定感測器檔案路徑,然後讀取原始資料。接下來,我們處理資料,然後提取溫度值。最後,我們傳回攝氏和華氏溫度值。

使用DS18B20模組測量溫度

模組介紹

DS18B20是一種數位溫度感測器,可以測量-55°C至125°C的溫度範圍。它使用一線式通訊協定,易於連線和使用。

程式碼

import time
import os

def read_temp():
    # 開啟DS18B20模組的w1_slave檔案
    with open('/sys/bus/w1/devices/28-000005e6c952/w1_slave', 'r') as f:
        # 讀取檔案內容
        lines = f.readlines()
        # 提取溫度資料
        temp_c = float(lines[1].split('t=')[1]) / 1000
        # 轉換為華氏溫度
        temp_f = temp_c * 9 / 5 + 32
        return temp_c, temp_f

while True:
    # 讀取溫度資料
    temp_c, temp_f = read_temp()
    # 印出溫度資料
    print('Temp C={:.2f}\ttemp F={:.2f}'.format(temp_c, temp_f))
    # 暫停1秒
    time.sleep(1)

內容解密:

上述程式碼使用DS18B20模組來測量溫度。它先開啟模組的w1_slave檔案,然後讀取檔案內容,提取溫度資料,最後轉換為華氏溫度並印出結果。

Mermaid 圖表

  flowchart TD
    A[開始] --> B[開啟w1_slave檔案]
    B --> C[讀取檔案內容]
    C --> D[提取溫度資料]
    D --> E[轉換為華氏溫度]
    E --> F[印出溫度資料]
    F --> G[暫停1秒]
    G --> A

圖表翻譯:

上述Mermaid圖表展示了程式碼的執行流程。它從開始到開啟w1_slave檔案,然後讀取檔案內容,提取溫度資料,轉換為華氏溫度,印出溫度資料,最後暫停1秒。

討論

DS18B20模組是一種方便使用的數位溫度感測器。它使用一線式通訊協定,易於連線和使用。程式碼中使用了read_temp函式來讀取溫度資料,然後轉換為華氏溫度並印出結果。這個模組可以用於各種應用,例如溫度監測、控制等。

連線三軸加速度計到樹莓派

問題描述

您想要將三軸加速度計連線到樹莓派,以測量X、Y和Z軸的加速度。

解決方案

使用I2C通訊協定的加速度計晶片來測量X、Y和Z軸的加速度。為了實作這個解決方案,您需要以下元件:

*麵包板(見「原型設計裝置和套件」) *四根母對母跳線(見「原型設計裝置和套件」) *MMA8452Q三軸加速度計(見「模組」)

圖13-19顯示了使用麵包板的連線安排。它使用三個ADC通道來測量X、Y和Z軸的加速度。

步驟1:啟用I2C功能

在樹莓派上啟用I2C功能。如果您尚未啟用,請按照配方9.3中的步驟進行。

步驟2:編寫程式碼

開啟編輯器並貼入以下程式碼(ch_13_i2c_acc.py):

import smbus
import time

bus = smbus.SMBus(1)
i2c_address = 0x1D
control_reg = 0x2A
bus.write_byte_data(i2c_address, control_reg, 0x01)  # 啟動
bus.write_byte_data(i2c_address, 0x0E, 0x00)  # 2g範圍
time.sleep(0.5)

def read_acc():
    data = bus.read_i2c_block_data(i2c_address, 0x00, 7)
    x = (data[1] * 256 + data[2]) / 16
    if x > 2047:
        x -= 4096
    y = (data[3] * 256 + data[4]) / 16
    if y > 2047:
        y -= 4096
    #...(其他軸的計算)

步驟3:讀取加速度資料

呼叫read_acc()函式來讀取加速度資料。這個函式從I2C匯流排上讀取7個位元組的資料,然後計算X和Y軸的加速度值。

內容解密:

上述程式碼使用smbus函式庫來與I2C匯流排進行通訊。SMBus類別代表I2C匯流排,write_byte_data()方法用來向I2C裝置寫入資料。read_i2c_block_data()方法用來從I2C裝置讀取資料。read_acc()函式計算X和Y軸的加速度值,並傳回這些值。

圖表翻譯:

  flowchart TD
    A[啟動I2C] --> B[初始化I2C匯流排]
    B --> C[寫入控制暫存器]
    C --> D[設定2g範圍]
    D --> E[延遲0.5秒]
    E --> F[讀取加速度資料]
    F --> G[計算X和Y軸加速度]
    G --> H[傳回加速度值]

這個流程圖顯示了程式碼的執行流程。首先,啟動I2C功能並初始化I2C匯流排。然後,寫入控制暫存器並設定2g範圍。接下來,延遲0.5秒以確保設定生效。然後,讀取加速度資料並計算X和Y軸的加速度值。最後,傳回加速度值。

加速計資料讀取與顯示

程式碼

import time

def read_accelerometer(data):
    x = (data[0] * 256 + data[1]) / 16
    if x > 2047:
        x -= 4096

    y = (data[2] * 256 + data[3]) / 16
    if y > 2047:
        y -= 4096

    z = (data[4] * 256 + data[5]) / 16
    if z > 2047:
        z -= 4096

    return x, y, z

while True:
    # 讀取加速計資料
    data = [0, 0, 0, 0, 0, 0]  # 模擬讀取資料
    x, y, z = read_accelerometer(data)

    # 顯示資料
    print("x={:.6f}\ty={:.6f}\tz={:.6f}".format(x, y, z))

    # 等待0.5秒後繼續讀取
    time.sleep(0.5)

內容解密:

上述程式碼示範如何讀取加速計資料並顯示出來。read_accelerometer函式負責將原始資料轉換為加速計的x、y、z軸的值。若資料超過2047,則進行調整以確保正確的表示。

在主程式中,使用while迴圈不斷讀取加速計資料,並使用print函式顯示出來。time.sleep(0.5)用於設定間隔時間,以控制讀取頻率。

圖表翻譯:

  flowchart TD
    A[開始] --> B[讀取加速計資料]
    B --> C[轉換資料]
    C --> D[顯示資料]
    D --> E[等待]
    E --> B

圖表翻譯:

此流程圖顯示了程式的運作流程。首先,程式開始運作(A),然後讀取加速計資料(B),接著轉換資料(C),顯示出來(D),最後等待一段時間後(E)再次迴圈讀取資料。

討論:

在使用加速計時,可能需要根據具體的硬體情況調整I2C地址。可以使用sudoi2cdetect -y 1命令檢查I2C地址。同時,需要注意的是,加速計的讀取結果可能會受到硬體和環境的影響,因此需要根據具體情況進行調整和校準。

加速計與傾斜檢測

加速計是一種可以測量物體加速度的感測器,常用於偵測傾斜、振動和衝擊等。其中,MMA8452Q是一種常用的加速計模組,它透過I2C通訊協定與微控制器進行通訊。

MMA8452Q的設定

要使用MMA8452Q,加速計需要設定其I2C地址、控制暫存器和組態命令。根據資料表,MMA8452Q的I2C地址為0x1D,控制暫存器為0x2A,組態命令為0x01。設定完成後,加速計開始工作。

讀取加速度資料

當需要讀取加速度資料時,透過I2C匯流排讀取資料,並將其分割為X、Y、Z三個方向的加速度資料。這些資料可以用於偵測傾斜、振動和衝擊等。

傾斜檢測

加速計最常用的應用之一就是傾斜檢測。當加速計傾斜時,重力沿著Z軸的分量會變化,從而影響其他軸的加速度資料。透過分析這些資料,可以偵測出傾斜的方向和角度。

Python程式範例

以下是使用Python程式語言讀取MMA8452Q加速計資料並偵測傾斜的範例:

import smbus
import time

# 設定I2C匯流排和加速計地址
bus = smbus.SMBus(1)
i2c_address = 0x1D

# 設定控制暫存器和組態命令
control_reg = 0x2A
bus.write_byte_data(i2c_address, control_reg, 0x01)  # 啟動加速計
bus.write_byte_data(i2c_address, 0x0E, 0x00)  # 設定2g範圍
time.sleep(0.5)

# 定義讀取加速計資料的函式
def read_acc():
    data = bus.read_i2c_block_data(i2c_address, 0x00, 7)
    x = (data[1] * 256 + data[2]) / 16
    if x > 2047:
        x -= 4096
    y = (data[3] * 256 + data[4]) / 16
    #... 處理其他軸的資料
    return x, y

# 讀取加速計資料並偵測傾斜
while True:
    x, y = read_acc()
    #... 處理傾斜檢測邏輯
    time.sleep(0.1)

這個範例程式展示瞭如何使用Python語言讀取MMA8452Q加速計資料並偵測傾斜。透過分析加速計資料,可以實作各種應用,如傾斜檢測、振動監測和運動追蹤等。

圖表翻譯:

  flowchart TD
    A[啟動加速計] --> B[設定控制暫存器]
    B --> C[設定組態命令]
    C --> D[讀取加速計資料]
    D --> E[分析資料並偵測傾斜]
    E --> F[處理傾斜檢測邏輯]

這個流程圖展示了使用MMA8452Q加速計偵測傾斜的步驟,從啟動加速計到處理傾斜檢測邏輯。

加速計資料處理與方向判斷

程式碼解說

if y > 2047:
    y -= 4096

此段程式碼負責將加速計的y軸資料進行調整,以確保其在正確的範圍內。當y軸資料大於2047時,減去4096以進行調整。

z = (data[5] * 256 + data[6]) / 16

此段程式碼計算z軸的加速計資料。它將data陣列中的第5和第6個元素進行位元運算,然後除以16以取得最終結果。

if z > 2047:
    z -= 4096

此段程式碼與前面的y軸調整類別似,對z軸資料進行調整,以確保其在正確的範圍內。

return (x, y, z)

此函式傳回x、y、z三個軸的加速計資料。

方向判斷迴圈

while True:
    x, y, z = read_acc()

此迴圈不斷地讀取加速計的資料,並將其儲存在x、y、z變數中。

if x > 400:
    print("Left")
elif x < -400:
    print("Right")
elif y > 400:
    print("Back")
elif y < -400:
    print("Forward")

此段程式碼根據x和y軸的資料判斷方向。如果x軸資料大於400,則印出"Left";如果x軸資料小於-400,則印出"Right";如果y軸資料大於400,則印出"Back";如果y軸資料小於-400,則印出"Forward"。

time.sleep(0.2)

此行程式碼使得迴圈每0.2秒執行一次,避免過度消耗系統資源。

圖表翻譯:

  flowchart TD
    A[開始] --> B[讀取加速計資料]
    B --> C[判斷方向]
    C --> D[印出方向]
    D --> E[等待0.2秒]
    E --> B

此流程圖描述了方向判斷迴圈的流程。從開始到讀取加速計資料,然後判斷方向,印出方向,最後等待0.2秒後再次讀取資料。

使用 Sense HAT 的磁力計來偵測磁北

在這個範例中,我們將使用 Sense HAT 的內建三軸磁力計來偵測磁北。首先,請按照 9.16 節的步驟安裝 Sense HAT 函式庫。

接下來,開啟編輯器並貼入以下程式碼(ch_13_sense_hat_compass.py):

from sense_hat import SenseHat

# 初始化 Sense HAT
sense = SenseHat()

# 取得磁力計的資料
magnetometer_data = sense.get_compass_raw()

# 將磁力計的資料轉換為方向
direction = sense.get_compass()

# 列印方向
print("Magnetic North: ", direction)

這個程式碼會取得 Sense HAT 的磁力計資料,並將其轉換為方向。最後,會列印出磁北的方向。

執行程式碼

執行程式碼後,你會看到磁北的方向被列印出來。這個結果可以用來控制一個機器人或一個帶有 webcam 的電動 pan-tilt 頭。

相關資訊

如果你想要了解更多關於 MMA8452Q 的資訊,可以參考 13.15 節的內容。Sense HAT 還包括了一個加速度計,可以用來偵測傾斜和振動。

Mermaid 圖表

  flowchart TD
    A[初始化 Sense HAT] --> B[取得磁力計資料]
    B --> C[轉換資料為方向]
    C --> D[列印方向]

圖表翻譯:

這個圖表顯示了使用 Sense HAT 的磁力計來偵測磁北的流程。首先,初始化 Sense HAT,然後取得磁力計的資料。接下來,將資料轉換為方向,最後列印出方向。

內容解密:

在這個範例中,我們使用了 Sense HAT 的內建三軸磁力計來偵測磁北。首先,初始化 Sense HAT,然後取得磁力計的資料。接下來,將資料轉換為方向,最後列印出方向。這個結果可以用來控制一個機器人或一個帶有 webcam 的電動 pan-tilt 頭。

程式碼解說:

  • from sense_hat import SenseHat:匯入 Sense HAT 函式庫。
  • sense = SenseHat():初始化 Sense HAT。
  • magnetometer_data = sense.get_compass_raw():取得磁力計的資料。
  • direction = sense.get_compass():將磁力計的資料轉換為方向。
  • print("Magnetic North: ", direction):列印出磁北的方向。

從使用者經驗的角度來看,本文介紹了多種感測器應用於樹莓派的實務操作,涵蓋溫度、加速度和磁場偵測,展現了豐富的應用場景。透過詳盡的程式碼範例和圖表說明,降低了讀者理解和實作的門檻,尤其對於初學者更具實用價值。然而,文章缺乏對不同感測器選型的比較分析,例如在不同精確度需求、成本考量或功耗限制下如何選擇合適的感測器。此外,對於感測器資料的校準和誤差處理也未深入探討,這在實際應用中至關重要。

綜合評估後,本文提供的程式碼範例和圖表有助於快速上手感測器應用,但仍需在實務中結合具體需求進行調整和最佳化。對於追求更高精確度和穩定性的應用,建議深入研究感測器資料處理、校準以及誤差分析等進階議題。從技術演進角度,隨著物聯網和邊緣計算的發展,感測器應用將更加普及,未來更需關注感測器資料的融合、分析和應用,以創造更多價值。玄貓認為,掌握感測器應用基礎,並持續探索進階技術,將是未來開發者不可或缺的核心能力。