返回文章列表

MicroPython GPIO 與外部裝置互動

本文探討 MicroPython 中 GPIO 與外部裝置的互動方式,涵蓋 GPIO 的基本概念、工作原理、常見的通訊協定(UART、SPI、I2C),以及紅外線通訊的應用。文章以 ESP8266、micro:bit 等開發板為例,提供程式碼範例,講解如何使用 MicroPython 控制

嵌入式系統 物聯網

MicroPython 的 GPIO 控制能力是其核心功能之一,允許開發者透過程式碼直接與外部硬體互動。理解 GPIO 的工作原理及相關的通訊協定,對於開發嵌入式系統和物聯網應用至關重要。本文將詳細介紹如何使用 MicroPython 操作 GPIO,並透過實際範例展示如何控制 LED、讀取按鈕狀態,以及使用 UART、SPI 和 I2C 等通訊協定與外部裝置進行資料交換。此外,文章也涵蓋了紅外線通訊的原理和應用,以及進階的 GPIO 技巧如位元碰撞,提供讀者更全面的 MicroPython GPIO 應用。

GPIO 與外部裝置的互動

GPIO(General Purpose Input and Output)是微控制器與外部世界溝通的橋樑。透過GPIO,MicroPython 能夠控制和讀取連線的外圍裝置,從而實作對外部世界的感知和控制。每個GPIO引腳都有特定的名稱,以便在程式中參照,根據組態的不同,這些引腳能夠處理和傳送不同型別的訊號。

引腳的工作原理

「引腳」是一個泛稱,歷史上它指的是看起來像針腳的連線點,但現代的設計往往並非如此。在本文的上下文中,引腳是指連線到微控制器的導電區域,透過這些區域可以與外部裝置進行通訊。圖9-1顯示了micro:bit上的「引腳」特寫:

這些「引腳」並不像傳統的針腳,有些甚至大到可以直接用鱷魚夾夾住。它們位於開發板的底部邊緣,但你可能會疑惑如何連線裝置到那些較小的引腳。解決方案是使用邊緣聯結器,將跳線連線到外部裝置,或使用麵包板來放置外部元件(圖9-2)。

使用外設進行感測

雖然micro:bit、Circuit Playground Express和PyBoard都具備內建的輸入和感測器,但你也可以將外設連線到任何執行MicroPython的裝置的GPIO引腳。關鍵在於透過引腳存取裝置,就像本章前面示範的那樣。對於外部外設,它們會使用可用的外部引腳,而不是直接連線到板上元件的「引腳」。

以下是一個使用ESP8266開發板的簡單範例(圖8-2):

from machine import Pin

led = Pin(2, Pin.OUT)
button = Pin(14, Pin.IN, Pin.PULL_UP)

while True:
    led.value(button.value())

內容解密:

  1. from machine import Pin:從machine模組匯入Pin類別,用於控制GPIO引腳。
  2. led = Pin(2, Pin.OUT):將引腳2組態為輸出模式,用於控制LED燈。
  3. button = Pin(14, Pin.IN, Pin.PULL_UP):將引腳14組態為輸入模式,並啟用上拉電阻,用於讀取按鈕狀態。
  4. while True::進入無限迴圈,不斷讀取按鈕狀態並更新LED狀態。
  5. led.value(button.value()):將LED的狀態設定為按鈕的當前值,實作按鈕控制LED的效果。

這個範例展示瞭如何透過GPIO引腳讀取外部按鈕的狀態,並控制LED燈的開關。

常見的通訊協定

本章將介紹三種常見的通訊協定:UART、SPI和I2C,這些協定使得與外部裝置的互動變得簡單和標準化。透過這些協定,你可以輕鬆地與各種外設進行資料交換,實作更豐富的功能。

UART 協定

UART(Universal Asynchronous Receiver/Transmitter)是一種常用的串列通訊協定,用於裝置之間的非同步資料傳輸。它只需要兩根線(TX和RX)即可實作雙向通訊,廣泛應用於微控制器與電腦或其他裝置之間的資料交換。

SPI 協定

SPI(Serial Peripheral Interface)是一種高速、全雙工的串列通訊協定,主要用於微控制器與外設之間的高速資料傳輸。SPI通常需要四根線(MOSI、MISO、SCK和CS),能夠實作高效的資料交換。

I2C 協定

I2C(Inter-Integrated Circuit)是一種多主機、多從機的串列通訊協定,只需要兩根線(SCL和SDA)即可實作多裝置之間的資料傳輸。I2C協定廣泛應用於各種感測器、顯示模組和其他外設的連線。

