RaspberryPi

RPi.GPIOでPWM信号を出力する

RPi.GPIO

RPi.GPIOとは、GPIOの制御用ライブラリの一つです。

GPIO制御ライブラリは他にもpigpio(後述)があります。

RPi.GPIOはRaspbianではデフォルトでインストールされているので、いきなりimportして使用することができます。

使用したコード

いきなりですが、コードです。

#coding=utf-8

import RPi.GPIO as GPIO
from time import sleep

GPIO.setmode ( GPIO.BCM )
GPIO.setup ( 18, GPIO.OUT)
pi = GPIO.PWM ( 18, 50 )  #( pin, Hz )
pi.start ( 0 )

try:
    while True:
        duty = 50 
        pi.ChangeDutyCycle( duty )

except KeyboardInterrupt:
    pass
p0.stop()
GPIO.cleanup()

使用するピンの宣言

GPIO.setmode ( GPIO.BCM )
GPIO.setup ( 18, GPIO.OUT)

ピン番号の指定方法(GPIO番号で指定)と、ピンモードが出力であることを宣言しています。

周波数を設定

pi = GPIO.PWM ( 18, 50 ) #( pin, Hz )

PWM信号を出力するピン番号と周波数を設定します。

ここでは、GPIO18から50Hzの矩形波を出力する設定になっています。

PWM信号を出力する

pi.start ( 0 )

ここで矩形波を出力しています。引数にはデューティ比が入ります。

ここでは説明の都合上0%に設定しています。

PWM信号の出力中にデューティ比を変更する

try:
 while True:
  duty = 50
  pi.ChangeDutyCycle( duty )

ChangeDutyCycle関数を用いることで、PWMの波形を出力している途中でもデューティ比を変更することができます。

後述のようなチョット応用したプログラムなどで使用できます。

例外処理

except KeyboardInterrupt:
 pass
p0.stop()
GPIO.cleanup()

Ctrl+Cのショートカットが押下された場合の処理です。

PWMの出力を停止し、GPIOの出力設定をリセットします。

オシロで見てみた

手元のオシロスコープで観測してみました。

ちゃんと50Hzかつ50%のデューティ比の矩形波が出力されていました。

チョット応用

ちょっとしたプログラムを組みました。

デューティー比が0%から100%に増えていき、100%から0%まで減少するのを繰り返します。

これでモーターを制御するならば、速度が上がっていき、だんだんゆっくりになっていきます。

#coding=utf-8

import RPi.GPIO as GPIO
from time import sleep

GPIO.setmode ( GPIO.BCM )
GPIO.setup ( 18, GPIO.OUT)
pi = GPIO.PWM ( 18, 50 )  #( pin, Hz )
pi.start ( 0 )

try:
    while True:
        for i in range(0, 100):
            duty = i
            pi.ChangeDutyCycle( duty )
            sleep(0.1)
        for i in range(0, 100):
            duty = 100 - i
            pi.ChangeDutyCycle( duty )
            sleep(0.1)

except KeyboardInterrupt:
    pass
pi.stop()
GPIO.cleanup()

問題点

RPi.GPIOを用いて50HzのPWM信号を出力することができますが、問題点があります。

それは高い周波数を安定して出すことができないのです。また、精度もそこまで良くありません。※筆者が試したところ8kHz辺りで頭打ちになりました…..

また、人の可聴域は20Hz~20kHzと言われていますので、この周波数帯でDCモーター等をPWM制御すると鳴きの原因となります。

解決策

pigpioという比較的新しいGPIO制御ライブラリを用いる方法があります。

pigpioでは、高時間分解能でのGPIO制御を可能としています。

ただし、デーモン(常駐ソフト)を起動しておく必要があり、事前にインストール作業や設定作業が必要となります。