PWM=Pulse Width Modulation,
通過調整數位脈衝的週期以及在週期中的寬度占比, 來模擬類比信號輸出
像是控制馬達轉速, 舵機角度, 燈號強度...等
目前樹莓派有幾種作法
一是通過軟體控制, 優點是每隻GPIO腳都可以發出, 數量不受限
缺點是占用CPU計算資源, 太多PWM有可能會延遲
另外是寬度占比只能設定0~100, 較不精準
二是硬體控制,
脈衝非常準確, 寬度可以設定0~1,000,000
但在樹莓派上一次只能產生兩組, BCM 12/18共用通道0, BCM 13/19共用通道1
三是DMA控制, 介於兩者之間
通常由擴充版提供, 精準度依板子不同而異
以GrovePi+來說脈衝寬度可以設定0~255的範圍, 僅D3/D5/D6可提供
================================
軟體控制PWM程式碼
================================
import RPi.GPIO as GPIO
import time
LedPin = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(LedPin, GPIO.OUT) # Set pin mode as output
p = GPIO.PWM(LedPin, 1000) # set Frequece to 1KHz
p.start(0) # Start PWM output, Duty Cycle = 0
try:
while True:
for dc in range(0, 101, 5): # Increase duty cycle: 0~100
p.ChangeDutyCycle(dc) # Change duty cycle
time.sleep(0.05)
time.sleep(1)
for dc in range(100, -1, -5): # Decrease duty cycle: 100~0
p.ChangeDutyCycle(dc)
time.sleep(0.05)
time.sleep(1)
except KeyboardInterrupt:
p.stop()
GPIO.cleanup()
================================
================================
硬體PWM程式碼, 必須先安裝pigpio庫, 並執行sudo pigpiod
================================
import pigpio
import time
PWM_LED_PIN = 18
PWM_FREQ = 1000
pi = pigpio.pi()
try:
while True:
for i in range(0, 50, 1):
pi.hardware_PWM(PWM_LED_PIN, PWM_FREQ, i*20000)
time.sleep(0.1)
for i in range(49, -1, -1):
pi.hardware_PWM(PWM_LED_PIN, PWM_FREQ, i*20000)
time.sleep(0.1)
except KeyboardInterrupt:
pi.set_mode(PWM_LED_PIN, pigpio.INPUT)
================================
================================
GrovePi+ PWM程式碼
================================
import grovepi
import time
led = 5 # Connect the Grove LED to digital port D5
grovepi.pinMode(led,"OUTPUT")
try:
while True:
for i in range(0, 256, 15): #Increment brightness for next iteration
grovepi.analogWrite(led,i) # Give PWM output to LED
time.sleep(.3)
for i in range(255, -1, -15):
grovepi.analogWrite(led,i) # Give PWM output to LED
time.sleep(.3)
except KeyboardInterrupt:
grovepi.analogWrite(led,0)
================================