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 80 24°C PM2.5 21
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 05

PWM:呼吸燈、音階與伺服

工作週期與頻率,控制亮度、音高與角度
Interaction 25 minute(s)

Learning Objectives

  • 說明 PWM 的頻率與工作週期,以及它們怎麼讓只有 0 與 1 的腳位「調出」中間值
  • 用 machine.PWM 與 duty_u16 調整 LED 亮度
  • 改變 PWM 頻率,讓無源蜂鳴器發出不同音高
  • 算出伺服馬達角度對應的脈波寬度與 duty_u16,控制伺服轉到指定角度

只有 0 與 1,怎麼調出一半的亮度

第 03 課的 LED 只有亮與暗兩種狀態,因為數位輸出只有 3.3V 與 0V。可是生活中的裝置常常需要「中間值」: 檯燈要調亮度、喇叭要發出不同的音、伺服馬達要轉到某個角度。

第 03 課的互動練習最後一題提過:把 sleep 拿掉,LED 亮暗切換得非常快,人眼看起來就是半亮。 這個想法做成硬體功能,就是脈波寬度調變(PWM,Pulse Width Modulation): 腳位以固定的節奏重複「高一段時間、低一段時間」,由硬體負責切換,程式只要設定兩個數字。

頻率與工作週期

         ┌────┐      ┌────┐      ┌────┐
 3.3V    │    │      │    │      │    │
   0V ───┘    └──────┘    └──────┘    └────
         |←高→|
         |←── 週期 ──→|
名稱 意思 例子
週期(period) 重複一次「高+低」花的時間 1 ms
頻率(frequency) 一秒重複幾次,等於 1 ÷ 週期 1 ÷ 0.001 秒 = 1000 Hz
工作週期(duty cycle) 一個週期裡高電位占的比例 高 0.25 ms ÷ 週期 1 ms = 25%

工作週期 25% 時,腳位的平均電壓大約是 3.3V × 25% ≈ 0.8V。LED、馬達這類反應比較慢的元件, 感受到的就是這個平均值,所以工作週期越大,LED 越亮。

三種用途,看的數字不一樣

用途 頻率 工作週期
LED 調光 夠快就好(例如 1000 Hz),人眼不會察覺閃爍 決定亮度
無源蜂鳴器 決定音高(例如 262 Hz 是 Do) 常用 50%;0 就安靜
伺服馬達 固定 50 Hz 高電位的時間長短決定角度

MicroPython 的 machine.PWM

from machine import Pin, PWM

led = PWM(Pin(23), freq=1000, duty_u16=32768)   # 1000 Hz、工作週期 50%
led.duty_u16(16384)      # 改成 25%
led.freq(2000)           # 改頻率
led.deinit()             # 關閉 PWM,腳位停止輸出
  • duty_u16(數值):工作週期用 0~65535 表示,0 是 0%,65535 是 100%。這個寫法在 ESP32、Raspberry Pi Pico 等不同開發板上都一樣,建議使用。
  • 舊程式常見 duty(數值),範圍是 0~1023(512 約是 50%)。ESP32 的 MicroPython 還能用,看到時知道是同一件事。
  • 建立 PWM 時沒有指定工作週期,ESP32 預設是 50%;接伺服馬達時,最好一開始就給一個合理的值。

ESP32 的 PWM 頻率可以從 1 Hz 設到 40 MHz,但頻率越高,工作週期能分得越細的程度(解析度)就越低。 原版 ESP32 有 16 個 PWM 通道,可以同時輸出 16 個不同的工作週期,但只有 8 種不同的頻率; 大部分專題用不到這麼多,知道有上限就好。以上數字以 MicroPython 官方文件的 ESP32 快速參考為準。

逐步看:調整 LED 亮度

每執行一次 led.duty_u16(duty),上方的 LED 亮度就跟著改變。看 duty 怎麼從百分比算出來。

呼吸燈與亮度的感覺

把上面的迴圈改成每次只差一點點,例如每 20 ms 增加 1%,亮度就會平順地變亮再變暗,像在呼吸:

while True:
    for p in range(0, 101):              # 漸亮
        led.duty_u16(p * 65535 // 100)
        time.sleep_ms(20)
    for p in range(100, -1, -1):         # 漸暗
        led.duty_u16(p * 65535 // 100)
        time.sleep_ms(20)

這樣的迴圈步數很多,不適合逐步播放;在下面的互動練習裡可以試試看。 你可能會發現:工作週期從 0% 到 25% 時亮度變化很明顯,75% 到 100% 卻感覺差不多。 人眼對亮度的感覺不是線性的,商業產品常把數值先經過一條曲線再送出,讓變化看起來比較均勻。

逐步看:蜂鳴器的音階

蜂鳴器有兩種:有源蜂鳴器裡面有振盪電路,接上高電位就響,音高固定; 無源蜂鳴器需要外面送進一定頻率的訊號,頻率就是音高。這個範例接的是無源蜂鳴器,看上方蜂鳴器顯示的頻率。

伺服馬達:用脈波寬度決定角度

伺服馬達(servo)裡面有馬達、齒輪、位置感測與控制電路,你只要告訴它「轉到幾度」,它會自己轉過去並停住。 告訴它的方式就是 PWM:

  • 頻率固定 50 Hz,也就是每 20 ms 送一個脈波
  • 脈波高電位維持多久決定角度。常見的小型伺服大約是 0.5 ms 對應 0°、2.5 ms 對應 180°(有些型號是 1~2 ms,實際範圍要看規格)

換算成 duty_u16:

脈波寬度(微秒)= 500 + 角度 × 2000 ÷ 180
duty_u16       = 脈波寬度 ÷ 20000 × 65535
90 度 → 1500 μs → 1500 ÷ 20000 × 65535 ≈ 4915

伺服馬達轉動時電流比較大,最好用獨立的 5V 電源供電,並把電源的 GND 和 ESP32 的 GND 接在一起;ESP32 只負責送訊號。馬達與電源的細節在「自造者入門」軌第 09 課。

逐步看:伺服轉到指定角度

看 set_angle 怎麼把角度換成脈波寬度,再換成 duty_u16;上方的伺服臂會轉到對應的角度。

互動練習:伺服掃描與小旋律

電路上有一個伺服馬達(GPIO18)與一個無源蜂鳴器(GPIO25)。起始程式讓伺服轉到 90 度,蜂鳴器響一聲 440 Hz。依序完成任務:

  1. 直接執行起始程式。
  2. 讓伺服從 0 度慢慢轉到 180 度(例如每 10 度停 0.1 秒)。
  3. 讓蜂鳴器依序播出 Do(262 Hz)、Mi(330 Hz)、Sol(392 Hz)。
  4. 回答一個問題。

小測驗:頻率與工作週期

1.

PWM 的頻率是 500 Hz,一個週期是多少?

2.

下面的程式會印出什麼?

percent = 40
print(percent * 65535 // 100)
3.

想讓無源蜂鳴器的聲音變高,要改哪一個?

第 1 次作答

小測驗:伺服的換算

1.

用本課的公式(0° = 500 μs、180° = 2500 μs、週期 20000 μs),下面的程式會印出什麼?

angle = 135
pulse_us = 500 + angle * 2000 // 180
print(pulse_us, pulse_us * 65535 // 20000)
2.

舊程式寫 servo.duty(77),這是用哪一種範圍表示工作週期?

第 1 次作答

重點整理

  • PWM 讓腳位快速重複高、低電位:頻率是一秒重複幾次,工作週期是高電位占的比例。
  • PWM(Pin(編號), freq=頻率, duty_u16=數值) 建立;duty_u16() 範圍 0~65535,freq() 改頻率,deinit() 關閉。舊的 duty() 範圍是 0~1023。
  • LED 調光看工作週期;無源蜂鳴器的音高看頻率;伺服馬達用 50 Hz,脈波寬度(約 0.5~2.5 ms,依型號)決定角度。
  • ESP32 的 PWM 頻率可設 1 Hz~40 MHz,頻率越高解析度越低;原版 ESP32 有 16 個通道、8 種頻率。
  • 伺服馬達用獨立電源供電,GND 要和 ESP32 共地。

下一課反過來讀「中間值」:用 ADC 讀取可變電阻與光敏電阻的電壓。

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