Raspberry Piでブラシレスモーターを制御する (RPZ-RC-Motor)

ラズパイでESCを通してブラシレスモーター回転させたり、回転数を制御する方法を解説しています。本来制御が複雑なブラシレスモーターですが、拡張基板「RPZ-RC-Motor」とPythonで動作する制御ソフトウェアcgservoを使うことで簡単かつ直感的にモーターを制御することができます。

更新日 : 2024年12月11日

ブラシレスモーターを制御する仕組み

RCカーやドローン向けの小型のブラシレスモーターとESC(モーターを制御する部品)は、PWMと呼ばれる共通の通信方式を採用しています。RPZ-RC-Motor基板はPWM信号でESCを通してブラシレスモーターを制御することが可能です。

また、BECと呼ばれる電力供給機能を持ったESCを使うと、Raspberry Piへの電力も供給することもできます。

制御の仕組み
RPZ-RC-MotorにESCとブラシレスモーターを接続した例

ハードウェアの準備

本記事ではサーボモータードライバー基板「RPZ-RC-Motor」を使用してブラシレスモーターを制御します。モーターやESC、電源の接続方法については製品ページのセットアップを参照してください。

ここからはPythonプログラムで実際に制御する方法について解説していきます。

I2C有効化

基板とはI2Cで通信します。こちらの記事を参考にRaspberry PiのI2Cを有効化して下さい。




制御ソフトウェアのインストール

Indoor Corgiが開発したPythonライブラリをインストールします。本ソフトウェアを使うことで、簡単かつ直感的にサーボモーターを制御することができます。

最新版へのアップグレードも同じコマンドで可能です。

$ sudo python3 -m pip install -U cgservo --break-system-packages

エラーが出る場合は最後のオプションを指定せずにお試しください。

$ sudo python3 -m pip install -U cgservo

PWM制御の仕組み

まず、ESCで使われているPWM制御の仕組みについて解説します。

ESCの3本の配線のうちの1つである制御信号(S/PWMなどと呼ぶ場合もあります)を使い、以下のような波形をESCへ出力します。

ここで、電圧が高くなっている部分の時間(パルス幅)の長さによって、モーターの回転数や回転方向が決まる仕組みになっています。本記事では、最もよく使われるパルス幅1.0[ms]〜2.0[ms]の範囲で指定することにします。

パルス幅 [ms]ESCへの指示相当するレバー操作
2.0フルスロットルレバーを最も上に倒した状態
1.5ニュートラルレバーが中間の状態
1.0フルブレーキレバーを最も下に倒した状態
パルス幅とESCへの指示の関係

上記のパルスは一定周期でモーターへ送信し続けます。この周期で最もよく使われているのは20[ms] (周波数50Hz)です。周波数については厳密に調整する必要はなく、100Hzや200Hzでも動作するものが多いです。

サンプルプログラムの実行

ここからは実際にモーターを制御していきます。モーターが回転しますので、安全に注意して進めて下さい。モーターを固定し、動作確認ではプロペラなどの負荷は取り外して行うことを推奨します。

モーターをM1端子に接続して下さい。キーボード操作でモーター制御できるサンプルコードをダウンロードし、ターミナルで以下のコマンドを実行して下さい。

python3 esc_keyboard.py

まず、プログラムの操作方法について解説し、その後でコードの内容について解説します。

モーター制御にはPythonプログラムを使用します。Pythonの基本的な使い方についてはこちらを参照して下さい。

ESC種類の選択

まず、以下のようなESC種類を選択する画面がターミナルに表示されます。

ESCの種類を選択してEnterを押してください
1) -100〜100  逆回転/ブレーキのある車用ESC
2)    0〜100  順回転のみの飛行機/ドローン用ESC
[1-2]:

車用ESC(HOBBY WING QuicRUN、G-Force BLC50など)の場合はターミナルで「1」を入力してEnterを押します。飛行機/ドローン用ESC(HOBBY WING SKYWALKER、 FLYFUNなど)の場合はターミナルで「2」を入力してEnterを押します。

ESC種類を選択している理由について解説します。ESCには大きく分けて2つのタイプがあり、動作が異なります。

