前回でRaspberry PiのPWM機能を使ってモーターの回転数を制御できるようになりました。しかし、レゴの車に載せるモーターとして、まだ足りない機能があります。
それは逆回転です。やはり前進だけでなくバックもできないと不便ですからね。
というわけで今回は、前回まで使っていたMOSFETの部分をモータードライバーに変えて、モーターの回転方向を正転/逆転切り替えできるようにします。
- 【第1回】Raspberry Piでモーターを制御してみよう
- 【第2回】Raspberry PiでPWM制御して、モーター回転数を制御しよう
- 【第3回】Raspberry Piでモータードライバーを制御して、モーターの回転方向を変えてみよう ← 今ココ
- 【第4回】Raspberry Piでモーターを制御するサーバープログラム
- 【第5回】Raspberry Piでモーターを制御するクライアントアプリ(iOS)
準備するもの
今回のモーター制御では下記のものを使用します。
- 初期設定済みのラズパイ
- パソコン
- 380モーター
- モーター駆動用のバッテリー(7.2V)
- ブレッドボード
- モータードライバー
- 整流ダイオード
- 抵抗器
- ジャンパ線
- ハンダゴテ
ちなみに私が今回使ったモータードライバーはこちら。

東芝の『TB67H450FNG』というDCモータードライバーを搭載した製品です。ピンヘッダーが付いていないので、自分でハンダ付けをする必要があります。
後々調べてみるとAmazonでもマルツ製のものが売っていました。ただ、配送料が高いので損した気分になるかも。
モータードライバーって何?
まずはモータードライバーがどういった物なのかを簡単に説明しておきます。
今回購入したモータードライバーは、正確には「DC ブラシモータードライバー」です。したがって、ブラシ付きモーターを簡単に動かすために用意されたICというわけです。今回駆動させる380モーターはブラシ付きモーターなので、DC ブラシモータードライバーを使うわけですね。
で、このモータードライバーですが、何ができるのかというと、PWMによる回転速度の制御はもちろんのこと、正転/逆転/ブレーキ/STOP といった制御も簡単にできるのです!
というのも、基本的にどんなモータードライバーもHブリッジという回路を内蔵しており、この回路によって正転/逆転/ブレーキ/STOPといった制御が可能になるのです。
https://techweb.rohm.co.jp/motor/knowledge/basics/basics-03/260
上記回路を見てもわかりますが、Hブリッジ回路はMOSFETを4つ用意すると自作できます。私も以前勉強のために作ったことがあります。
ただ、わざわざMOSFETを4つ用意して自分でHブリッジ回路を作るより、すでにコンパクトにまとめられたICを使った方がラクチンなので、今回もモータードライバを使うことにしました。
なお、モータードライバによっては過熱検出や過電流検出といった機能も搭載しており、かなり便利ですよ。
モータードライバーを使った回路の作成
まずは今回使うモータードライバー『TB67H450FNG』の仕様書を確認します。下記のリンクでデータシートがダウンロードできるので、まずはダウンロードしておきます。
まずは回路を作るために各端子に何を繋げるべきなのかを確認します。『TB67H450FNG』のデータシートを見ると、下記の8つの端子があります。
端子番号 | 端子名称 | 機能 | 接続先 |
---|---|---|---|
1 | GND | GND端子 | 回路全体のGND |
2 | IN2 | ロジック入力端子 2 | ラズパイのPWM出力端子(GPIO19) |
3 | IN1 | ロジック入力端子 1 | ラズパイのPWM出力端子(GPIO18) |
4 | VREF | モーター出力電流設定端子 | ラズパイの5Vpower端子 【補足】 この端子は定電流制御に使われる端子であり、 今回は定電流制御を使わないため5Vに接続 |
5 | VM | モーター電源 | 電源(バッテリー)のプラス端子 |
6 | OUT1 | モーター出力端子 1 | モーターの端子の片側 |
7 | RS | モーター出力電流検出用端子 | 回路全体のGND 【補足】 この端子は定電流制御に使われる端子であり、 今回は定電流制御を使わないためGNDに接続 |
8 | OUT2 | モーター出力端子 2 | モーターの端子の片側 |
というわけで、これらの情報を元に回路図を作成すると、下記のようになりました。

これでモーターに掛かる電圧を両端で制御できるようになりました。あとはこの回路図に合わせて回路を作成します。作成するとこんな感じ。

