第8章 Raspberry Pi GPIO Output 實作:Python 控制 LED 閃爍與流水燈

發布日期: |更新日期:
文章主圖:第8章 Raspberry Pi GPIO Output 實作:Python 控制 LED 閃爍與流水燈

前面七章,我們已經完成:

Raspberry Pi 5
     │
     ├── Raspberry Pi OS
     ├── Linux
     ├── Network
     ├── SSH
     ├── Python
     └── 40-pin GPIO

但截至目前,我們還沒有真正讓 Python 改變外部電子元件的狀態。

本章要完成整套 Raspberry Pi 課程第一個真正的:

Physical Computing 實作

我們會讓:

Python
   │
   ▼
GPIO17
   │
   ▼
LED
   │
   ▼
亮 / 滅

接著從一顆 LED 延伸成:

4 顆 LED 流水燈
        ↓
8 顆 LED 跑馬燈
        ↓
往返流水燈

這一章非常重要,因為後面控制:

  • Buzzer
  • Relay
  • Servo Driver
  • Motor Driver
  • LCD
  • Sensor

本質上都是建立在相同的:

Python → GPIO → Electronic Circuit

概念之上。

1. 本章使用 GPIO Zero

本章 Python GPIO Library 使用:

GPIO Zero

GPIO Zero 是為 Raspberry Pi GPIO 提供較高階 Python 介面的 Library,可以直接用 LED、Button 等物件描述實際電子元件。GPIO Zero 目前預設使用 BCM GPIO 編號,例如 LED(17) 代表 GPIO17,而不是 Physical Pin 17。

例如:

from gpiozero import LED

led = LED(17)

這段程式的意思非常直觀:

建立一個接在 BCM GPIO17 的 LED 裝置。

2. 為什麼 Raspberry Pi 5 不直接使用舊 RPi.GPIO 教學?

Raspberry Pi 5 和前代最大的 GPIO 底層差異之一,是使用者可見 GPIO 主要由 RP1 提供。

Raspberry Pi 官方 GPIO 技術文件指出,舊版 RPi.GPIO 透過直接硬體存取的方式並不支援 Raspberry Pi 5;Pi 5 的 GPIO 架構改變後,更適合透過現代 Linux GPIO 介面與相容 Library 使用。

因此看到舊文章:

import RPi.GPIO as GPIO

不要直接假設:

Raspberry Pi 5 也應該照抄。

本系列 Raspberry Pi 5 Python 基礎 GPIO 統一使用:

GPIO Zero

3. Raspberry Pi 5 GPIO Zero 背後使用什麼?

GPIO Zero 本身是一層較高階 API。

實際控制 GPIO 還需要底層:

Pin Factory

目前 GPIO Zero 文件指出,在 Raspberry Pi 5 上應使用:

lgpio

而且目前列出的 Pin Factory 中,只有 lgpio 支援 Pi 5。正常環境中若已安裝 lgpio,GPIO Zero 會使用 LGPIOFactory。

概念如下:

Python 程式
    │
    ▼
GPIO Zero
    │
    ▼
lgpio
    │
    ▼
Linux GPIO
    │
    ▼
RP1
    │
    ▼
GPIO Pin

初學者平常不需要直接操作這麼底層。

但是遇到:

GPIO Zero 找不到 Pin Factory

時,就必須知道這一層存在。

4. GPIO Zero 要另外安裝嗎?

目前 GPIO Zero 官方安裝文件指出,Raspberry Pi OS 的 Desktop 與 Lite Image 都預先包含 GPIO Zero;如果系統中沒有,也可以使用 Raspberry Pi OS 的 APT Package 安裝。

先測試:

python3 -c "import gpiozero; print(gpiozero.__version__)"

如果可以顯示版本,就表示:

GPIO Zero
=
可以 Import

5. 如果顯示 ModuleNotFoundError

例如:

ModuleNotFoundError: No module named 'gpiozero'

可以先:

sudo apt update

再:

sudo apt install python3-gpiozero

GPIO Zero 官方目前將 python3-gpiozero 列為 Raspberry Pi OS 的標準 APT 安裝方式。

6. 本章不建議使用 sudo pip install gpiozero

前面第 6 章已經介紹過:

現代 Raspberry Pi OS 應該避免任意修改 System Python。

因此本章如果只是 Raspberry Pi OS 上的基礎 GPIO:

APT
↓
python3-gpiozero

最單純。

不要看到缺 Package 就立刻:

sudo pip install gpiozero

7. 如果一定要在 Virtual Environment 使用 GPIO Zero

第 6 章建立過:

.venv

如果要讓 venv 使用系統已安裝的 GPIO Zero,可以建立:

python3 -m venv .venv --system-site-packages

然後:

source .venv/bin/activate

這樣 Virtual Environment 可以讀取 APT 安裝的 GPIO Zero。GPIO Zero 官方目前也直接提供 --system-site-packages 的 venv 使用方式。

8. GPIO Zero 現在也可以用 pip 安裝嗎?

可以。

GPIO Zero 官方文件指出,過去 Raspberry Pi 5 上以 pip 安裝 GPIO Zero 曾因 lgpio Pin Factory 問題無法正常使用,但此問題已於 2026 年 7 月 GPIO Zero 2.0.1.post1 修復。

因此現在如果使用沒有 System Package 的 Virtual Environment,也可以依官方方式安裝:

pip install gpiozero

並準備相容的 lgpio。

不過本系列基礎實驗仍優先:

Raspberry Pi OS
+
APT GPIO Zero

減少環境變數。

9. 本章需要哪些材料?

第一個 LED 實驗需要:

  • Raspberry Pi 5
  • Raspberry Pi OS
  • Breadboard
  • LED × 1
  • 330Ω Resistor × 1
  • Female-to-Male Dupont Wire
  • Raspberry Pi 5 正常電源
  • Active Cooler 或適當散熱

後面流水燈則增加:

  • LED × 4 或 × 8
  • 330Ω Resistor × 4 或 × 8
  • 更多 Jumper Wire

10. 第一個 LED 使用哪一支 GPIO?

本章第一顆 LED 使用:

BCM GPIO17

對應:

BCM GPIO17
=
Physical Pin 11

GND 使用:

Physical Pin 6
=
GND

GPIO Zero 預設採 BCM Number,因此程式:

LED(17)

代表 GPIO17,也就是 Physical Pin 11。

11. GPIO17 LED 接線

接線:

Raspberry Pi 5

GPIO17
Physical Pin 11
      │
      ▼
    330Ω
      │
      ▼
 LED Anode (+)
 LED Cathode (-)
      │
      ▼
GND
Physical Pin 6

GPIO Zero 官方 LED 文件同樣建議 LED Cathode 接 Ground、Anode 經限流 Resistor 接 GPIO;限流電阻放在 LED 任一側的串聯位置皆可達到限制電流的目的。

