Raspberry PiのGPIOライブラリpigpioでPWM信号を出力する

  • URLをコピーしました!

今回はRaspberry PiのGPIO制御ライブラリ、pigpioを使ってモーター制御等に使用できるPWM信号を生成する方法について解説します。
PWMを使用することにより電子工作の幅が広がりますので、ぜひトライしてみてください。

目次

Raspberry Pi(ラズベリーパイ)とは

Raspberry Piはイギリスのラズベリーパイ財団が教育用に開発したボードコンピュータです。
以下のページでスペックや活用事例を紹介していますので、あわせてご覧ください。

PMW(Pluse Width Modulation)

PWMとは名前の通りパルスの幅(1周期内のパルスのON時間)を長くしたり短くしたりして流す電流や電圧を制御する方式です。

PWM方式ではパルス信号をON、OFFさせるために一定周期で動作するタイマーを利用するのが一般的です。タイマーを使って生成した波形は以下となります。搬送波と呼ばれ、主にのこぎり波と三角波の2パターンが用いられます。
今回はのこぎり波の例を示します。

タイマーのカウント値が0から始まり、最大値になってリセットされるまでの間がPWMの1周期となります。

この搬送波にパルス信号をONする位置を決めるためのコンパレータ(比較器)を組み合わせてパルス幅を制御します。
タイマーで生成したのこぎり波(黄色)が、コンパレータ(青)値を下回ったらON、上回ったらOFFという形で出力電圧を切り替えます。
下段の波形が実際に出力されるPWM信号となります。

コンパレータの値は指令値となるデューティ比によって決まります。このデューティ比を制御プログラムで決定し、PWMモジュールに与えることで出力を変化させます。
画像中央より左側がDuty30%、右側がDuty80%の状態です。

デューティ比を変更する前と後でON時間とOFF時間が変わっているのがわかります。
このON/OFFを非常に速い速度で行うことにより、長い時間間隔で見た場合の平均電圧を制御することが可能になります。

pigpioとは

pigpioとはRaspberry PiのGPIOを制御するためのライブラリです。CとPythonのプログラムから使用することができます。
ライブラリの詳細は以下のサイトをご覧ください。

また、Raspberry Pi 4のGPIOのハードウェア仕様については以下の記事で詳細を解説しています。
PWMを出力できるピンはあらかじめ決められていますので、こちらのピンアサインを参考に配線してください。本記事内で掲載しているソースコードで指定しているGPIOのNoは、下記記事GPIO一覧の「BMC」の番号を指定しています。

環境

ハードウェア:Raspberry Pi 2
OS:Raspbiann 11
Python:3.9.2

今回は空いてる実機がなかったのでRaspberry Pi 2でやりましたが、Raspberry Pi 3、4でも同じように使用可能です。

※Raspberry Pi 4の場合はピンアサインが異なりますので、「Raspberry PiのGPIOを活用してハードウェアを接続しよう」のピンアサインを参考に、使用するピンを設定してください。

回路作成する際に揃えておきたいアイテム

実際にRaspberry Piと電子部品などを接続する前に用意しておきたいアイテムを以下にまとめています。

pigpioのインストール

ライブラリをインストールするため以下のコマンドを実行してください。

sudo apt-get update
sudo apt-get install pigpio

インストール後、以下のコマンドでデーモンを起動して使用します。

sudo pigpiod

Raspberry PiからPWMを出力する

PythonのプログラムからPWM信号を出力してみます。
今回はハードウェアPWMを出力可能なGPIO18、19番ピンを使用します。デューティは18番が70%、19番が40%という設定で出力してみました。PWM周波数は1kHzです。

※Raspberry Pi 4の場合はGPIO12、13がハードウェアPWM出力に対応したピンとなります。

import pigpio
pi = pigpio.pi()