PWMによるモーターの動かし方
前回までは「gpio」コマンドを使ってモーター駆動の制御を行っていましたが、今回からはプログラムを使った制御を行います。
というのも『TB67H450FNG』はかなり高周波数(400kHz)のPWM入力を受け付けることができるので、折角ならこの特性を活かしたいからです(一概に高周波数が良いわけではありませんがメリットはあります)。しかし、「gpio」コマンドだとクロック制御が限られるため、この特性を活かせません。
というわけで、ラズパイのPWMをプログラムで制御したいわけですが、ラズパイのPWMを制御するとなると、以下の2つが代表的なライブラリとして挙げられます。
- pigpio
- WiringPi
この2つのライブラリを比較したところ、PWM制御を行うのであればpigpioの方がオススメです。PWM出力のI/F(インターフェース)が分かりやすいですし、高クロックのPWMを出力できるからです。
WiringPiのコードを見てみましたが、PWMのクロック源は「gpio」コマンドと一緒でオシレーターのクロックを使っています。つまり、19.2MHzのクロックを使っているので、rangeの設定によっては400kHzの特性をまったく活かせません。
一方、pigpioのコードを見てみたところ、PWMのクロック源をPLLD(500MHz)に変えています。そのため、PWMに設定できる周波数が30MHzとなっており、周波数の高いPWMを出力できます。
なお、pigpioのI/Fは125MHzまで対応しているが、実際のところ30MHz以上は機能しないとのこと。公式に「Frequencies above 30MHz are unlikely to work.」と記載されています。
pigpioライブラリの使い方
pigpioライブラリを使うには下記手順が必要になります。
- pigpioライブラリのインストール
- pigpiodの起動
- pigpioのI/F呼び出し(プログラム作成)
pigpioライブラリのインストールは、ラズパイ上のターミナルで下記コマンドを実行します。
sudo apt install pigpio
インストールが完了したら、pigpiod(デーモン)を起動します。
sudo pigpiod
あとはpigpioが公開しているPWM出力のI/Fを呼び出せば使うことができます。今回はPython用のI/Fを使うので、下記のように呼び出します。(pigpioにはC言語用にI/Fも用意されています)
import pigpio
pi = pigpio.pi()
pi.hardware_PWM(GPIO番号, 周波数(0〜125000000), ONの割合(0〜1000000))
モーターを動かすサンプルコード
今回作成したコードはこちらです。
import pigpio
import time
IN1_GPIO = 18
IN2_GPIO = 19
pi = pigpio.pi()
# Forward 20%
# IN2 - HI75% : LO25%
pi.hardware_PWM(IN2_GPIO, 200000, 750000)
# IN1 - HI100% : LO0%
pi.hardware_PWM(IN1_GPIO, 200000, 1000000)
time.sleep(5)
# Forward 50%
# IN2 - HI50% : LO50%
pi.hardware_PWM(IN2_GPIO, 200000, 500000)
# IN1 - HI100% : LO0%
pi.hardware_PWM(IN1_GPIO, 200000, 1000000)
time.sleep(5)
# Stop
pi.hardware_PWM(IN2_GPIO, 0, 0)
pi.hardware_PWM(IN1_GPIO, 0, 0)
time.sleep(2)
# Reverse 20%
# IN1 - HI75% : LO25%
pi.hardware_PWM(IN1_GPIO, 200000, 750000)
# IN2 - HI100% : LO0%
pi.hardware_PWM(IN2_GPIO, 200000, 1000000)
time.sleep(5)
# Reverse 50%
# IN1 - HI50% : LO50%
pi.hardware_PWM(IN1_GPIO, 200000, 500000)
# IN2 - HI100% : LO0%
pi.hardware_PWM(IN2_GPIO, 200000, 1000000)
time.sleep(5)
# Stop
pi.hardware_PWM(IN1_GPIO, 0, 0)
pi.hardware_PWM(IN2_GPIO, 0, 0)
pi.stop()
一応GitHubにもアップロードしておいたので、コピペも面倒だという方はこちらからどうぞ。
コードを見ると気になる部分があると思います。
それは正転時はIN1をDuty 100%(HI固定)にして、IN2のDutyを変えることで回転速度を制御して、反対に逆転時はIN2をDuty 100%(HI固定)にして、IN1のDutyを変えることで回転速度を制御しているという点です。
この辺りは詳細を語り始めると長くなるので別記事にて解説する予定ですが、このようにすることでOFF区間をSlowモードで動かすことができ、ON区間でチャージした電流を効率よくモータートルクに変換することができます。図にするとこんな感じ。

逆に正転時にIN2をDuty 0%(LO固定)、IN1のDutyを変えることで回転速度を制御しようとすると、OFF区間でHブリッジ内の全MOSFETがOFFとなります。
これはFastモードの状態となり、モーターにチャージされた電流は瞬間的に電源に戻され、モーターを回転させるほどのトルクが得られません。(PWMの周波数を1kHzとかに落とすとチャージ区間が長くなりトルクを得られますが、20kHzを超えるような周波数帯になると回転しない。)図にするとこんな感じ

以下の動画が実際にサンプルコードを動かしたときの様子です。
正転/逆転している様子が見える…と思います。モータードライバーを使うとこんなにも簡単に正転/逆転が制御できるのです。
まとめ
モータードライバーを使うことで回転の方向を制御することができました。
ここまで出来てしまえば、あとはDuty値と回転方向の情報を受け取るサーバーを作成して、クライアントからDuty値と回転方向を指示してあげれば、リモートでモーターの回転数と回転方向を制御できます。そうなれば、後はレゴの車に搭載することで走らせることができるでしょう。
次回はDuty値と回転方向を受け取るサーバーの作成とクライアントの作成を行います。
コメント