12. LED 的方向不能接反

一般未剪腳 LED:

長腳
=
Anode
=
+

短腳
=
Cathode
=
-

LED Package 常見扁平側也通常位於 Cathode。

本章電路:

GPIO17
 ↓
330Ω
 ↓
Anode
 LED
Cathode
 ↓
GND

如果 LED 完全接反,通常不會按照預期發光。

13. 為什麼一定使用 330Ω?

GPIO17 HIGH 約為 3.3V。

以常見 LED 為例,如果 Forward Voltage 約 2V,使用 330Ω 可以把 LED 電流限制在數 mA 級,非常適合教學。

概念:

3.3V
 │
330Ω
 │
LED
 │
GND

本實驗目的不是追求最大 LED 亮度。

而是:

安全而清楚地觀察 GPIO HIGH / LOW。

14. 接線前先關機

本系列所有 GPIO 實驗建議:

sudo poweroff

等 Raspberry Pi 完全停止後:

  1. 拔除 USB-C Power
  2. 接 GPIO
  3. 接 Resistor
  4. 接 LED
  5. 接 GND
  6. 再檢查一次
  7. 最後重新供電

不要養成:

Pi 開著
+
拿杜邦線試來試去

的習慣。

15. 第一次接線檢查

上電前確認:

GPIO17 / Physical 11
      │
      ▼
330Ω
      │
      ▼
LED Anode

LED Cathode
      │
      ▼
GND / Physical 6

特別確認:

沒有把 Physical Pin 2 / 4 的 5V 接到 GPIO17。

16. 建立第 8 章程式目錄

開機後:

cd ~

建立:

mkdir -p raspberrypi-course/chapter08

進入:

cd raspberrypi-course/chapter08

確認:

pwd

例如:

/home/jason/raspberrypi-course/chapter08

17. 第一支 GPIO Output 程式

建立:

nano led_on.py

輸入:

from gpiozero import LED
from time import sleep

led = LED(17)

led.on()

sleep(5)

led.off()

儲存後:

python3 led_on.py

18. 這支程式在做什麼?

第一行:

from gpiozero import LED

載入 GPIO Zero 的:

LED

物件。

第二行:

from time import sleep

載入時間延遲功能。

19. LED(17) 是什麼?

led = LED(17)

表示:

建立 LED Object
        │
        ▼
BCM GPIO17

GPIO Zero 文件確認整數 GPIO 編號預設使用 BCM Scheme,因此 17 不是 Physical Pin 17。

20. led.on()

led.on()

將這個 Output Device 設成 Active。

在本章的標準 Active-high 接法中:

GPIO17 HIGH
≈
3.3V

因此電流:

GPIO17
  ↓
330Ω
  ↓
LED
  ↓
GND

LED 亮起。

GPIO Zero 的 LED.on() 就是將 LED 裝置切換為開啟狀態。

21. led.off()

led.off()

則將 LED 關閉。

GPIO Zero LED.off() 會把該 Output Device 切換為 Off。

所以:

led.on()
   ↓
LED ON

led.off()
   ↓
LED OFF

22. sleep(5)

sleep(5)

讓目前 Python 程式暫停約:

5 seconds

因此完整流程:

Program Start
    ↓
LED ON
    ↓
Wait 5 sec
    ↓
LED OFF
    ↓
Program End

23. 第一個 LED Blink 程式

建立:

nano led_blink.py

內容:

from gpiozero import LED
from time import sleep

led = LED(17)

while True:
    led.on()
    sleep(1)

    led.off()
    sleep(1)

執行:

python3 led_blink.py

LED 將:

亮 1 秒
 ↓
滅 1 秒
 ↓
亮 1 秒
 ↓
滅 1 秒
 ↓
持續循環

這也是 GPIO Zero 官方 LED 基本 Recipe 的標準操作模式。

24. 這就是 Raspberry Pi 版 Blink

Arduino 初學通常第一個程式是:

Blink

Raspberry Pi 也一樣。

差異是:

Arduino
C/C++
digitalWrite()

對比:

Raspberry Pi
Python
GPIO Zero
LED.on()
LED.off()

兩邊最後做的事情相同:

Digital Output
HIGH / LOW

25. 如何停止一直執行的 Blink?

因為:

while True:

會永久循環。

在 Terminal 按:

Ctrl + C

Python 通常顯示:

KeyboardInterrupt

然後停止。

這不是 GPIO 壞掉。

而是你主動中止程式。

26. 用 try / except 做比較漂亮的停止

可以改成:

from gpiozero import LED
from time import sleep

led = LED(17)

try:
    while True:
        led.on()
        sleep(1)

        led.off()
        sleep(1)

except KeyboardInterrupt:
    print("\nProgram stopped.")

finally:
    led.off()
    led.close()

這個版本更適合後面的正式 GPIO Project。

27. finally 為什麼重要?

無論:

  • 正常離開
  • Ctrl+C
  • 某些 Exception

finally 都可以用來進行:

Cleanup

例如:

led.off()

確保程式離開前把 LED 關掉。

再:

led.close()

釋放 GPIO Zero Device 使用的資源。

28. GPIO Zero 為什麼有 close()?

GPIO 是 Linux 系統資源。

程式取得 GPIO 後,結束時最好釋放。

對單次簡單 Script,GPIO Zero 可以協助處理生命週期;但在較正式程式中明確:

device.close()

會讓資源管理意圖更清楚。

GPIO Zero API 也提供 close(),關閉後該裝置不再保持對 GPIO Pin 的控制。

29. 使用 toggle()

GPIO Zero 還有:

led.toggle()

意思:

如果目前 ON
   ↓
變 OFF

如果目前 OFF
   ↓
變 ON

GPIO Zero 官方 toggle() 定義就是反轉目前 Device 狀態。

30. toggle Blink 程式

from gpiozero import LED
from time import sleep

led = LED(17)

try:
    while True:
        led.toggle()
        sleep(1)

except KeyboardInterrupt:
    print("\nProgram stopped.")

finally:
    led.off()
    led.close()

這和:

led.on()
sleep(1)
led.off()
sleep(1)

功能很接近。

31. led.is_lit

還可以檢查:

led.is_lit

例如:

from gpiozero import LED

led = LED(17)

led.on()

print(led.is_lit)

led.off()

print(led.is_lit)

led.close()

得到:

True
False

GPIO Zero 的 is_lit 會回傳 LED 是否處於 Active 狀態。

32. 使用 GPIO Zero 內建 blink()

其實 GPIO Zero 已經提供:

blink()

可以寫:

from gpiozero import LED
from signal import pause

led = LED(17)

led.blink()

pause()

GPIO Zero 官方 Recipe 就提供這種寫法。

