2016年1月4日 星期一

[Raspberry PI] PWM


PWM,Pulse Width Modulation,以數位方式控制高低電位週期比例來達到模擬類比電壓的效果,比方說控制馬達速度、LED燈亮度...

值得一提的是,因為是模擬的方式所以PWM訊號頻率其實也會出現在輸出訊號的頻譜裏,當然也要輸出裝置頻寬夠高才能夠被察覺.

樹莓派身為一塊萬用開發版當然有辦法輸出PWM,目前查到有下面幾個方法:


  • RPi.GPIO
    • 指令下達方式:Python
    • PWM生成方式:軟體模擬
    • 安裝
        • #sudo apt-get install python-dev python-rpi.gpio
    • 用法:
        • #sudo python #進入Python
        • >>import RPi.GPIO as GPIO
        • >>GPIO.setmode(GPIO.BCM)
        • >>GPIO.setup(18, GPIO.OUT)    #設定GPIO18為輸出腳
        • >>pwm = GPIO.PWM(18, 500)   #建立PWM實例,在GPIO18輸出,頻率為500Hz
        • >>pwm.start(100) #開始輸出DUTY=100%的脈波
    • 心得:
      • 用在伺服馬達(Servo)上會感覺到顫振,確實是用軟體方式來輸出,持續輸出脈寬的重複性不佳,大概只適合做LED燈控制等人機應用.
      • 軟體輸出方式大概是以系統內建計時器,去計時控制輸出腳位為高位/低位,由於Linux並非即時系統,各行程(process)無法保證被定時呼喚,因此即便系統計時器是可靠的,在上位做控制的行程也沒辦法總是在計時到達的當下去處理.



  • RPIO
    • 指令下達方式:Python
    • PWM生成方式:半軟體模擬?(文件上寫著透過DMA通道,不太清楚背後機制)
    • 安裝
        • #sudo apt-get install python-setuptools
        • #sudo easy_install -U RPIO
    • 用法:
        • #sudo python #進Python
        • >> from RPIO import PWM
        • >> servo = PWM.Servo()           #建立一個Servo實例,預設週期為50Hz
        • >> servo.set_servo(18,1500)    #在GPIO18上持續輸出脈寬為1500us的脈波
        • >> servo.set_servo(19,10000)  #在GPIO19上持續輸出脈寬為10000us的脈波
    • 心得:
        • 發現如果將其中一隻Pin輸出關閉,所有輸出都會被關閉,不知道是不是BUG?
        • 可以多通道輸出(但不曉得通道代表什麼意思),比方說
          • >> servo0 = PWM.Servo(0)
          • >> servo1 = PWM.Servo(1)
          • 如此就建立了兩個Servo物件對應到不同的DMA通道,但操作起來仍發現會相互干擾
        • 顫陣比GPIO小,但仍能感受到.


  • pigpio
    • 指令下達方式:pipe 、c-interface、python
    • PWM生成方式:軟體模擬(p指令)、硬體輸出(hp指令)

      • #git clone https://github.com/joan2937/pigpio #跟上最新版
      • cd PIGPIO
      • make
      • sudo make install

    • 用法(pipe方式):

      • #sudo pigpiod #喚起掌管輸出入的專用daemon
      • #pigs  p 19 255 #在GPIO19上輸出DUTY 100%的PWM信號(軟體模擬輸出)
      • #pigs hp 18 100 500000#在GPIO18上輸出頻率為100Hz DUTY為50%的PWM信號(硬體直接輸出)

    • 心得:
      • "硬"PWM,直接用樹莓派BCM2835晶片內建兩個底層PWM輸出單元生成PWM信號,直接以IC輸出信號重複性一定是最穩定的,也就是脈寬不會有忽大忽小的問題
        • pigpio只是作為寫入晶片上特定registor的API罷了
      • BCM2835只有兩個PWM通道(Channel),甚至在Pi2上只有一隻引腳被接到介面IO上,而Raspberry PI B+則有GPIO18,GPIO19可用.
      • 操作起來真的是顫陣最低的(滿意)!
      • 另外要說pigpio的shell指令很豐富,初期拿來測試硬體相當順手,文件也建立的很完整(滿意)!
      • 各型Raspberry PI GPIO表:http://elinux.org/RPi_BCM2835_GPIOs
從BCM2835文件可以發現這塊晶片頂多只能輸出兩個PWM信號,真要再多的話就要以通訊方式(I2C UART)送出命令透過PWM IC代為輸出穩定的PWM信號了,類似透過這樣的晶片

後記:
即便是用了Hardware PWM,功率電路之間的相互干擾也是另一令人頭痛的因素....尚待努力


其他參考:
BCM2835硬體Sheet



沒有留言:

張貼留言