1つ目はニュートラル(パルス幅1.5ms)で停止し、スロットルレバーを上に倒す(パルス幅 > 1.5ms)と前進し、下に倒す(パルス幅 < 1.5ms)と後退もしくはブレーキとなります。主に車用ESCで採用されています。

2つ目はスロットルレバーを一番下に倒す(パルス幅1.0ms)と停止し、スロットルレバーをそれより上にしていくと出力が上昇していきます。主に飛行機やドローン用ESCで採用されています。

ESCへの指示車用ESCの動作飛行機、ドローン用ESCの動作
フルスロットル順回転(前進)順回転(出力100%)
ニュートラル停止順回転(出力50%)
フルブレーキ逆回転(バック)もしくはブレーキ停止
ESCタイプによる動作の違い

パルス幅からだと実際にどのような動作になるのかわかりにくいため、0〜100などの分かりやすい値を入力することで、自動的にパルス幅を計算して出力する機能を用意しています。

本サンプルコードでは、前進と後退/ブレーキがある車用ESCでは-100〜100の範囲で入力し、順方向にしか回転しない飛行機/ドローン用ESCでは0〜100の範囲で入力する仕組みになっています。これにより、0で停止、プラスの値で順回転、マイナスの値で逆回転/ブレーキの動作となり、直感的な操作が可能になります。




キーボード入力

ESCの選択が終わると、キーボードから入力値を指定できる状態になります。以下のように各キーの動作が表示されます。何かキーを押すまではパルスは出力されません。

------------------------------------------
値を指定
  1   2   3   4   5   6   7   8   9   0
 10  20  30  40  50  60  70  80  90  100
  Q   W   E   R   T   Y   U   I   O   P
-10 -20 -30 -40 -50 -60 -70 -80 -90 -100
                Space
                  0
------------------------------------------
現在の値から+/-
  A   S   D
 +1  +5  +20
  Z   X   C
 -1  -5  -20
------------------------------------------

1、2、3、・・・0のキーを押すと入力値を直接指定でき、それぞれ10、20、30、・・・100になります。

その下の列のQ、W、E、・・・Pを押すと、それぞれ-10、-20、-30、・・・-100になります。これらは入力範囲が-100〜100のESCを選択した場合のみ使用します。

スペースキーを押すと、入力が0になります。

また、現在の入力値から増減させることも可能です。A、S、Dを押すとそれぞれ現在の値+1、+5、+20となり、Z、X、Cを押すとそれぞれ-1、-5、-20となります。

ESCのキャリブレーション

ESCに出力する準備は整いましたが、多くのESCは最初に使う際にキャリブレーション処理が必要です。これは制御側のパルス幅の情報をESCに登録する作業です。1度キャリブレーションを行えば次回起動時は省略可能です。

車用ESCと飛行機/ドローン用ESCのキャリブレーションの方法についてそれぞれ解説します。同じ種類のESCではキャリブレーション方法も似ていますが、違いがある場合もあるため、お使いのESCの説明書をご確認ください。

車用ESCのキャリブレーション例

HOBBY WING QuicRUN-WP-16BL30のキャリブレーション手順を解説します。

まず、説明書にある手順で電源をONすることでキャリブレーションを開始します。

キャリブレーション開始方法 (QuicRUN-WP-16BL30説明書より引用)

説明書の手順の通り、ニュートラル(入力値0)、フルスロットル(入力値100)、フルブレーキ(入力値-100)の順にキャリブレーションを行います。

キャリブレーション手順 (QuicRUN-WP-16BL30説明書より引用)

具体的には以下のように操作します。

  1. 「スペース」キーを押して入力値0(ニュートラル相当)にし、ESCのセットボタンを押します
  2. 「0」キーを押して入力値100(フルスロットル相当)にし、ESCのセットボタンを押します
  3. 「P」キーを押して入力値-100(フルブレーキ相当)にし、ESCのセットボタンを押します
  4. 「スペース」キーを押して入力値0に戻します
飛行機/ドローン用ESCのキャリブレーション例

HOBBY WING Skywalker-V2のキャリブレーション手順を解説します。

説明書の手順の通り、スロットル最大(入力値100)、スロットル最小(入力値0)の順にキャリブレーションを行います。