33. 為什麼 blink() 後面還要 pause()?

blink() 預設會在 Background Thread 中控制 LED。

如果主程式直接執行到底:

Program End

程序就會離開。

因此官方 Recipe 使用:

pause()

讓 Script 繼續存活。

架構:

Main Program
    │
    ├── led.blink()
    │      │
    │      └── Background Thread
    │
    └── pause()
           │
           └── Keep Program Alive

34. blink() 的預設速度

GPIO Zero blink() 預設:

ON  = 1 second
OFF = 1 second

如果 n=None,預設會持續閃爍。

所以:

led.blink()

大致相當於:

while True:
    led.on()
    sleep(1)

    led.off()
    sleep(1)

35. 自訂 Blink 速度

例如:

from gpiozero import LED
from signal import pause

led = LED(17)

led.blink(
    on_time=0.2,
    off_time=0.8
)

pause()

效果:

亮 0.2 秒
滅 0.8 秒

GPIO Zero blink() 可以分別指定 on_time 與 off_time。

36. 只閃五次

可以:

from gpiozero import LED

led = LED(17)

led.blink(
    on_time=0.5,
    off_time=0.5,
    n=5,
    background=False
)

led.close()

GPIO Zero 的 n 可以指定 Blink 次數;background=False 則讓程式等待 Blink 完成後再往下執行。

37. while True 和 blink() 哪個比較好?

兩種都值得會。

while True

優點:

容易理解程式流程
容易加入其他邏輯
適合初學

blink()

優點:

程式短
GPIO Zero 已封裝
可使用 Background Thread

本系列初期會刻意多寫:

while True:

因為後面:

Sensor
Button
Relay
MQTT

都要在主 Loop 中加入更多邏輯。

38. 改變 LED 閃爍速度

建立:

nano led_speed.py

內容:

from gpiozero import LED
from time import sleep

led = LED(17)

delay = 0.2

try:
    while True:
        led.on()
        sleep(delay)

        led.off()
        sleep(delay)

except KeyboardInterrupt:
    print("\nProgram stopped.")

finally:
    led.off()
    led.close()

39. delay Variable 的好處

現在速度集中在:

delay = 0.2

如果想慢:

delay = 1.0

如果想快:

delay = 0.1

不用修改兩個:

sleep(...)

這就是前面 Python Variable 的實際用途。

40. 不要把 LED Blink 設得無限快

例如:

delay = 0

配合:

while True:

會讓程式持續高速循環。

這樣:

  • 人眼可能看不出 Blink
  • CPU 使用率可能增加
  • 對教學沒有實際價值

如果需要真正頻率控制或 PWM,應使用適當:

  • PWMLED
  • Hardware PWM
  • 專用控制方法

而不是用 Python Busy Loop 硬湊。

41. PWMLED 是什麼?

GPIO Zero 另外提供:

PWMLED

可用:

0.0
~
1.0

控制 LED Brightness。

GPIO Zero 官方 Recipe 例如:

0   = off
0.5 = half brightness
1   = full brightness

並可以使用 pulse() 做 Fade In / Fade Out。

不過 PWM 會留到第 10 章完整學習。

42. 第二階段:兩顆 LED

我們現在增加:

LED1
LED2

使用:

LED1 → GPIO17 → Physical Pin 11

LED2 → GPIO27 → Physical Pin 13

兩顆 LED 都各自使用:

330Ω

43. 兩顆 LED 接線

GPIO17 / Pin 11
      │
     330Ω
      │
     LED1
      │
      └──── GND


GPIO27 / Pin 13
      │
     330Ω
      │
     LED2
      │
      └──── GND

可以共用:

Breadboard Ground Rail

再連回 Raspberry Pi GND。

44. 兩顆 LED 輪流亮

from gpiozero import LED
from time import sleep

led1 = LED(17)
led2 = LED(27)

try:
    while True:
        led1.on()
        led2.off()
        sleep(0.5)

        led1.off()
        led2.on()
        sleep(0.5)

except KeyboardInterrupt:
    print("\nProgram stopped.")

finally:
    led1.off()
    led2.off()

    led1.close()
    led2.close()

效果:

LED1 ON
LED2 OFF
   ↓
LED1 OFF
LED2 ON
   ↓
Repeat

45. 這就是最基本流水燈概念

如果:

LED1 → LED2

可以輪流亮。

再增加:

LED3
LED4

就變成:

LED1
 ↓
LED2
 ↓
LED3
 ↓
LED4

這就是:

流水燈

46. 4 顆 LED 使用哪些 GPIO?

本章建議:

4 顆 LED GPIO 配置表
LED BCM GPIO Physical Pin
LED1 GPIO17 Pin 11
LED2 GPIO27 Pin 13
LED3 GPIO22 Pin 15
LED4 GPIO23 Pin 16

這四支都是本章拿來進行一般 Digital Output 的 GPIO。

每一顆 LED:

GPIO
 ↓
330Ω
 ↓
LED
 ↓
GND

47. 4 顆 LED 接線概念

GPIO17 ──330Ω── LED1 ── GND
GPIO27 ──330Ω── LED2 ── GND
GPIO22 ──330Ω── LED3 ── GND
GPIO23 ──330Ω── LED4 ── GND

注意:

每一顆 LED 都要有自己的限流電阻。

不要只在四顆 LED 共用 GND 之前放一顆總電阻。

48. 最直覺的 4 LED 流水燈程式

from gpiozero import LED
from time import sleep

led1 = LED(17)
led2 = LED(27)
led3 = LED(22)
led4 = LED(23)

delay = 0.2

try:
    while True:
        led1.on()
        sleep(delay)
        led1.off()

        led2.on()
        sleep(delay)
        led2.off()

        led3.on()
        sleep(delay)
        led3.off()

        led4.on()
        sleep(delay)
        led4.off()

except KeyboardInterrupt:
    print("\nProgram stopped.")

finally:
    led1.off()
    led2.off()
    led3.off()
    led4.off()

    led1.close()
    led2.close()
    led3.close()
    led4.close()

功能可以正常工作。

但是:

程式太重複。

49. 使用 List 改善程式

前面第 6 章已學過:

list

現在就派上用場。

from gpiozero import LED
from time import sleep

leds = [
    LED(17),
    LED(27),
    LED(22),
    LED(23)
]

delay = 0.2

try:
    while True:
        for led in leds:
            led.on()
            sleep(delay)
            led.off()

except KeyboardInterrupt:
    print("\nProgram stopped.")

finally:
    for led in leds:
        led.off()
        led.close()

50. 這個版本為什麼更好?

原本:

LED1
LED2
LED3
LED4

每一顆都要重複:

on()
sleep()
off()

現在:

for led in leds:

會自動逐一處理。

這就是:

Python List
+
for Loop
+
GPIO

真正結合起來。