透過瞭解和掌握這些通訊協定,你可以更加靈活地使用MicroPython開發各種應用,與外部世界進行互動。

GPIO 與微控制器的互動基礎

在微控制器(如 micro:bit、Circuit Playground Express、PyBoard 和 ESP8266/32)的世界中,GPIO(通用輸入/輸出)針腳扮演著至關重要的角色。這些針腳讓開發者能夠與外部周邊裝置進行互動,實作各種創意專案。

針腳的命名與功能

不同的微控制器板有不同的針腳組態和命名規則。例如,micro:bit 和 Circuit Playground Express 的針腳較大,便於使用鱷魚夾進行連線;而 PyBoard 則有兩種組態,一種是沒有預先焊接針腳,另一種是預先焊接了 female 針腳。ESP8266/32 板通常預先焊接了 male 針腳。

針腳的名稱通常印在電路板上,以便開發者參考。在程式碼中參照針腳時,需要根據所使用的 MicroPython 版本和裝置型別進行不同的操作。例如,在 micro:bit 上,需要使用 microbit 模組;而在 CircuitPython 中,則使用 board 模組。

針腳的多樣功能

GPIO 針腳有多種功能,包括:

  • 數位輸入/輸出:控制針腳的狀態為高(3.3V)或低(0V)。
  • 類別比輸入/輸出:讀取或輸出介於高低之間的電壓值。
  • 電容式觸控:檢測人體觸控。
  • 中斷請求(IRQ):當針腳狀態改變時,觸發中斷請求。

中斷請求(IRQ)的使用

在某些微控制器板上,可以定義中斷請求(IRQ),當針腳的輸入狀態改變時觸發回呼函式。以下是一個 ESP8266 板的範例:

from machine import Pin

def callback(p):
    print('Pin', p)

p0 = Pin(0, Pin.IN)
p0.irq(trigger=Pin.IRQ_FALLING, handler=callback)

內容解密:

  1. 匯入 machine 模組中的 Pin 類別,用於控制 GPIO 針腳。
  2. 定義一個回呼函式 callback,當中斷請求觸發時列印針腳物件。
  3. 將針腳 0 設定為輸入模式,並定義中斷請求的觸發條件為下降沿(Pin.IRQ_FALLING),並指定回呼函式。
  4. 當針腳 0 的狀態從高變低時,回呼函式被觸發,列印相關資訊。

序列通訊與 UART

UART(通用非同步收發傳輸器)是微控制器中用於序列通訊的硬體元件。它將序列訊號轉換為平行位元組,或將平行位元組轉換為序列訊號。UART 在 REPL(互動式命令列介面)中扮演著重要角色,使得開發者能夠透過 USB 連線與微控制器進行通訊。

串列通訊協定:UART 與 SPI 詳解

在微控制器與外設之間的通訊中,串列通訊協定扮演著重要的角色。其中,UART(通用非同步收發傳輸器)與 SPI(串列周邊介面)是兩種常見的串列通訊協定。

UART 通訊協定

UART 是一種非同步串列通訊協定,廣泛應用於微控制器與電腦之間的通訊。要實作 UART 通訊,需要進行以下組態:

  1. 連線 TX 與 RX 引腳:裝置 A 的 TX 引腳須連線到裝置 B 的 RX 引腳,反之亦然。
  2. 設定鮑率:雙方須約定相同的鮑率(bits per second),常見的鮑率有 9600、14400、19200、28800、38400、57600 和 115200。
  3. 設定資料位元、奇偶校驗位元和停止位元:通常資料位元為 8 位元,但有時需要指定奇偶校驗位元和停止位元的數量。

UART 具有「先進先出」(FIFO)佇列,能夠緩衝接收到的資料。MicroPython 開發板上的 UART 通常連線到內部 USB-UART TX/RX 引腳,透過 USB 連線到電腦。在電腦端,可以使用 pySerial 或 picocom 等函式庫或工具開啟串列連線,實作與 MicroPython REPL 的通訊。

MicroPython 中的 UART 範例

from microbit import *

while True:
    msg = uart.read()
    if msg:
        uart.write(msg)

此範例演示瞭如何使用 UART 讀取和寫入資料到連線的電腦。micro:bit 開發板具有一個 uart 物件來處理通訊。其他開發板可能需要例項化 UART 類別並進行相應的組態。

SPI 通訊協定

SPI 是另一種串列通訊協定,與 UART 不同的是,它是一種同步資料匯流排,具有裝置階層結構。

