【Raspberry Pi】PWM制御でDCモーターの回転速度を変化させよう!

「Raspberry PiでDCモーターに電圧を加えても、回転速度は一定。モーターの回転速度ってどうやって制御するんだろう?」

これを解決するのがPWM制御です。

本記事では、Raspberry PiのPWM制御機能を使ってDCモーターの回転速度を変化させる方法について解説します。

▼今回の記事の完成形はこちら

この記事はこんな人におすすめ!
 ・DCモーターの回転速度を変化させるPWM制御について学びたい人
 ・Raspberry PiのPWM制御機能について知りたい人
 ・Raspberry Piを使った電子工作を始めてみたい人

DCモーターの動かし方がまだ分からない人はこちらの記事がおすすめです。

あわせて読みたい
Raspberry PiとTA7291PでDCモーターを正転/逆転する仕組みと方法 Raspberry Piを購入したら、ロボットやラジコンカーを作ってみたくなりませんか? ロボットやラジコンを動かすにはモーターを制御する必要があります。今回のポイントは...

それでは始めていきましょう!

プログラミング言語の人気オンラインコース
目次

DCモーターの速さを変えるPWM制御とは?

PWMはPulse Width Modulation(パルス幅変調)の略です。デジタル信号をON/OFF繰り返すことでパルス(矩形波)波とするとともに、ON/OFF時間割合を変え、パルス信号幅を変化させる手法です。

PWM制御がなぜDCモーター回転速度を変化させることと関係があるの?

デジタル信号ON/OFFを繰り返し、電圧値を制御

DCモーターの回転速度は、印加電圧に比例する特性を持っています。

しかし、Raspberry PiのGPIOからの電圧出力はHigh(3.3V)かLow(0V)かON/OFFでしか制御出来ません。

これではDCモーターの回転速度を可変にすることが出来ないです。

そこで、電圧出力をON/OFF繰り返しパルスとすることで、0~3.3Vの間を調整したのと同様な効果が得られます。

下図のように電圧出力ON/OFFの周期をパルス周期、ON時間をパルス幅と呼びます。

電圧値を決めるDuty比

Duty比とは、パルス周期に対するパルス幅の比のことです。

Duty比を変化させると下図のような電圧波形となります。

100%だと、ずっと電圧出力はHigh(3.3V)。0%だと、ずっと電圧出力はLow(0V)です。

PWM周期を短くするとモーター動きはスムーズになる

PWM周期は、電圧出力ON/OFF 1回あたりの時間です。周期によって電圧平均は変わりません。

では、PWM周期はどんな役割があるのでしょうか。

周期が長いとパルス1回あたりの電圧出力OFF時間が長くなります。電圧出力OFFではモーターが止まろうとするため、周期が長いとモーターがガクガク動き、スムーズに回転しなくなります。このため、モーター回転をスムーズに回すためには、PWM周期は短い方が良いです。

ただし、PWM周期を短くするデメリットもあります。

  • ソフトウェア負荷が増える
  • 高周波音が発生する
【Pythonではじめる】ラズベリーパイと電子工作入門 | Udemy

Raspberry PiでPWM制御する方法

ハードウェアPWMとソフトウェアPWM

Raspberry PiではPWMを行う方法は2つあります。ハードウェアPWMとソフトウェアPWMです。

ハードウェアPWMは、前述のソフトウェア負荷が増えるデメリットが発生しません。しかし、ハードウェアPWMが出来るGPIOは限られています。GPIO12, GPIO13, GPIO18, GPIO19の4つです。この内、GPIO12とGPIO18、GPIO18とGPIO19は連動し、独立に制御できるGPIOは2つまでです。

  • Channel 0: GPIO 12、 GPIO 18
  • Channel 1: GPIO 13、 GPIO 19

ソフトウェアPWMはすべてのGPIOで実行できます。

RPi.GPIOモジュールを使えばソフトウェアPWMが簡単にプログラミングできる

Raspberry Piでは、簡単にPWM制御を実装出来るRPi.GPIOというモジュールがあります。今回の記事では、RPi.GPIOを使ってPWM制御を行っていきます。

しかし、残念なことにRPi.GPIOはハードウェアPWMをサポートしていません。今回はソフトウェアPWMのみの解説です。

Note that the current release does not support SPI, I2C, hardware PWM or serial functionality on the RPi yet.

https://pypi.org/project/RPi.GPIO/

RPi.GPIOの使い方は↓の記事で解説していますので、今回はPWM制御部のみの解説になります。

あわせて読みたい
Raspberry PiのGPIO端子電圧を制御してLEDを点滅 Raspberry Piから指令を与えて様々な電子デバイスを制御してみたいですよね。 GPIO出力電圧制御の基本をマスターすれば、様々な電子デバイス制御に応用出来ます! 今回...

PWMインスタンスの生成

p = GPIO.PWM(channel, frequency)

クラス内の関数を実行するためにPWMインスタンスを生成します。

第1引数のchannelは、PWM制御したいGPIO端子番号を指定します。BCM番号を指定するかGPIO番号を指定するかは、GPIO.setmode()での設定次第になります。PWMインスタンスを生成した後は、p.の後に関数名を指定することで、指定した関数が実行できます。

第2引数のfrequencyはPWM周波数で、単位は[Hz]です。PWM周期[s]は、1/frequencyになります。

PWM制御の開始

p.start(dc)

PWM制御を開始するにはp.start()を実行します。引数のdcはDuty比で、単位は[%]です。0~100%の範囲で指定してください。

PWM周期の変更

p.ChangeFrequency(frequency)