51. 4 顆 LED 流水流程

程式:

for led in leds:

實際順序:

GPIO17 ON
 ↓
GPIO17 OFF
 ↓
GPIO27 ON
 ↓
GPIO27 OFF
 ↓
GPIO22 ON
 ↓
GPIO22 OFF
 ↓
GPIO23 ON
 ↓
GPIO23 OFF
 ↓
Repeat

因此肉眼看到亮點向一個方向移動。

52. 讓每顆 LED 保留較明顯的暗間隔

可以:

for led in leds:
    led.on()
    sleep(0.2)

    led.off()
    sleep(0.05)

增加:

OFF Gap

有時流水效果會更清楚。

53. 往返流水燈

現在不要:

1 → 2 → 3 → 4
1 → 2 → 3 → 4

而改:

1 → 2 → 3 → 4
3 → 2
1 → 2 → 3 → 4

這就是:

往返跑馬燈

54. 最簡單的往返方法

from gpiozero import LED
from time import sleep

leds = [
    LED(17),
    LED(27),
    LED(22),
    LED(23)
]

delay = 0.2

try:
    while True:
        for led in leds:
            led.on()
            sleep(delay)
            led.off()

        for led in leds[-2:0:-1]:
            led.on()
            sleep(delay)
            led.off()

except KeyboardInterrupt:
    print("\nProgram stopped.")

finally:
    for led in leds:
        led.off()
        led.close()

55. leds[-2:0:-1] 是什麼?

原 List:

LED1
LED2
LED3
LED4

第一個:

for led in leds:

執行:

LED1 → LED2 → LED3 → LED4

反向:

leds[-2:0:-1]

取得:

LED3 → LED2

因此不會讓:

LED4

與:

LED1

在轉向時各重複亮兩次。

56. 初學者如果不熟 Slice,可以用 index

比較容易理解的版本:

from gpiozero import LED
from time import sleep

leds = [
    LED(17),
    LED(27),
    LED(22),
    LED(23)
]

delay = 0.2

try:
    while True:
        for index in range(len(leds)):
            leds[index].on()
            sleep(delay)
            leds[index].off()

        for index in range(
            len(leds) - 2,
            0,
            -1
        ):
            leds[index].on()
            sleep(delay)
            leds[index].off()

except KeyboardInterrupt:
    print("\nProgram stopped.")

finally:
    for led in leds:
        led.off()
        led.close()

這和前面學過的:

range()
List Index
for

完全銜接。

57. 接下來擴充成 8 顆 LED

8 顆 LED 使用:

8 顆 LED GPIO 配置表
LED BCM GPIO Physical Pin
LED1 GPIO17 Pin 11
LED2 GPIO27 Pin 13
LED3 GPIO22 Pin 15
LED4 GPIO23 Pin 16
LED5 GPIO24 Pin 18
LED6 GPIO25 Pin 22
LED7 GPIO5 Pin 29
LED8 GPIO6 Pin 31

每一顆:

GPIO
 ↓
330Ω
 ↓
LED
 ↓
GND

58. 8 顆 LED Breadboard 電源觀念

八顆 LED Cathode 可以全部接:

Breadboard GND Rail

GND Rail 再接:

Raspberry Pi GND

例如:

Pi GND Pin 6
      │
      ▼
Breadboard GND Rail
      │
      ├── LED1 Cathode
      ├── LED2 Cathode
      ├── LED3 Cathode
      ├── LED4 Cathode
      ├── LED5 Cathode
      ├── LED6 Cathode
      ├── LED7 Cathode
      └── LED8 Cathode

59. 8 顆 LED 每一顆仍要一個 Resistor

正確:

GPIO17 ─330Ω─ LED1 ─ GND
GPIO27 ─330Ω─ LED2 ─ GND
GPIO22 ─330Ω─ LED3 ─ GND
...

不是:

8 顆 LED
   │
共用一個 330Ω
   │
GND

每個 LED Branch 都需要自己的 Current Limiting。

60. 8 顆 LED 單向跑馬燈

建立:

nano led_running_8.py

內容:

from gpiozero import LED
from time import sleep

GPIO_PINS = [
    17,
    27,
    22,
    23,
    24,
    25,
    5,
    6
]

leds = [
    LED(pin)
    for pin in GPIO_PINS
]

delay = 0.15

try:
    while True:
        for led in leds:
            led.on()
            sleep(delay)
            led.off()

except KeyboardInterrupt:
    print("\nProgram stopped.")

finally:
    for led in leds:
        led.off()
        led.close()

61. GPIO_PINS 為什麼使用大寫?

我們把:

GPIO_PINS

當作:

Project Configuration Constant

它在程式執行期間不打算修改。

Python 並沒有強制 Constant 語法,但使用全大寫名稱是常見程式風格,讓閱讀者知道:

這個值是設定資料。

62. List Comprehension

這一段:

leds = [
    LED(pin)
    for pin in GPIO_PINS
]

相當於:

leds = []

for pin in GPIO_PINS:
    leds.append(
        LED(pin)
    )

只是更精簡。

初學者不熟時,使用第二種完整寫法完全沒問題。

63. 8 顆 LED 往返跑馬燈

from gpiozero import LED
from time import sleep

GPIO_PINS = [
    17,
    27,
    22,
    23,
    24,
    25,
    5,
    6
]

leds = [
    LED(pin)
    for pin in GPIO_PINS
]

delay = 0.12

try:
    while True:
        for led in leds:
            led.on()
            sleep(delay)
            led.off()

        for led in leds[-2:0:-1]:
            led.on()
            sleep(delay)
            led.off()

except KeyboardInterrupt:
    print("\nProgram stopped.")

finally:
    for led in leds:
        led.off()
        led.close()

效果:

1 → 2 → 3 → 4 → 5 → 6 → 7 → 8
                              ↓
1 ← 2 ← 3 ← 4 ← 5 ← 6 ← 7

持續循環。

64. 做成 Function

現在開始把功能拆乾淨:

from gpiozero import LED
from time import sleep

GPIO_PINS = [
    17,
    27,
    22,
    23,
    24,
    25,
    5,
    6
]

DELAY = 0.12


def show_led(led):
    led.on()
    sleep(DELAY)
    led.off()


def turn_all_off(leds):
    for led in leds:
        led.off()


def close_all(leds):
    for led in leds:
        led.close()


def main():
    leds = [
        LED(pin)
        for pin in GPIO_PINS
    ]

    try:
        while True:
            for led in leds:
                show_led(led)

            for led in leds[-2:0:-1]:
                show_led(led)

    except KeyboardInterrupt:
        print("\nProgram stopped.")

    finally:
        turn_all_off(leds)
        close_all(leds)


if __name__ == "__main__":
    main()

這個版本已經更接近正式 Project。