SPI 的特點

  • 同步時脈訊號:SPI 使用時脈訊號(SCLK)來同步資料傳輸,避免了 UART 中因時脈不同步而導致的錯誤。
  • 主從式架構:SPI 具有主從式架構,主裝置(通常是微控制器)提供時脈訊號,從裝置則根據時脈訊號進行資料傳輸。
  • 資料傳輸連線:SPI 使用 MOSI(主出從入)和 MISO(主入從出)連線進行資料傳輸。
  • 晶片選擇(CS)連線:SPI 使用 CS 連線來選擇特定的從裝置進行資料傳輸。

SPI 組態範例

SPI 可以組態為獨立從裝置模式或菊花鏈模式。在獨立從裝置模式中,每個從裝置都有一個獨立的 CS 連線。在菊花鏈模式中,所有從裝置共用一個 CS 連線。

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title SPI 組態範例

rectangle "SCLK" as node1
rectangle "MOSI" as node2
rectangle "MISO" as node3
rectangle "CS" as node4

node1 --> node2
node2 --> node3
node3 --> node4

@enduml

此圖示說明瞭 SPI 的主從式架構和兩種組態模式。

#### 內容解密:

此圖表呈現了 SPI 的基本架構,包括主裝置和從裝置之間的連線。在獨立從裝置模式中,每個從裝置都有獨立的 CS 連線,而在菊花鏈模式中,所有從裝置共用一個 CS 連線,並透過 MISO 連線串聯起來。這種架構使得 SPI 能夠支援多個從裝置的通訊。

SPI與I2C通訊協定在MicroPython中的應用

在MicroPython中,SPI(Serial Peripheral Interface)與I2C(Inter-Integrated Circuit)是兩種重要的硬體通訊協定,分別具有不同的特點和應用場景。

SPI通訊協定

SPI是一種高速的、全雙工的同步序列通訊協定,廣泛應用於微控制器與周邊裝置之間的資料傳輸。其主要特點包括:

  • 高速資料傳輸
  • 全雙工通訊
  • 主從式架構
  • 需要至少四條連線線(MISO、MOSI、SCLK、CS)

在SPI通訊中,主裝置透過CS(Chip Select)訊號選擇特定的從裝置進行資料交換。資料傳輸透過MISO(Master In Slave Out)和MOSI(Master Out Slave In)線路進行,分別負責主裝置接收從裝置資料和主裝置向從裝置傳送資料。

Daisy Chain組態

SPI支援Daisy Chain組態,即多個從裝置串聯連線,主裝置只需一個CS訊號即可控制所有從裝置。資料透過每個從裝置傳遞,最終到達目標裝置。

from machine import SPI, Pin

# 初始化SPI物件
spi = SPI('X')

# 初始化CS物件
cs = Pin('X1', Pin.OUT)

# 啟動CS訊號
cs.value(0)

# 建立資料緩衝區
buffer = bytearray(5)

# 進行資料交換
spi.write_readinto(b'hello', buffer)

# 結束CS訊號
cs.value(1)

程式碼解析

  1. 初始化SPI物件:使用SPI('X')初始化SPI物件,指定SPI介面。
  2. 初始化CS物件:使用Pin('X1', Pin.OUT)初始化CS物件,並設定為輸出模式。
  3. 啟動CS訊號:將CS訊號設為低電平,啟動與從裝置的通訊。
  4. 建立資料緩衝區:使用bytearray(5)建立一個大小為5位元組的資料緩衝區。
  5. 進行資料交換:使用spi.write_readinto(b'hello', buffer)進行資料交換,將b'hello'傳送到從裝置,並將從裝置的回應儲存在buffer中。
  6. 結束CS訊號:將CS訊號設為高電平,結束與從裝置的通訊。

I2C通訊協定

I2C是一種半雙工的同步序列通訊協定,使用兩條線路(SCL、SDA)進行資料傳輸。其主要特點包括:

  • 半雙工通訊
  • 主從式架構
  • 支援多主裝置和多從裝置
  • 需要兩條連線線(SCL、SDA)

在I2C通訊中,主裝置透過SCL(Serial Clock)訊號控制時鐘,SDA(Serial Data)訊號傳輸資料。從裝置透過地址識別自身是否為目標裝置。

I2C通訊流程

  1. 起始條件:主裝置將SDA訊號拉低,同時保持SCL訊號高電平,表示開始新的通訊。
  2. 地址幀:主裝置傳送7位元地址和1位元讀寫控制位,從裝置根據地址識別自身是否為目標裝置。
  3. 確認位元:目標從裝置將SDA訊號拉低,表示確認收到地址幀。
  4. 資料幀:主裝置或從裝置根據讀寫控制位傳輸資料。
  5. 停止條件:主裝置將SCL訊號拉高,同時將SDA訊號拉高,表示結束通訊。