キャリブレーション手順 (SkyWalker説明書より引用)

具体的には以下のように操作します。

  1. ESCに電源は投入しないでおく
  2. 「0」キーを押して入力値100(スロットル最大)にする
  3. ESCに電源を投入し、ビープ音を待つ
  4. 「スペース」キーを押して入力値0(スロットル最小)にし、ビープ音を待つ

モーターを回転させる

モーターを回転させる場合、一度「スペース」キーを押して入力値0にしておきます。そこから「1」、「2」、「3」キーや「A」、「S」、「D」キーを押して入力値を上げていくとモーターが回転し、回転数も上昇していきます。現在の値はターミナルに表示されます。

回転中に「スペース」キーを押すと入力値が0に戻りモーターが停止します。プログラムを終了したい場合は「Ctrl + C」を押してください。

車用ESCの場合、入力をマイナスにすると逆回転やブレーキの動作になりますが、モーターが回転中かどうかや、ESCの型番や設定によって動作が変わります。お使いのESCの説明書を参照してください。

うまく回転しない場合

  • 0→100などのように急激に入力を変化させるとうまく回転しない場合があります。徐々に上昇させてみてください。
  • ブラシレスモーターが振動するものの回転しない場合は、モーターを接続する3線のうちいずれかが接触不良の場合があります。配線を確認してください。
  • RPZ-RC-Motorの端子に接続するコネクターの向きが正しいかご確認ください。一般的に黒色の線がGNDとなっています。
  • ESCによってはリチウムイオン電池での利用を前提としており、電源電圧が想定と異なると動作しない場合があります。リチウムイオン電池を利用した場合に近い電圧でお試しください。リチウムイオン電池の電圧は1セル(1S)あたり3.7Vとなっており、最低2セルのESCの場合電圧は7.4V必要です。
  • ESCがLEDやビープ音でエラーの状態を示している場合があります。ESCの説明書を確認してください。



コードの解説

28行目
def main():
  """
  メインルーチン
  """

プログラムを実行しimportなどの準備が終わると、mainルーチンが実行されます。

32〜46行目
  current_value = 0  # 現在の入力値
  max_value = 100  # 入力範囲の最大値

ここで現在の入力値と、入力範囲の最大値用の変数を宣言しています。

入力範囲の最小値は選択したESC種類に応じて-100(42行目)もしくは0(45行目)に設定しています。

48〜53行目
  esc = Servo()
  esc.m1_param = MotorParam(
      input_start=min_value,
      input_end=max_value,
  )
  esc.init()

コントローラーIC制御用クラスであるServoの初期設定を行っています。

m1_paramにはM1端子に接続されたESC用の設定を記述します。input_startに入力範囲の最小値、input_endに入力範囲の最大値を指定します。

設定完了後、init()を実行するようにしてください。これによりコントローラーICがリセットされ、初期設定が行われます。

59〜65行目
      # キーボード入力に応じて入力値current_valueを増減する
      current_value = change_value_by_keyboard(current_value, min_value, max_value)

      # ESCのM1端子の入力値を変更. PWMパルス幅が変わりモーターの回転も変わる.
      # M2端子に変更する場合は esc.m2... のようにする
      esc.m1 = current_value

キーボード入力を処理しています。change_value_by_keyboardサブルーチンにより、キー入力に応じてcurrent_valueの値を入力範囲の中で変更しています。

esc.m1に入力値を代入することで、コントローラーICが自動的にパルス幅を計算してM1端子からPWM信号を出力します。これにより、ESCがモーターを制御して回転します。

複数のESC、モーターを制御する

サンプルコードではM1端子に接続されたESCとモーターを制御していました。M2〜M6端子のESCを制御する場合の手順について解説します。

まず、Servoクラスの設定で、mX_paramパラメーターに端子の設定を記述します。(Xは端子番号) 以下はM1に加えてM2についても設定した例です。

  esc = Servo()
  esc.m1_param = MotorParam(
      input_start=min_value,
      input_end=max_value,
  )
  esc.m2_param = MotorParam(
      input_start=min_value,
      input_end=max_value,
  )
  esc.init()