#PWMパラメータ
pwm_pin1 = 18 #PWM出力ピンを指定
pwm_pin2 = 19 #PWM出力ピンを指定
duty1 = 70 #デューティー比を%で指定
duty2 = 40 #デューティー比を%で指定
freq = 1000 #PWM周波数をHzで指定

#パラメータ変換
cnv_dutycycle1 = int((duty1 * 1000000 / 100))
cnv_dutycycle2 = int((duty2 * 1000000 / 100))

#PWMを出力
pi.hardware_PWM(pwm_pin1, freq, cnv_dutycycle1)
pi.hardware_PWM(pwm_pin2, freq, cnv_dutycycle2)

実際にプログラムを実行し、Raspberry PiのGPIOから出力された信号をオシロスコープで計測してみました。
PWM周波数は1kHzに設定されているため、5目盛りで1周期となっています。

まず1枚目の画像はGPIO18ピンから出力されるduty1のデューティ比70%のPWM波形です。hardware_PWMの引数で指定した通り、1周期内でHiの時間が70%になっていて、正しく出力されていることが確認できました。


続いて2枚目の画像はGPIO19ピンから出力されるduty2のデューティ比40%のPWM波形です。こちらも1周期内でHiの時間が40%で、指令値通りに出力されていることが確認できました。

PWMのデューティーを変化させてみる

続いてプログラムから動的にPWMのデューティー比を変化させてみます。プログラムでは0%~100%までの増減を繰り返す処理となっています。

※Raspberry Pi 4の場合はGPIO12、13がハードウェアPWM出力に対応したピンとなります。

from time import sleep
import pigpio
import time
pi = pigpio.pi()

#PWMパラメータ
pwm_pin1 = 18 #PWM出力ピンを指定
duty = 0 #デューティー比を%で指定
freq = 1000 #PWM周波数をHzで指定
up_flag = True

while True:
    #デューティサイクル計算
    cnv_dutycycle = int((duty * 1000000 / 100))

    #PWMを出力
    pi.hardware_PWM(pwm_pin1, freq, cnv_dutycycle)

    #dutyを変更
    if up_flag == True:
        if duty == 100:
            up_flag = False
        else:
            duty += 1
    else:
        if duty == 0:
            up_flag = True
        else:
            duty -=1
    
    time.sleep(0.05)

プログラムを実行した様子を動画で撮影しました。

PWMのデューティー比が0%~100%の間で繰り替えされているのが見て頂けるかと思います。

PWMの応用

ここからは実際にPWMを使ってアクチュエータなどを制御した事例をご紹介します。

DCモーターを制御する

pigpioを使ってPWM制御でDCモーターを回す方法とソースコードを紹介した事例です。
Raspberry Piの出力ピンはハードウェアPWMのチャンネルを使用しています。モータドライバICはL298Nを使用しています。

L298Nの詳細は以下のページで解説しています。

Raspberry Pi のハードウェアPWMを使って実際にDCモーターを駆動している動画をソースコード付きで以下のページで解説しています。

サーボモーターを制御する

サーボモーターSG90をPWMで制御する方法とソースコードを以下の記事で解説しています。
SG90はアナログタイプのサーボモーターで、直接Raspberry PiのPWM信号をサーボに入力して駆動しています。

まとめ

いかがだったでしょうか?
DCモーターなどは印加される電圧に速度が比例するため、PWMで平均電圧をコントロールしてやることで速度制御がかのうです。pigpioはソフトウェアPWMも精度が良いらしいので、そちらも今後試してみたいと思います。

また、Raspberry Piでのハードウェア制御をさらに深く学びたい方にはUdemyの以下の講座がおすすめです。

Raspberry Pi Picoで作る!USBショートカットキーデバイス。Pythonで手軽に電子工作しよう! icon



それでは、また次の記事でお会いしましょう。

ツール

今回、PWMの計測にはOWONのオシロスコープを使用しました。(私が所有しているのは旧モデルです)

参考

よかったらシェアしてね!
  • URLをコピーしました!
目次