from machine import I2C

# 初始化I2C物件
i2c = I2C('X')

# 掃描I2C匯流排上的裝置
devices = i2c.scan()
print(devices)

# 向指定裝置寫入資料
i2c.writeto(46, b'A')

# 從指定裝置讀取資料
data = i2c.readfrom(46, 8)
print(data)

程式碼解析

  1. 初始化I2C物件:使用I2C('X')初始化I2C物件,指定I2C介面。
  2. 掃描I2C匯流排上的裝置:使用i2c.scan()掃描I2C匯流排上的裝置,並傳回裝置地址列表。
  3. 向指定裝置寫入資料:使用i2c.writeto(46, b'A')向地址為46的裝置寫入位元組b'A'
  4. 從指定裝置讀取資料:使用i2c.readfrom(46, 8)從地址為46的裝置讀取8位元組的資料。

綜上所述,SPI和I2C是兩種常見的硬體通訊協定,分別具有不同的特點和應用場景。在MicroPython中,可以使用相關的函式庫和API實作這兩種通訊協定,從而實作微控制器與周邊裝置之間的資料交換。

網路連線

由於執行MicroPython的裝置體積小巧,無法容納乙太網路介面。因此,這些裝置若具備相互通訊的能力,通常採用無線方式進行。

無線通訊的魅力

遠距離互動總帶有某種奇妙的滿足感,彷彿是在施展魔法。然而,這背後的原理遠比魔法更為精彩:物理學!本章將探討兩種通訊方式:紅外線(適用於Circuit Playground Express)與無線電(適用於micro:bit及ESP8266/32為基礎的裝置)。

紅外線通訊

紅外線通訊最常見的應用是電視遙控器:使用者按下按鈕,遙控器發出訊號給電視。紅外線在短距離內效果良好,但需要發射器與接收器之間有直接視線(因此需要將遙控器對準電視)。

紅外線的工作原理

紅外線的波長略低於可見光,因此人類無法直接觀察到紅外線。環境中有許多紅外線源,例如陽光、燈泡、蠟燭,甚至人體(人體輻射的大部分熱能都屬於紅外線光譜)。為了減少環境中紅外線源的幹擾,傳送訊號時通常會對訊號進行調變。所謂調變,是指訊號以預先約定的頻率傳送,最常見的是38 kHz(儘管也有其他頻率被使用)。簡單來說,紅外線發射器以每秒38,000次的頻率閃爍。這種訊號與環境中的其他紅外線源有所不同,從而減少幹擾。

MicroPython中的I2C介面使用範例

>>> i2c.writeto_mem(46, 0, b'A')
>>> i2c.readfrom_mem(46, 0, 2)
b'\x00A'

程式碼解析:

  1. i2c.writeto_mem(46, 0, b'A'):向位址為46的I2C裝置的記憶體位址0寫入字元’A’。
  2. i2c.readfrom_mem(46, 0, 2):從位址為46的I2C裝置的記憶體位址0讀取2個位元組。

這個範例展示瞭如何在MicroPython中使用I2C介面與外部裝置進行通訊。

GPIO進階技巧與協定

除了常見的UART、SPI和I2C協定之外,一些周邊裝置可能使用專有的協定,例如NeoPixels(也稱為ws2812)和數位濕度與溫度(DHT)感測器系列,它們都使用1-wire介面。MicroPython已經為這兩種裝置提供了模組,因此實際實作細節並不重要。然而,當遇到沒有標準協定的周邊裝置時,若沒有現成的模組可用,可能需要自行實作相關程式碼。

位元碰撞(Bit Banging)

位元碰撞是一種忽略硬體協定,直接使用軟體控制針腳、時序、電平和同步,以創造低成本、高度客製化的解決方案來處理周邊裝置問題的方法。這是一種「駭客」行為,但也正是其趣味所在。當遇到需要與硬體進行非標準互動的情況時,位元碰撞提供了一種靈活的解決方案。

網路連線的重要性

MicroPython執行於微控制器上,提供了一種高階、表達力強且易於使用的語言,使開發者能夠在極短的時間內建立可運作的解決方案。這種接近硬體卻又具備高階語言特性的開發方式,使得MicroPython成為一種優秀的教育工具。開發者既能夠深入瞭解電腦硬體的工作原理,又能夠使用功能強大、靈活且易於學習的程式語言。將MicroPython所學的技能轉移到「一般」Python程式設計中,也證明瞭Python生態系統所提供的經驗連續性。