mXパラメーターに入力値を指定します。(Xは端子番号) 以下はM1端子のESCに0、M1端子のESCに50を入力した例です。

  esc.m1 = 0
  esc.m2 = 50

パルス幅を指定する

サンプルコードでは-100〜100のような直感的な入力値を使用して操作を行いました。しかし、状況によってはパルス幅を直接指定したい場合もあると思います。

以下のようにmXpパラメーターにパルス幅をミリ秒単位で設定することで、指定したパルス幅のPWM信号を出力します。(Xは端子番号)

  esc.m1p = 1.5 # 1.5[ms]のパルス幅でM1端子に出力
  esc.m2p = 2.0 # 2.0[ms]のパルス幅でM2端子に出力

複数の基板を制御する

RPZ-RC-Motorは基板2枚使うことで、最大12台のESCを制御できます。また、RPZ-RC-Servoと組み合わせてサーボモーターとブラシレスモーター両方を制御することができます。その際のプログラム方法について解説します。

まず、製品ページのセットアップにある通り、1枚目の基板のADRスイッチをOFF(I2Cアドレス0x40)、2枚目の基板のADRスイッチをON(I2Cアドレス0x41)に設定しておきます。

次に、基板1を制御するesc1と基板2を制御するesc2の2つのインスタンスを作成します。i2c_addrが異なっていることに注意して下さい。入力範囲の設定はこれまでと同じです。

esc1 = Servo(
    i2c_addr=0x40,
    ...(入力範囲の設定)...
)

esc2 = Servo(
    i2c_addr=0x41,
    ...(入力範囲の設定)...
)

基板2枚使用時の注意点として、2枚目の基板(esc2)でinitを実行する際はreset=Falseを指定して下さい。仕組み上、どちらかの基板でinit()を実行すると両方の基板のICがリセットされます。そのため、2枚目の基板ではでリセットを行わずに初期化処理のみ実行するようにします。

esc1.init()
esc2.init(reset=False)

モーターを回転させるには、基板単体の時と同様、esc1.m1やesc2.m1に値を設定すればOKです。




まとめ

RPZ-RC-MotorとRaspberry Pi(ラズパイ)を使ってブラシレスモーター回転させたり、回転数を制御する手順を解説しました。制御ソフトウェアcgservoを使うことで、直感的にブラシレスモーターを回転させることができ、車輪やプロペラ、ファンなどを駆動することが可能です。本記事ではキーボードを使用して操作しましたが、ご自身のプログラムでモーターを制御することも可能です。

また、高精度な位置合わせや回転数の制御が可能なステッピングモータードライバーや、指定した角度へ回転させることができるサーボモータードライバーも用意しています。

静音モードでステッピングモーターの動作音を抑える (Raspberry Pi + RPZ-Stepper)

ステップ角単位で回転するという仕組み上、ステッピングモーターは振動や音が大きくなりやすい特徴があります。RPZ-Stepperは静音モードを搭載しており、振動と音を低減できます。モーターや回転数にもよりますが、動いているのかほとんどわからないレベルまで振動や音を減らすことも可能です。静かな環境で動作させるアプリケーションを実現できます。

SCD41 CO2センサーとラズパイで二酸化炭素濃度を測定する

Indoor Corgiのセンサー制御ソフトウェア「cgsensor」を利用して、SCD41 CO2センサーで二酸化炭素濃度を測定したり、センサーの校正や設定を変更する方法を解説します。コマンドラインツールを使って1行もコードを書かずに測定や記録ができるほか、Pythonパッケージを使えばご自身のプログラムから簡単にセンサーを制御できます。

RPi TPH Monitor Rev2 (Raspberry Pi用 温度/湿度/気圧/赤外線 ホームIoT拡張ボード)

動作をプログラミング可能な、Raspberry Pi(ラズパイ)用ホームIoT拡張ボードです。温度、湿度、気圧センサー、赤外線送信、受信機能を搭載。温度が上がったらエアコンをオンにする、外出先から家電の操作をする、気温や湿度を記録する、といった使い方が可能です。ディスプレイやLEDに情報表示、スイッチを押したら特定の処理をすることもできます。