65. 為什麼 Function 版本比較好?

現在:

show_led()

負責:

LED ON
Delay
LED OFF

turn_all_off():

關閉所有 LED

close_all():

釋放所有 GPIO Device

main():

負責主要流程

這種結構後面加入:

  • Button
  • Speed Control
  • MQTT
  • Web Control

會比較容易。

66. 全亮與全滅

可以新增:

def all_on(leds):
    for led in leds:
        led.on()


def all_off(leds):
    for led in leds:
        led.off()

然後:

all_on(leds)
sleep(1)

all_off(leds)
sleep(1)

就可以實作:

全部亮
 ↓
全部滅

67. 全亮全滅五次

def flash_all(
    leds,
    times,
    delay
):
    for _ in range(times):
        for led in leds:
            led.on()

        sleep(delay)

        for led in leds:
            led.off()

        sleep(delay)

使用:

flash_all(
    leds,
    times=5,
    delay=1
)

效果:

全亮 1 秒
全滅 1 秒
× 5

68. underscore _ 是什麼?

這裡:

for _ in range(times):

我們只在意:

重複幾次

卻不需要使用 Loop Index。

因此常用:

_

表示:

這個變數我刻意不用。

69. 全亮全滅+跑馬燈完整實作

現在可以做一個比較完整的 Project:

from gpiozero import LED
from time import sleep

GPIO_PINS = [
    17,
    27,
    22,
    23,
    24,
    25,
    5,
    6
]

FLASH_DELAY = 1.0
RUN_DELAY = 0.15


def all_on(leds):
    for led in leds:
        led.on()


def all_off(leds):
    for led in leds:
        led.off()


def flash_all(leds, times):
    for _ in range(times):
        all_on(leds)
        sleep(FLASH_DELAY)

        all_off(leds)
        sleep(FLASH_DELAY)


def show_led(led):
    led.on()
    sleep(RUN_DELAY)
    led.off()


def running_light(
    leds,
    cycles
):
    for _ in range(cycles):
        for led in leds:
            show_led(led)

        for led in leds[-2:0:-1]:
            show_led(led)


def close_all(leds):
    for led in leds:
        led.close()


def main():
    leds = [
        LED(pin)
        for pin in GPIO_PINS
    ]

    try:
        while True:
            flash_all(
                leds,
                times=5
            )

            running_light(
                leds,
                cycles=5
            )

    except KeyboardInterrupt:
        print(
            "\nProgram stopped."
        )

    finally:
        all_off(leds)
        close_all(leds)


if __name__ == "__main__":
    main()

70. 這個完整程式如何動作?

流程:

Program Start
     ↓
8 LED 全亮
     ↓
1 秒
     ↓
8 LED 全滅
     ↓
1 秒
     ↓
重複 5 次
     ↓
LED1 → LED8
     ↓
LED7 → LED2
     ↓
重複往返 5 次
     ↓
回到全亮 / 全滅
     ↓
持續循環

這已經是一個完整的小型燈光控制專案。

71. 如何改跑馬燈速度?

目前:

RUN_DELAY = 0.15

變快:

RUN_DELAY = 0.05

變慢:

RUN_DELAY = 0.5

後面第 9 章加入 Button 後,就可以進一步製作:

Button +
      ↓
加速

Button -
      ↓
減速

72. GPIO Zero LEDBoard

GPIO Zero 其實還有:

LEDBoard

可以將多個 LED 組成一個 Board Device。

例如:

from gpiozero import LEDBoard

leds = LEDBoard(
    17,
    27,
    22,
    23
)

這在多 LED Project 很方便。

不過本章前半刻意先使用:

LED
+
List

因為這樣可以同時練習:

  • Python List
  • for Loop
  • Device Object

等重要基礎。

73. LED 不亮:第一步不要先改 Python

遇到 LED 不亮時,很多人第一個動作是:

一直修改程式

但電子實驗應該分成:

Hardware
+
Software

兩邊 Debug。

建議順序:

Power
 ↓
Wiring
 ↓
LED Direction
 ↓
Resistor
 ↓
GPIO Number
 ↓
Python
 ↓
GPIO Library

74. LED 不亮:檢查 LED 方向

確認:

GPIO
 ↓
Resistor
 ↓
Anode
 LED
Cathode
 ↓
GND

如果方向反了:

Cathode
接 GPIO

Anode
接 GND

LED 通常不會按照這個電路工作。

75. LED 不亮:確認 Physical Pin

程式:

LED(17)

代表:

BCM GPIO17

它的 Physical Position 是:

Pin 11

不是:

Physical Pin 17

GPIO Zero 官方文件特別用 GPIO17 / BOARD11 說明這個編號差異。

76. Physical Pin 17 是什麼?

Physical Pin 17 是:

3.3V Power

不是 BCM GPIO17。

所以如果程式:

LED(17)

而你的 LED 實際插:

Physical Pin 17

就完全接錯位置。

這是本章最重要的 Debug 項目之一。

77. LED 一直亮,程式無法控制

如果 LED 接到:

3.3V Power Pin

而不是:

GPIO

就可能一開機就持續亮。

因為 Power Rail 不是 Python GPIO Output。

例如:

Physical Pin 1
Physical Pin 17

都是 3.3V Power。

78. LED 太暗

可能原因:

  • Resistor 太大
  • LED 顏色 / Forward Voltage
  • LED 品質
  • 接觸不良
  • GPIO 沒有真正 Active

例如:

10kΩ

雖然可能仍有微弱電流,但亮度會比:

330Ω

低很多。

79. LED 很亮但擔心電流過大

不要使用:

沒有電阻

或過低的 Resistor 值去追求亮度。

Raspberry Pi GPIO 是邏輯控制介面。

本課程目標是:

數 mA 等級的可視 LED

而不是使用 GPIO 直接驅動高亮度照明 LED。

80. 顯示 No module named gpiozero

執行:

python3 led_blink.py

如果:

ModuleNotFoundError:
No module named 'gpiozero'

先:

sudo apt update
sudo apt install python3-gpiozero

GPIO Zero 官方把此 APT Package 列為 Raspberry Pi OS 的標準 Python 3 安裝方法。

81. 在 venv 中找不到 gpiozero

假設:

System Python
可以 import gpiozero

但是:

.venv
不可以

這通常是因為 Virtual Environment 預設隔離 System Package。

可以建立:

python3 -m venv .venv \
  --system-site-packages

官方 GPIO Zero 文件目前就提供這種方式。

82. BadPinFactory 是什麼?

例如看到:

BadPinFactory:
Unable to load any default pin factory

代表 GPIO Zero:

本身 Import 成功

但找不到可使用的底層 GPIO Backend。

GPIO Zero 文件說明,在 Raspberry Pi 5 上目前要使用 lgpio Pin Factory。

因此要檢查:

GPIO Zero
+
lgpio
+
Raspberry Pi OS Environment

是否完整。

83. 如何查看目前 Pin Factory?

可以建立:

nano gpio_factory.py

內容:

from gpiozero import Device
from gpiozero import LED

led = LED(17)

print(
    Device.pin_factory
)

led.close()

在正常 Pi 5 GPIO Zero / lgpio 環境中,應該看到與:

LGPIOFactory

相關的資訊。GPIO Zero 文件說明,如果系統安裝 lgpio,建立第一個 Device 時預設會採用 LGPIOFactory。

84. 不要在 Pi 5 強制選 native Factory

例如網路舊文章可能出現:

GPIOZERO_PIN_FACTORY=native

但目前 GPIO Zero 文件的 Pi Support 表明:

native
RPi.GPIO
pigpio

這些 Factory 並不支援 Pi 5,而 lgpio 支援所有列出的 Pi Model。

所以 Pi 5 不要為了解決錯誤,反而強迫 GPIO Zero 使用不相容 Backend。

85. 不要看到舊 pigpio 教學就直接套用 Pi 5

Raspberry Pi 官方 GPIO Best Practices 文件指出,pigpio 由於底層高度依賴舊 Broadcom GPIO 架構,目前並不支援 Raspberry Pi 5,也不建議新 Pi 5 Project 把它當標準解法。

所以本系列:

Pi 5 Python GPIO
      ↓
GPIO Zero
      ↓
lgpio

保持一致。

86. GPIO Busy / Resource Busy

如果 GPIO 正被另一個 Process 佔用,可能發生:

GPIO busy
resource busy

先確認是否有另一個 Python GPIO Program 還在執行。

例如:

ps aux | grep python

不要同時開兩個程式爭用同一個 GPIO。

87. Ctrl+C 後 LED 還亮著怎麼辦?

如果你的程式沒有 Cleanup:

中途停止

時 LED 狀態可能不如預期。

因此本系列後續標準結構會逐漸採用:

try:
    ...

except KeyboardInterrupt:
    ...

finally:
    ...

在 finally:

led.off()
led.close()

確保應用程式自己完成收尾。

88. GPIO Output 不能拿來驅動馬達

本章 LED 可以使用 GPIO,是因為 LED 加限流電阻後只需要很小電流。

不要把:

GPIO17

改接:

DC Motor

認為:

motor = LED(17)

就可以控制。

馬達、Relay Coil、Pump 等需要:

GPIO
 ↓
Driver
 ↓
External Power
 ↓
Load

這個安全原則和第 7 章完全一致。

89. Raspberry Pi GPIO Output 是「控制」,不是「供電」

要建立正確觀念:

GPIO
=
Signal

而不是:

GPIO
=
Power Supply

LED 只是因為功率很小,所以可以做第一個 Output Lab。

後續負載越大,就越需要:

  • Transistor
  • MOSFET
  • Driver IC
  • External Power

90. Raspberry Pi 5 GPIO 是 3.3V

Raspberry Pi 官方 GPIO Best Practices 文件明確指出,Raspberry Pi GPIO 在 Output On 時工作於約 3.3V,作 Input 時也不可接超過 3.3V 的訊號。

因此本章:

GPIO17 HIGH

不是:

5V HIGH

這點和 Arduino UNO R3 的 5V 使用習慣一定要分清楚。

91. 可以用 Multimeter 驗證 GPIO17 嗎?

可以。

如果具備基本電表操作能力:

Black Probe
→ GND

Red Probe
→ GPIO17

程式:

led.on()

時可以量到接近:

3.3V

led.off():

接近 0V

Raspberry Pi 官方也將 GPIO Output 的 On 狀態描述為約 3.3V。

量測時務必避免 Probe 滑動短接相鄰 5V、3.3V 與 GND。

92. 使用 pinout 指令確認 GPIO

如果系統有 GPIO Zero Command-Line Tool,可以試:

pinout

它可以顯示 Raspberry Pi Board 與 GPIO Header Pinout。

因此接線前除了文章 Pin Table,最好也養成:

實際 Raspberry Pi
+
pinout
+
接線圖

三者交叉確認的習慣。

93. 本章推薦的最小測試程式

如果 8 LED Project 有問題,不要從完整程式開始除錯。

把它縮小成:

from gpiozero import LED
from time import sleep

led = LED(17)

led.on()
sleep(2)

led.off()
sleep(2)

led.close()

硬體也縮成:

Pi
 │
GPIO17
 │
330Ω
 │
LED
 │
GND

如果最小系統能工作,再一顆一顆增加。

94. 多顆 LED Debug 方法

假設 LED5 不亮。

Pin Table:

LED5
=
GPIO24
=
Physical Pin 18

先暫時只測:

from gpiozero import LED
from time import sleep

led = LED(24)

led.on()
sleep(5)
led.off()

led.close()

如果仍不亮:

檢查:

GPIO24
Physical Pin 18
330Ω
LED Direction
Breadboard Row
GND

不要先懷疑 for Loop。

95. 如果所有 LED 都不亮

優先檢查:

  1. Raspberry Pi 是否正常開機。
  2. GND Rail 是否真的接 Pi GND。
  3. LED 方向是否全部錯。
  4. GPIO Zero 是否能建立 Device。
  5. Pin Factory 是否正常。
  6. 程式是否使用正確 BCM GPIO。
  7. 是否誤接 Physical Pin。
  8. Breadboard Ground Rail 是否中間斷開。

最後這一點很常被忽略。

有些 Breadboard Power Rail:

左半段

和:

右半段

並不是內部連通。

96. Breadboard Rail 不是永遠全部相通

不同 Breadboard Layout 不同。

不要看到:

紅線
藍線

就直接假設從頭到尾全部 Connected。

可以使用 Multimeter:

Continuity Mode

確認。

97. 程式可以執行但 LED 完全沒有反應

這種情況很可能是:

Software PASS
Hardware FAIL

典型原因:

BCM / Physical 搞錯
LED 方向錯
Breadboard 插錯 Row
Ground 沒接
電阻沒有真正串聯

這也是電子實驗和純 Python 最大的差別:

沒有 Error Message 不代表硬體一定正確。

98. 程式一開始就出 Exception

如果:

LED(17)

當下就 Error:

這反而比較接近:

Library
Pin Factory
GPIO Resource
Permission
System Environment

問題。

因此:

初始化就失敗

和:

程式正常跑但燈不亮

要分開判斷。

99. GPIO Output Debug 流程

可以記:

1. Python 可執行?
        ↓
2. import gpiozero 成功?
        ↓
3. LED(17) 建立成功?
        ↓
4. Pin Factory 正常?
        ↓
5. BCM GPIO 正確?
        ↓
6. Physical Pin 正確?
        ↓
