更新於 2023/01/19閱讀時間約 6 分鐘

樹莓派筆記RaspberryPi -(7) LED 呼吸燈 (PWM 控制)

    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)

    ================================

     

     

    分享至
    成為作者繼續創作的動力吧!
    © 2024 vocus All rights reserved.