RaspberryPi の PWM 出力で DC モーター制御

はじめに

カムロボを動かしたときに調べた,RasPi の PWM を簡単に動かすための備忘.

カムロボを作った際は /sys/class/gpio の仮想ファイルシステムを使って GPIO にアクセスした.PWM でも同様に仮想ファイルシステムを使って簡単に動作確認してみる.

PWM 出力テスト

デバイスツリーオーバレイを使って PWM を有効にする.ここでは GPIO12 と GPIO13 を PWM 出力に利用する.

$ dtoverlay -a | grep pwm
  i2c-pwm-pca9685a
  pwm
  pwm-2chan
  pwm-ir-tx

$ dtoverlay -h pwm-2chan
Name:   pwm-2chan

Info:   Configures both PWM channels
        Legal pin,function combinations for each channel:
          PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0)            52,5(Alt1)
          PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1)
        N.B.:
          1) Pin 18 is the only one available on all platforms, and
             it is the one used by the I2S audio interface.
             Pins 12 and 13 might be better choices on an A+, B+ or Pi2.
          2) The onboard analogue audio output uses both PWM channels.
          3) So be careful mixing audio and PWM.
          4) Currently the clock must have been enabled and configured
             by other means.

Usage:  dtoverlay=pwm-2chan,<param>=<val>

Params: pin                     Output pin (default 18) - see table
        pin2                    Output pin for other channel (default 19)
        func                    Pin function (default 2 = Alt5) - see above
        func2                   Function for pin2 (default 2 = Alt5)
        clock                   PWM clock frequency (informational)

$ sudo dtoverlay pwm-2chan pin=12 func=4 pin2=13 func2=4

Alt は Alternate Function のこと.Alt を設定することで各 IO に機能を割り当てることができる.

PWM を有効にすると /sys/class/pwm//pwmchip0 以下に仮想ファイルシステムが見えるようになる.次に export へのリダイレクトで 2 系統の PWM(pwm0,pwm1) を有効にする.

$ ls /sys/class/pwm//pwmchip0
device  export  npwm  power  subsystem  uevent  unexport
$ echo 0 > /sys/class/pwm/pwmchip0/export 
$ echo 1 > /sys/class/pwm/pwmchip0/export 
$ ls /sys/class/pwm//pwmchip0/
device  export  npwm  power  pwm0  pwm1  subsystem  uevent  unexport

pwm0 や pwm1 ディレクトリ以下には PWM の設定に必要な仮想ファイルが配置してある.代表的な物は次の通り.

ファイル名用途
periodPWM の周期を nsec 単位で設定
duty_cyclepolarity=normal: HIGH 期間のパルス幅を nsec 単位で設定
polarity=inversed: LOW 期間のパルス幅を nsec 単位で設定
polarityPWM の極性を設定.
normal: 正転
inversed: 反転
enablePWM の動作を設定
0: 出力停止
1: 出力開始

SG-90 のようなサーボを想定し,PWM 周期を 20ms,パルス幅を 10ms (デューティ比 50%),と設定して出力波形を確認してみる.

$ ls /sys/class/pwm/pwmchip0/pwm1 
capture  duty_cycle  enable  period  polarity  power  uevent
$ # 周期設定 20ms
$ echo 20000000 > /sys/class/pwm/pwmchip0/pwm1/period
$ # パルス幅設定 10ms
$ echo 10000000 > /sys/class/pwm/pwmchip0/pwm1/duty_cycle
$ # 出力開始
$ echo 1 > /sys/class/pwm/pwmchip0/pwm1/enable
$ # 出力停止
$ echo 0 > /sys/class/pwm/pwmchip0/pwm1/enable 

鈍り無くきれいに出力出来ていた.

PWM と MX1508 による DC モーターの調速制御

RasPi の PWM ポートは別途拡張するとして,DC モーターの調速動作確認だけしてみる.前回の配線図の IN1〜4 のどれかに RasPi の PWM 信号を入力する.

処理内容は次の通り.デューティ比を 0〜100% まで 25% ずつ増やしていく.

#!/bin/bash
# start
echo 1 > /sys/class/pwm/pwmchip0/pwm1/enable

# speed up
echo "duty 0%"
echo 0 > /sys/class/pwm/pwmchip0/pwm1/duty_cycle
sleep 2
echo "duty 25%"
echo 5000000 > /sys/class/pwm/pwmchip0/pwm1/duty_cycle
sleep 2
echo "duty 50%"
echo 10000000 > /sys/class/pwm/pwmchip0/pwm1/duty_cycle
sleep 2
echo "duty 75%"
echo 15000000 > /sys/class/pwm/pwmchip0/pwm1/duty_cycle
sleep 2
echo "duty 100%"
echo 20000000 > /sys/class/pwm/pwmchip0/pwm1/duty_cycle
sleep 2

# stop
echo 0 > /sys/class/pwm/pwmchip0/pwm1/enable

Python RPi.GPIO で PWM

参考までに Python でも PWM 出力を試してみる.使ったライブラリは RPi.GPIO.まともなリファレンスは SourceFoge の Wiki だけ?

RPi.GPIO
A module to control Raspberry Pi GPIO channels
raspberry-gpio-python / Wiki / PWM

適当にコードを書いた.こんな感じ.

#############################
# usage: ./pwm_sound_test.py freq dc bt
#   freq: Frequency in Hz
#   dc:   Duty in percentage
#   bt:   beep time in sec
#############################
import RPi.GPIO as GPIO
import time
import sys

# INIT
if len(sys.argv) != 4:
    print('[ERROR] missing args')
    exit()

GPIO.setmode(GPIO.BCM)
pwm_pin = 13
GPIO.setup(pwm_pin, GPIO.OUT)
pwm = GPIO.PWM(pwm_pin, 50)    # Duty 50%

freq = int(sys.argv[1])
dc   = float(sys.argv[2])
bt   = float(sys.argv[3])

# MAIN
pwm.start(dc)
pwm.ChangeFrequency(freq)
time.sleep(bt)
pwm.stop()
GPIO.cleanup()

波形はデバイスツリーオーバレイとあまり変わらず.

おわりに

RasPi で PWM の出力方法とその波形を確認した.MX1508 の入力に利用することでモーターの回転速度も制御できる.カムロボにちゃんと PWM 制御を組み込むのはまた後日.

ちなみに波形確認に使った WAVE2 の話はこちら.

コメント

タイトルとURLをコピーしました