7. LED 極性正確?
        ↓
8. Resistor 正確?
        ↓
9. GND 正確?
        ↓
10. Breadboard Connected?

這會比:

不亮
↓
重灌 Raspberry Pi OS

有效很多。

100. GPIO Zero LED 常用 API

GPIO Zero LED 常用 API
API 功能
LED(pin) 建立 LED Device
led.on() LED ON
led.off() LED OFF
led.toggle() 反轉狀態
led.blink() 自動閃爍
led.is_lit 查詢是否亮起
led.value 讀取/設定狀態
led.close() 關閉 Device

GPIO Zero 官方 LED API 提供上述 on()、off()、toggle()、blink()、is_lit 與 value 等功能。

101. 本章 GPIO Pin 配置總表

第 8 章 GPIO Pin 配置總表
功能 BCM GPIO Physical
LED1 GPIO17 Pin 11
LED2 GPIO27 Pin 13
LED3 GPIO22 Pin 15
LED4 GPIO23 Pin 16
LED5 GPIO24 Pin 18
LED6 GPIO25 Pin 22
LED7 GPIO5 Pin 29
LED8 GPIO6 Pin 31
Ground GND Pin 6

每個 LED:

GPIO
 ↓
330Ω
 ↓
LED
 ↓
GND

102. 本章完整學習流程

GPIO Zero
    ↓
確認 lgpio / Pi 5
    ↓
GPIO17
    ↓
330Ω
    ↓
單顆 LED
    ↓
led.on()
    ↓
led.off()
    ↓
Blink
    ↓
toggle()
    ↓
Ctrl+C
    ↓
finally Cleanup
    ↓
2 LEDs
    ↓
4 LEDs
    ↓
List + for Loop
    ↓
8 LEDs
    ↓
Running Light
    ↓
Bidirectional Running Light
    ↓
完整燈光控制 Project

103. 本章重點整理

完成本章後,應該掌握:

  1. Raspberry Pi GPIO Output 可以控制 LED。
  2. Raspberry Pi 5 Python GPIO 本系列使用 GPIO Zero。
  3. GPIO Zero 預設使用 BCM GPIO Number。
  4. LED(17) 表示 BCM GPIO17,而不是 Physical Pin 17。
  5. GPIO17 對應 Physical Pin 11。
  6. Raspberry Pi GPIO Output HIGH 約為 3.3V。
  7. LED 必須使用合適限流電阻。
  8. 本系列基本 LED 實驗使用 330Ω。
  9. LED Anode 經 Resistor 接 GPIO,Cathode 接 GND 是 GPIO Zero 官方基本接法。
  10. from gpiozero import LED 載入 LED Class。
  11. led = LED(17) 建立 GPIO17 LED。
  12. led.on() 開燈。
  13. led.off() 關燈。
  14. led.toggle() 反轉 LED 狀態。
  15. led.blink() 可以自動閃爍。
  16. blink() 預設 on/off 各一秒。
  17. pause() 可以讓 Background Blink Script 保持運作。
  18. while True 可以建立持續 GPIO 控制。
  19. Ctrl+C 會產生 KeyboardInterrupt。
  20. try / except / finally 適合做 GPIO Cleanup。
  21. 程式結束前應讓重要 Output 回到安全狀態。
  22. led.close() 可以釋放 GPIO Device。
  23. List 可以保存多個 LED Object。
  24. for Loop 可以依序控制多顆 LED。
  25. 4 顆 LED 可以製作基本流水燈。
  26. 8 顆 LED 可以製作跑馬燈。
  27. Forward + Reverse Loop 可以製作往返流水燈。
  28. 每顆 LED 都應有自己的限流 Resistor。
  29. 多顆 LED 可以共用 Ground Rail。
  30. GPIO_PINS 可以集中管理 Pin Assignment。
  31. Function 可以把燈光效果拆成可重複功能。
  32. all_on() 可以全部亮。
  33. all_off() 可以全部滅。
  34. flash_all() 可以完成全亮全滅效果。
  35. running_light() 可以封裝跑馬燈效果。
  36. Pi 5 的 GPIO Zero 底層應使用 lgpio。
  37. 目前 GPIO Zero 列出的 Pin Factory 中只有 lgpio 支援 Pi 5。
  38. GPIO Zero 可透過 Raspberry Pi OS 的 python3-gpiozero 安裝。
  39. Virtual Environment 可以使用 --system-site-packages 存取 APT GPIO Zero。
  40. 2026 年 7 月後 GPIO Zero 已修正 Pi 5 pip/lgpio 的相關安裝問題。
  41. 舊版 RPi.GPIO 本身不支援 Raspberry Pi 5。
  42. 舊 pigpio 也不應直接當作 Pi 5 新專案的預設方案。
  43. LED 不亮要同時 Debug Hardware 與 Software。
  44. Physical Pin 17 是 3.3V Power,不是 GPIO17。
  45. GPIO Output 不應直接驅動 Motor 或 Relay Coil。
  46. GPIO 的主要角色是控制訊號,而不是大電流 Power Supply。
  47. 5V Signal 不應直接進 Raspberry Pi GPIO。
  48. Breadboard Rail 不一定整條相通。
  49. 多 LED Project 出問題時應先縮小成單顆 LED 測試。
  50. 本章已完成 Raspberry Pi 第一個真正的 Physical Computing Project。

FAQ:Raspberry Pi LED 與 GPIO Output 常見問題

Q1:Raspberry Pi 5 要用哪個 Python GPIO Library?

本系列建議:

GPIO Zero

GPIO Zero 提供較容易閱讀的 Python Physical Computing API;在 Raspberry Pi 5 上,目前 GPIO Zero 應使用 lgpio Pin Factory。

Q2:RPi.GPIO 可以用在 Raspberry Pi 5 嗎?

原始 RPi.GPIO Library 本身不支援 Raspberry Pi 5 的新 GPIO 硬體架構。Raspberry Pi 官方 GPIO Best Practices 文件也明確指出這一點。

因此本系列不使用舊 RPi.GPIO 寫法。

Q3:GPIO Zero 要安裝嗎?

Raspberry Pi OS 官方 Image 通常已包含 GPIO Zero。

如果沒有:

sudo apt update
sudo apt install python3-gpiozero

GPIO Zero 官方目前提供這個 APT 安裝方式。

Q4:LED(17) 是 Physical Pin 17 嗎?

不是。

LED(17)

表示:

BCM GPIO17

也就是:

Physical Pin 11

GPIO Zero 預設使用 BCM Number。

Q5:Physical Pin 17 是什麼?

Physical Pin 17 是:

3.3V Power

不是 GPIO17。

這兩個不能混淆。

Q6:LED 要不要電阻?

要。

LED 必須使用適當限流 Resistor。

本系列基本 GPIO LED 實驗使用:

