National Central University
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try an AI Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

3

Local AI

--

Uedu Code

--

中央大學 AQI 72 24°C PM2.5 13
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 07

PWM:調光與聲音

用脈波寬度調變控制亮度與蜂鳴器音高
Interaction 25 minute(s)

Learning Objectives

  • 說明 PWM 的週期、頻率與工作週期,算出平均電壓
  • 用 gpiozero 的 PWMLED 設定 LED 的亮度,寫出呼吸燈
  • 分辨有源與無源蜂鳴器,用 TonalBuzzer 依音名播放音階
  • 說明軟體 PWM 與硬體 PWM 的差別,以及什麼時候需要在意

只有開和關,怎麼做出「半亮」

上一課的 LED 只有兩種狀態:led.on() 讓腳位輸出 3.3V,led.off() 輸出 0V。樹莓派的 GPIO 是數位腳位, 沒有辦法直接輸出 1.65V 這種「中間」的電壓。

可是很多時候我們要的就是中間值:檯燈要能調亮度、蜂鳴器要能唱出不同的音、伺服馬達要轉到指定的角度。 這一課要回答:

  1. 只能開和關的腳位,怎麼讓 LED 看起來只有一半亮?
  2. 同一個技巧,為什麼也能讓蜂鳴器發出 Do、Re、Mi?
  3. gpiozero 的 PWMLED、TonalBuzzer 要怎麼用?

答案是脈波寬度調變(Pulse Width Modulation,PWM):開、關切換得非常快,再控制「開」佔了多少時間。

週期、頻率與工作週期

把腳位快速地開、關、開、關,電壓畫出來會是一串方波。描述它只需要兩個數字:

名詞 意思 例子
週期(period)T 開加關一輪花多少時間 10 ms
頻率(frequency)f 一秒有幾輪,= 1 ÷ 週期 1 ÷ 0.01 秒 = 100 Hz
工作週期(duty cycle) 一輪裡「開」佔幾 %,也就是高電位的時間 ÷ 週期 開 2.5 ms ÷ 10 ms = 25%

一個週期內的平均電壓= 3.3V × 工作週期。工作週期 25% 時平均是 0.825V,50% 是 1.65V。

LED 每秒亮暗 100 次,眼睛跟不上,看到的是平均的效果:工作週期越大,看起來越亮。 gpiozero 的 PWMLED 把這件事包好了:

from gpiozero import PWMLED
led = PWMLED(18)
led.value = 0.25      # 工作週期 25%:value 是 0~1 的小數

PWMLED 預設的頻率是 100 Hz(建立時可以用 frequency= 改)。value 寫 0 等於 off(),寫 1 等於 on()。 接線和上一課一樣:GPIO18 經過限流電阻接 LED 長腳,短腳接 GND。

逐步看:四種亮度

注意上方電路的 LED:每執行一次第 7 行,下一步亮度就換成新的工作週期。輸出列出每一種工作週期對應的平均電壓。

互動練習:用示波器看 PWM

示波器畫出腳位的電壓隨時間的變化,黃色虛線是平均電壓。拖動「頻率」與「工作週期」,再切換腳位上接的是 LED、伺服馬達還是蜂鳴器, 看同一種訊號在三種零件上各代表什麼。依序完成下面的任務。

呼吸燈:讓亮度慢慢變

亮度能調之後,把 value 一點一點加上去、再一點一點減下來,LED 就像在呼吸。最直接的寫法是迴圈:

for i in range(11):        # 0.0、0.1、…、1.0
    led.value = i / 10
    time.sleep(0.1)

gpiozero 也內建了 pulse():呼叫之後立刻回到你的程式,呼吸在背景一直進行,程式可以同時做別的事。 fade_in_time、fade_out_time 設定變亮與變暗各花幾秒。

下一個範例兩種都用。逐步動畫只會在「執行一行程式」時畫一次電路,所以背景的 pulse() 在 sleep 的那一步一口氣跑完; 想看它真的一明一暗,到下面的電路模擬器按播放。

逐步看:自己寫的呼吸與 pulse()

前兩個迴圈每 0.1 秒改一次亮度。第二個迴圈的 range 每次減 2,所以變暗比變亮快一倍。

蜂鳴器:頻率就是音高

蜂鳴器有兩種,外觀很像,用法完全不同:

有源蜂鳴器 無源蜂鳴器
裡面 自帶振盪電路 只有振動片,沒有振盪電路
怎麼讓它響 給高電位就響,音高固定 要送方波進去,方波的頻率就是聲音的頻率
gpiozero Buzzer(on、off、beep) TonalBuzzer(play、stop)

聲音是空氣的振動,每秒振動幾次就是頻率,頻率越高聽起來越高。國際標準音 A4(La)是 440 Hz, 高八度的 A5 是 880 Hz,低八度的 A3 是 220 Hz:每升高一個八度,頻率乘 2。

TonalBuzzer 的 play() 可以直接寫音名(例如 "C4"、"A4"),它會換算成頻率,送出工作週期 50% 的方波。 它預設以 A4 為中心,可以播上下各一個八度(A3~A5)的音;要更寬的範圍,建立時設定 octaves。

無源蜂鳴器的工作週期影響的是音色與音量,音高只看頻率。工作週期 0% 或 100% 時電壓沒有變化,振動片不會動,就不會響。

逐步看:Do Re Mi Fa Sol

看電路上蜂鳴器顯示的頻率:C4 約 262 Hz,往上每個音都比前一個高一些。

軟體 PWM 與硬體 PWM

PWM 可以用兩種方式產生:

  • 軟體 PWM:由程式(或函式庫的背景執行緒)按時間開、關腳位,任何 GPIO 都能用。樹莓派執行的是 Linux, 作業系統同時在做很多事,開關的時間點偶爾會晚一點點。LED 亮度差一點點看不出來,但伺服馬達對脈波寬度很敏感, 可能會微微抖動(第 11 課會再談)。
  • 硬體 PWM:由晶片裡專門的電路產生,時間很準,不受程式忙不忙影響。樹莓派只有少數腳位接得到硬體 PWM (例如 GPIO12、GPIO13、GPIO18、GPIO19,依型號與設定而定),通道數也很少。

gpiozero 會用哪一種,取決於它背後使用的「腳位工廠」(pin factory)與腳位;初學時不用管,寫法都一樣。 ESP32 這類微控制器有很多組硬體 PWM,「ESP32」軌第 05 課用同樣的觀念做呼吸燈、音階與伺服。

互動練習:調光與音階

電路上有一顆接 GPIO18 的 LED,以及一個接 GPIO17 的無源蜂鳴器。改程式、按「模擬執行」,依序完成任務:

  1. 先直接執行起始程式,看 LED 一級一級變亮。
  2. 改程式,讓 LED 最後停在約 30% 的亮度。
  3. 讓蜂鳴器依序播出 C4、E4、G4(Do、Mi、Sol)。
  4. 回答一個問題。

小測驗:PWM 的數字

1.

樹莓派的腳位輸出工作週期 25% 的 PWM,平均電壓大約是多少?

2.

PWMLED 預設的頻率是 100 Hz,一個週期是多久?

3.

下面的程式會印出什麼?(高電位時間=工作週期 × 週期,單位毫秒)

duty = 0.4
freq = 50
period_ms = 1000 / freq
print(duty * period_ms)
第 1 次作答

小測驗:亮度與聲音

1.

想讓 LED 看起來更亮,PWM 要改哪一個數字?

2.

一個蜂鳴器接上 3.3V 就會「嗶」一聲、音高固定,它是哪一種?該用 gpiozero 的哪個類別?

3.

A4 是 440 Hz,bz.play("A5") 送出的方波頻率大約是多少?

第 1 次作答

重點整理

  • PWM 用快速的開、關模擬中間值:頻率是一秒幾輪,工作週期是一輪裡高電位佔幾 %。
  • 平均電壓=3.3V × 工作週期;LED 看起來的亮度跟著工作週期走,頻率只要夠高、看不出閃爍。
  • PWMLED(腳位) 的 value 是 0~1;pulse() 在背景做呼吸燈,程式可以繼續做別的事。
  • 有源蜂鳴器通電就響(Buzzer);無源蜂鳴器靠方波的頻率決定音高(TonalBuzzer.play("C4")),高一個八度頻率乘 2。
  • 軟體 PWM 任何腳位都能用但時間不一定準;需要準確時序(例如伺服)時,考慮硬體 PWM。

下一課讀取類比訊號:樹莓派沒有類比輸入,要靠 ADC 晶片 MCP3008,把可變電阻轉到的位置變成數字。

這一課完成了!
Next lesson:讀取類比訊號:MCP3008 與 SPI
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。