はじめに
カムロボを動かしたときに調べた,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 の設定に必要な仮想ファイルが配置してある.代表的な物は次の通り.
ファイル名 | 用途 |
---|---|
period | PWM の周期を nsec 単位で設定 |
duty_cycle | polarity=normal: HIGH 期間のパルス幅を nsec 単位で設定 polarity=inversed: LOW 期間のパルス幅を nsec 単位で設定 |
polarity | PWM の極性を設定. normal: 正転 inversed: 反転 |
enable | PWM の動作を設定 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 だけ?
適当にコードを書いた.こんな感じ.
#############################
# 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 の話はこちら.
コメント