330Ω

Q7:330Ω 要放 LED 前面還是後面?

只要和 LED 串聯,放在 LED Anode 前或 Cathode 後,在這種簡單串聯電路中都能限制同一支路電流。GPIO Zero 官方 LED 文件也說明 Resistor 可以放在 LED 任一側。

本系列為了接線一致,統一:

GPIO
 ↓
330Ω
 ↓
LED
 ↓
GND

Q8:如何讓 LED 閃爍?

最基本:

from gpiozero import LED
from time import sleep

led = LED(17)

while True:
    led.on()
    sleep(1)

    led.off()
    sleep(1)

GPIO Zero 官方基本 Recipe 也採用相同概念。

Q9:GPIO Zero 有內建 blink() 嗎?

有。

from gpiozero import LED
from signal import pause

led = LED(17)

led.blink()

pause()

GPIO Zero 官方直接提供此 Recipe。

Q10:為什麼 blink() 需要 pause()?

blink() 預設在 Background 執行,因此主程式仍需要保持存在。

GPIO Zero 官方提醒,Script 到達結尾後 Process 結束,GPIO 可能被重設,因此 Recipe 使用 pause() 保持程式運行。

Q11:如何讓 LED 只閃 5 次?

可以:

led.blink(
    on_time=0.5,
    off_time=0.5,
    n=5,
    background=False
)

n 控制 Blink 次數。

Q12:如何停止 while True?

Terminal:

Ctrl + C

Python 會產生:

KeyboardInterrupt

可以用:

except KeyboardInterrupt:

做正常退出處理。

Q13:為什麼程式結束要 led.off()?

對 LED 來說,讓 Output 回到明確 Off State 比較容易預期。

對未來:

  • Relay
  • Motor Driver
  • Buzzer

等裝置更重要。

正式控制程式應該設計清楚:

程式離開時,硬體應該處於什麼狀態?

Q14:為什麼還要 led.close()?

close() 用來關閉 GPIO Zero Device 並釋放它使用的資源。

這對長期及結構化 Project 是良好的 Device Lifecycle 管理方式。

Q15:Raspberry Pi 5 GPIO Zero 顯示 BadPinFactory 怎麼辦?

Pi 5 要檢查:

GPIO Zero
+
lgpio

因為目前 GPIO Zero 文件指出 Pi 5 支援的 Pin Factory 是 lgpio。

Q16:可以在 venv 裡使用 GPIO Zero 嗎?

可以。

例如建立:

python3 -m venv .venv \
  --system-site-packages

然後:

source .venv/bin/activate

即可讀取 APT 安裝的 GPIO Zero。

Q17:可以使用 pip install gpiozero 嗎?

目前可以。

GPIO Zero 官方表示,Pi 5 過去的 pip/lgpio 相容問題已於 2026 年 7 月 2.0.1.post1 修復。

不過 Raspberry Pi OS 初學環境仍建議優先使用 APT 版本,減少套件環境混亂。

Q18:8 顆 LED 可以共用 GND 嗎?

可以共用同一個 Ground Reference。

例如所有 LED Cathode 接到 Breadboard GND Rail,再將 Rail 接 Raspberry Pi GND。

但是:

每顆 LED 仍應有自己的限流電阻。

Q19:GPIO 可以直接接高功率 LED 嗎?

不應直接這樣做。

GPIO 適合小電流 Control Signal。

高功率 LED 應使用:

  • Driver
  • Transistor / MOSFET
  • External Power
  • Appropriate Current Control

Q20:跑馬燈為什麼很適合學 GPIO?

因為它同時整合:

GPIO Output
+
Python List
+
for Loop
+
Function
+
Timing
+
Hardware Wiring

是從 Python 基礎跨入真正電子控制非常好的練習。

結語

完成這一章之後,我們終於真正做到:

Python
   ↓
GPIO Zero
   ↓
lgpio
   ↓
Raspberry Pi 5 RP1
   ↓
GPIO17
   ↓
LED
   ↓
ON / OFF

而且不只是控制一顆 LED。

我們已經從:

一顆 LED

一路擴充到:

2 LEDs
   ↓
4 LED Running Light
   ↓
8 LED Running Light
   ↓
Bidirectional Running Light
   ↓
全亮 / 全滅
   ↓
完整燈光循環程式

更重要的是,前面幾章看似彼此分開的知識:

Python Variable
Python List
for Loop
while Loop
Function
Exception
GPIO BCM Number
GPIO Voltage
Breadboard
Resistor

現在第一次真正整合成:

一個可以看得到實際動作的 Raspberry Pi 專案。

但是到目前為止,Raspberry Pi 還只有:

Output

也就是:

Raspberry Pi 告訴硬體要做什麼。

下一章我們要反過來:

讓外部硬體告訴 Raspberry Pi 發生了什麼。

也就是:

Button
   ↓
GPIO Input
   ↓
Python

接著我們就可以做到:

按一下按鍵
     ↓
LED ON

再按一下
     ↓
LED OFF

並進一步使用兩顆按鍵控制本章 8 顆 LED 跑馬燈的:

加速
+
減速

讓 Raspberry Pi 第一次真正具有:

人機輸入與互動控制能力。

下一章

第 9 章 Raspberry Pi GPIO Input 實作:按鍵輸入、Pull-up、Pull-down 與 Debounce

下一章將完整學習:

  • GPIO Input
  • Push Button
  • Normally Open Button
  • Floating Input
  • Pull-up
  • Pull-down
  • Internal Pull-up
  • Internal Pull-down
  • GPIO Zero Button
  • Button(27)
  • is_pressed
  • wait_for_press()
  • when_pressed
  • when_released
  • Event-driven Programming
  • Button 控制 LED
  • 按住亮、放開滅
  • 按一下切換 LED ON/OFF
  • toggle()
  • Mechanical Contact Bounce
  • Debounce
  • bounce_time
  • 按鍵誤觸發 Debug
  • 兩顆 Button
  • 加速按鍵
  • 減速按鍵
  • 控制第 8 章 8 顆 LED 跑馬燈速度
  • 建立 Raspberry Pi 第一個完整人機互動 GPIO 專案

完成第 9 章後,我們就同時具備:

GPIO Input
   +
GPIO Output

可以開始建立真正具有「感知 → 判斷 → 動作」能力的 Raspberry Pi 控制系統。

下一步學習

不要停在這一篇,接著把內容做成自己的實作

目前主題:Raspberry Pi。從完整學習路線、免費資源、會員下載,再接到實作所需材料。

同系列:Raspberry-Pi |  已是會員?直接前往 Getfile
相關資源與會員文章下載
文章可免費閱讀;下載完整 DOCX 或 PDF 需登入免費基本會員。
會員免費下載 DOCX 會員免費 PDF/列印

← 回文章列表