PWM周波数はPWMインスタンス生成時に設定しますが、p.ChangeFrequency()でPWM周波数を変更することができます。引数のfrequencyは変更するPWM周波数で、単位は[Hz]です。

Duty比の変更

p.ChangeDutyCycle(dc)

p.ChangeDutyCycle()でPWM開始中でもDuty比を変更することができます。引数のdcは変更するDuty比で、単位は[%]です。

PWM制御を停止

p.stop()

PWM制御を停止する場合には、p.stop()を実行します。

実際にプログラミングしてみよう!

準備したもの

  • Raspberry Pi Zero WH
  • DCモーター
  • モータードライバ TA7291P
  • ブレッドボード
  • ジャンパワイヤ オス-メス
  • 電池ボックス
  • 単三電池 × 2

回路図

こちらが回路構成となります。

端子記号端子説明接続先
Vccロジック側電源端子Raspberry Pi +5V端子
Vs出力側電源端子電池+極
Vref制御電源端子電池+極 (3kΩ以上の保護抵抗を介す)
GNDGNDRaspberry Pi GND & 電池ー極
IN1入力端子1Raspberry Pi GPIO 27
IN2入力端子2Raspberry Pi GPIO 22
OUT1出力端子1モーター +極
OUT2出力端子2モーター ー極

モータードライバICへPWM信号を入力する

モータードライバIC TA7291Pでモーターを駆動するには、2つの電圧信号が必要です。PWM信号は下表のように入力することでモーターの回転速度を変化できます。

IN1(GPIO 27)IN2(GPIO 22)モード
00ストップ
PWM0正転
0PWM逆転
11ブレーキ
長らく電子工作で愛用されてきたTA7291Pが生産停止になりました。TA7291Pの代替として、DRV8835などがあります。モータードライバICが変わると端子配列や指令方法は異なりますが、Hブリッジ回路の仕組みが分かっていれば、使い方は基本的に同じです。

サンプルプログラム

Duty比 80%、PWM周波数 50Hzでモーターを駆動するサンプルプログラムを紹介します。「e」キーを押すとモーターが正転、「d」キーを押すと逆転、「q」キーを押すと停止するようにしました。

import RPi.GPIO as GPIO
import sys

duty = 80

#GPIO初期設定
GPIO.setmode(GPIO.BCM)
GPIO.setup(27, GPIO.OUT)
GPIO.setup(22, GPIO.OUT)

p1 = GPIO.PWM(27, 50) #50Hz
p2 = GPIO.PWM(22, 50) #50Hz
            
p1.start(0)
p2.start(0)

try:
    while True:
        #「e」キーが押されたら前進
        c = sys.stdin.read(1)
        if c == 'e':
            p1.ChangeDutyCycle(duty)
            p2.ChangeDutyCycle(0)
              
        #「d」キーが押されたら後退
        if c == 'd':
            p1.ChangeDutyCycle(0)
            p2.ChangeDutyCycle(duty)

        #「q」キーが押されたら止まる
        if c == 'q':
            p1.ChangeDutyCycle(0)
            p2.ChangeDutyCycle(0)

except KeyboardInterrupt:
    pass

GPIO.cleanup()

Duty比を変化させて、モーター回転速度が変化するのを確認してみる

PWM制御のDuty比を変化させたときのモーター回転速度の違いを実験しました。

Duty比は70%→85%→100%と変化させましたので、その違いを見て下さい。

何だこのマシンは!?準備したものに入ってないじゃないかと思われたかもしれません。

ヴィストン社のビュートローバーH8が埃かぶっていましたので、H8マイコン部を取り除き、Raspberry Piを載せたマシンです。

ただモーターを回すだけでは回転速度の違いが分かりにくいので、分かりやすいようにこのようにしています。

このマシンの製作記は別記事で紹介しています。

あわせて読みたい
【Raspberry Pi】スマホで動くラジコンカーを製作(車体編) Raspberry Piをいじっていると作りたくなるのが、ラジコンカー。今回、WebIOPiを使ってスマホから操作するラジコンカーを製作したので、記事にします。 ゆくゆくはライ...

このマシンにはタミヤ製のダブルギヤボックスが載っていますので、片側のモーターをPWM制御で駆動しています。

Duty比増加とともにマシンの回転速度が速くのが一目瞭然ですね。

PWM周波数を変化させて、モーター回転がスムーズに動くのを確認してみる

次はPWM周波数を1Hzから1Hz刻みで5Hzまで高くする実験です。

Duty比は85%としました。

PWM周波数が低いとマシンがガクガク動き、PWM周波数を高くするにつれてスムーズに動いていきますね。

PWM周波数5Hzまで高くなると、だいぶマシンがスムーズに動くようになります。

まとめ

DCモーターの回転速度を変えるPWM制御について解説しました。

今回の記事をまとめると

  • DCモーターの速さを変えるPWM制御について解説
  • Raspberry PiでPWM制御するRPi.GPIOモジュールの使い方を説明
  • Duty比を変化させて、モーターの回転速度が変化するか確認
  • PWM周波数を変化させて、モーター回転がスムーズに動くのを確認

です。

PWM制御はモーターの回転速度を変化させるだけでなく、サーボモーターの角度を制御したり、LEDの明るさを変えたりも出来ます。

PWM制御を覚えておけば、電子制御の応用幅が広がりますね!

最後までお読み頂きありがとうございました。

プログラミング言語の人気オンラインコース
よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

大学で機械工学を学んだ後、製造業で働く40代の会社員です。
IT系、電気系を学んでこなかった機械系人間が、ゲーム制作、電子工作に奮闘してます。
極力低コストでものづくりを楽しむのがモットー。

目次