R_Castle が 2020年05月30日18時27分44秒 に編集
初版
タイトルの変更
DCモーターをArduinoUnoで動かしてみる(その2)
タグの変更
Arduino
Arduino_Uno
トランジスタ
FET
モーター
回路
ブリッジ回路
記事種類の変更
セットアップや使用方法
本文の変更
少し間が開きましたが、今回はArduinoUnoを使ってモーターを制御する話の続きをしたいと思います。前回記事はこちらになります。 記事リンク:[DCモーターをArduinoUnoで動かしてみる(その1)](https://elchika.com/article/e6b4f3ec-2e19-4c98-b35f-5f3cd5fa1033/) 前回はマイコンからの信号を利用して大きな電流を制御する制御回路をご紹介しました。 # ブリッジ回路 前回ご紹介した「Iブリッジ回路」では、トランジスタ1個によるON/OFF制御でモーターの回転と速度を制御する事が出来る様になります。この回路は電源の+側からGND側をつなぐ制御回路のレイアウトの様子がIの形に見える事からそう呼ばれる事があります。  この回路では速度の上げ下げは制御できますが回転方向の制御は出来ません。 回転方向も含めて自由に制御する為には、モーターの端子両端に加えられる電圧の向きを切り替える必要があります。 例えば、モーターの接続方向を逆にしたIブリッジ回路が二つあったとします。  これをモーターの接続端子の向きを合わせて合体させたら回転方向も制御できる様になるのでは?という事で二つの回路を合成します。   するとモーターの両端がVcc端子に接続されてしまう回路が出来てしまいました。 これではモーターの両端に加わるのは電源電圧+のみとなってしまい制御が出来ませんので、回路図の上側、モーターの両端子に繋がっている電源のラインにもトランジスタを追加して電圧が加わる方向を選択できる様にします。  これで、4つのトランジスタをコントロールする事でモーターの回転方向が制御できる回路になりました。この回路のレイアウトから、制御素子を4つ使用してモーターの回転方向も制御可能な回路の事を「Hブリッジ」と呼んでいます。   Hブリッジを構成する時、モーターから上流に追加するトランジスタにはPNP型の素子を使用します。全部NPN型で構成しても動作はするのですが4本の信号線をすべて個別に制御する必要が生じて回路が複雑になります。 ここでPNP型とNPN型のトランジスタの動作に必要な信号のHIGH/LOWが逆な点に注目して、ブリッジ回路左右の素子をひとまとめに1本の信号線で制御できる様にします。  これで、2本の信号線のHIGH/LOWの切り替えで回転方向を制御する事が出来る様になります。 ※ 図中では素子の名称をモーターの上側のPNP型トランジスタを「Tr_P1」「Tr_P2」、モーター下側のNPN型トランジスタを「Tr_N1」「Tr_N2」と置き換えてあります。 この置き換えた名称を使って、信号線2つの組み合わせとトランジスタの動作を確認すると次の様になります。 |Arduino_Pin1|Arduino_Pin2|Tr_P1|Tr_P2|Tr_N1|Tr_N2|モーター動作| |---|---|---|---|---|---|---| |LOW|LOW|ON|ON|OFF|OFF|停止| |HIGH|LOW|OFF|ON|ON|OFF|1→2方向| |LOW|HIGH|ON|OFF|OFF|ON|2→1方向| |HIGH|HIGH|OFF|OFF|ON|ON|停止|   この状態のArduinoの制御プログラムは以下の様になります。 まず前回も記述した、Iブリッジの制御プログラムをもう一度見てみます。 ```arduino:1秒おきにモーターを回転/停止させるプログラム(Iブリッジ版) /*****************************************************************/ int Motor = 13; // モーター動作確認用に13番ポートのLEDも利用します。 int Time = 1000; // 連続動作時間を指定します。 void setup() { pinMode(Motor, OUTPUT); } void loop() { digitalWrite(Motor, HIGH); // モーター回転 delay(Time); digitalWrite(Motor, LOW); // モーター停止 delay(Time); } /*****************************************************************/ ``` このIブリッジ版をベースに、Hブリッジに対応した2信号出力版のプログラムに書き替えます。 ```arduino:1秒おきにモーターを回転/停止させるプログラム(Hブリッジ版①) /*****************************************************************/ int Pin1 = 13; // Arduino_Pin1を13番ピンに割り当てます。 int Pin2 = 12; // Arduino_Pin2を12番ピンに割り当てます。 int Time = 1000; // 連続動作時間を指定します。 void setup() { pinMode(Pin1, OUTPUT); pinMode(Pin2, OUTPUT); } void loop() { // 停止(解放) digitalWrite(Pin1, LOW); digitalWrite(Pin2, LOW); delay(Time); // 1→2回転 digitalWrite(Pin1, HIGH); digitalWrite(Pin2, LOW); delay(Time); // 停止(ブレーキ) digitalWrite(Pin1, HIGH); digitalWrite(Pin2, HIGH); delay(Time); // 2→1回転 digitalWrite(Pin1, LOW); digitalWrite(Pin2, HIGH); delay(Time); // 停止(ブレーキ) digitalWrite(Pin1, HIGH); digitalWrite(Pin2, HIGH); delay(Time); } /*****************************************************************/ ``` 頻繁に回転方向を切り替える動作が行えるのがHブリッジの特徴ですが、制御信号の組み合わせを間違えると望まない方向に回転してしまうといった現象が起きる事もあります。今のうちにプログラムの命令各動作毎にサブルーチンを宣言した形のプログラムにしておいてもいいでしょう。 ```arduino:1秒おきにモーターを回転/停止させるプログラム(Hブリッジ版②) /*****************************************************************/ int Pin1 = 13; // Arduino_Pin1を13番ピンに割り当てます。 int Pin2 = 12; // Arduino_Pin2を12番ピンに割り当てます。 int Time = 1000; // 連続動作時間を指定します。 void MotorStop() { // 停止(ブレーキ) digitalWrite(Pin1, HIGH); digitalWrite(Pin2, HIGH); } void MotorOpen() { // 停止(解放) digitalWrite(Pin1, LOW); digitalWrite(Pin2, LOW); } void MotorCW() { // 1→2回転をCW(時計回り)と定義 digitalWrite(Pin1, HIGH); digitalWrite(Pin2, LOW); } void MotorCCW() { // 2→1回転をCCW(反時計回り)と定義 digitalWrite(Pin1, LOW); digitalWrite(Pin2, HIGH); } void setup() { pinMode(Pin1, OUTPUT); pinMode(Pin2, OUTPUT); } void loop() { // 停止(解放) MotorOpen(); delay(Time); // 1→2回転 MotorCW(); delay(Time); // 停止(ブレーキ) MotorStop(); delay(Time); // 2→1回転 MotorCCW(); delay(Time); // 停止(ブレーキ) MotorStop(); delay(Time); } /*****************************************************************/ ``` 実際にモーターを制御する回路として組み立てる際にはこのHブリッジの構成が基本になると言ってよいと思います。 使うモーターの性能に応じた素子の選定に始まって、回転方向に応じた整流ダイオードや各種保護回路を追加する事も必要になって・・・と、ここからどんどん複雑な回路構成になって行きます。 最近の電子工作では素子の一つ一つを選定して回路を組むといったケースはあまり見られず、代わりに次以降に紹介する様なFETを利用したブリッジモジュールを使用する人の方が多いと思います。 # FETによるHブリッジ バイポーラトランジスタは大電流を制御できる代わりに、動作させる為に必要な駆動電流が多めで、かつ電子素子としては動作が遅めという特徴を持っています。 複雑なON/OFF、回転量制御を繰り返すのは少々苦手な所もある所から、制御信号への反応の良さ=応答性を重視するHブリッジ回路では「FET=電界効果トランジスタ」を用いてブリッジを構成する事が一般的になっています。 FETは回路記号が異なるだけでなく信号の呼び方も変わりますので混乱しがちですが、よく確認して誤った接続をしない様にしましょう。  このFET素子のN-ch、P-chの素子で構成したHブリッジ回路の例は下図の様になります。  この時、トランジスタ版のHブリッジでひとまとめにした信号線を再び4つに分割しています。 また制御が複雑になるの?と思うでしょうが、複雑になる代わりに大きな利点が使える様になる為、あえて信号線を元の4つに戻します。 これによってHブリッジ全体で回転方向を制御するだけでなく、P-ch側のFETに入力する信号の電圧制御を行う事でモーターの速度コントロールが出来る様になります。 ==信号のHIGH/LOW制御の組み合わせには充分注意しましょう。== 回路図の様なHブリッジにおける制御信号の組み合わせは下表の様になります。 |pin1|pin2|pin3|pin4|FET-P1|FET-P2|FET-N1|FET-N2|動作| |---|---|---|---|---|---|---|---|---| |LOW|LOW|LOW|LOW|ON|ON|OFF|OFF|停止(解放)| |HIGH|LOW|HIGH|LOW|OFF|ON|ON|OFF|1→2回転| |LOW|HIGH|LOW|HIGH|ON|OFF|OFF|ON|2→1回転| |HIGH|HIGH|HIGH|HIGH|OFF|OFF|ON|ON|停止(ブレーキ)| |HIGH|HIGH|LOW|LOW|ON|ON|ON|ON|破損(FETが壊れます)| 信号の組み合わせを間違えるとFETが破損します。   ==制御用のプログラムについても単純に正転/反転だけではなく 「一度停止」→「回転方向切り替え」→「回転開始」 といった手順を丁寧に守って記述する必要があります。==  以上を踏まえて、トランジスタ用に作っていたArduinoのプログラムをFETのHブリッジ用に書き換えると次の様になります。 ```arduino:1秒おきにモーターを回転/停止させるプログラム(FET-Hブリッジ版①) /*****************************************************************/ int Pin1 = 13; // Arduino_Pin1を13番ピンに割り当てます。 int Pin2 = 12; // Arduino_Pin2を12番ピンに割り当てます。 int Pin3 = 11; // Arduino_Pin3を11番ピンに割り当てます。 int Pin4 = 10; // Arduino_Pin4を10番ピンに割り当てます。 int Time = 1000; // 連続動作時間を指定します。 void MotorStop() { // 停止(ブレーキ) digitalWrite(Pin1, HIGH); digitalWrite(Pin2, HIGH); digitalWrite(Pin3, HIGH); digitalWrite(Pin4, HIGH); } void MotorOpen() { // 停止(解放) digitalWrite(Pin1, LOW); digitalWrite(Pin2, LOW); digitalWrite(Pin3, LOW); digitalWrite(Pin4, LOW); } void MotorCW() { // 1→2回転をCW(時計回り)と定義 digitalWrite(Pin1, HIGH); digitalWrite(Pin2, LOW); digitalWrite(Pin3, HIGH); digitalWrite(Pin4, LOW); } void MotorCCW() { // 2→1回転をCCW(反時計回り)と定義 digitalWrite(Pin1, LOW); digitalWrite(Pin2, HIGH); digitalWrite(Pin3, LOW); digitalWrite(Pin4, HIGH); } void setup() { pinMode(Pin1, OUTPUT); pinMode(Pin2, OUTPUT); pinMode(Pin3, OUTPUT); pinMode(Pin4, OUTPUT); } void loop() { // 停止(解放) MotorOpen(); delay(Time); // 1→2回転 MotorCW(); delay(Time); // 停止(ブレーキ) MotorStop(); delay(Time); // 2→1回転 MotorCCW(); delay(Time); // 停止(ブレーキ) MotorStop(); delay(Time); } /*****************************************************************/ ``` 以上の様に回路構成もプログラムも少々複雑になるFETによるブリッジ回路ですが、少ない電力で駆動する目的に適したワンパッケージ化されたIC、制御モジュール等が入手できますのでこれらを利用すると良いと思います。 # FETブリッジモジュール「MP4212」 模型用モーターの制御を目的としたHブリッジを用意したい、という時には調達しやすいモジュールICが色々あります。 ここでは使用事例も多い「MP4212」をご紹介します。 メーカーのICデータシート:[パワーMOSFETモジュール[MP4212]](https://toshiba.semicon-storage.com/info/docget.jsp?did=15988&prodName=MP4212) 最近はメーカーの生産の都合などもあり型番が変わったり生産休止になったりする部品なども多い状況が続いています。 MP4212についてもメーカーのWEBサイトでは製造中止予定と言われていますが今でもまだ入手自体は可能ですし、半完成品の互換キット等が電気街のお店で販売されていますので、モーター制御をマスターする為の練習台としては比較的挑戦しやすいモジュールだと思います。  互換モジュールキットのリンク:[秋月電子[ TPC8407×2 MP4212ピン互換 パワーMOSFETモジュール]](http://akizukidenshi.com/catalog/g/gK-10721/) 互換モジュールに使用されているのはやはり同様のFETブリッジICである場合が多いのですが、ブレッドボード等に配線するのが少々難しい小さなパッケージが採用されていたりするので、自身で変換基板を設計・製作できる様になるまでの間は積極的に互換モジュールも使って行きましょう。 MP4212モジュール内の回路構成を以下に示します。  4つのFET素子と整流ダイオード等が内蔵されていて、Hブリッジのモーター=負荷を接続するところで上下のブロックに分かれてICの端子に配線が出てきていますので、各ピンに電源と信号を入力するだけでモーターの回転方向と速度制御が可能になります。 モジュールの3番と7番、5番と9番をそれぞれ接続した上でモーターにつなぎます。信号線には2番、4番、6番、8番ピンを接続して制御します。 それぞれのピンをON/OFFする為の信号の組み合わせは先に述べたFETを用いたHブリッジの制御信号の組み合わせと同様になります。 |ピン番号|chタイプ|ON動作|OFF動作| |---|---|---|---| |6|P-ch|信号:LOW|信号:HIGH| |8|P-ch|信号:LOW|信号:HIGH| |2|N-ch|信号:HIGH|信号:LOW| |4|N-ch|信号:HIGH|信号:LOW| ==制御信号の組み合わせ間違いでFETモジュールを破損しない様、十分注意してください。== しつこいくらい信号の組み合わせについての注意を述べていますが、制御を間違え破損したFETはものすごい熱を発生する為この熱で周りの電線や可燃物に火がつく恐れがあります。 回路もプログラムも特に丁寧に作り込んで常に点検する様にしておく事がトラブル回避には大切なポイントになります。 このFETモジュールの6番ピンと8番ピンをPWM制御で電圧を変化させる様にプログラムを組む事でモーターの速度制御が可能になります。 先ほどのプログラムでは単純な正転/反転のみでしたので、もう少し回転速度の制御を盛り込んだArduinoのプログラム例を作りたいと思います。 ```arduino:速度制御を伴い回転/停止させるプログラム(FET-Hブリッジ版②) /*****************************************************************/ int Pin1 = 13; // Arduino_Pin1を13番ピンに割り当てます。 int Pin2 = 12; // Arduino_Pin2を12番ピンに割り当てます。 int Pin3 = 11; // Arduino_Pin3を11番ピンに割り当てます。 int Pin4 = 10; // Arduino_Pin4を10番ピンに割り当てます。 int Time = 1000; // 連続動作時間を指定します。 void MotorStop() { // 停止(ブレーキ) digitalWrite(Pin1, HIGH); digitalWrite(Pin2, HIGH); digitalWrite(Pin3, HIGH); digitalWrite(Pin4, HIGH); } void MotorOpen() { // 停止(解放) digitalWrite(Pin1, LOW); digitalWrite(Pin2, LOW); digitalWrite(Pin3, LOW); digitalWrite(Pin4, LOW); } void MotorCW(int Speed) { // 1→2回転をCW(時計回り)と定義 digitalWrite(Pin1, HIGH); digitalWrite(Pin2, LOW); digitalWrite(Pin3, HIGH); analogWrite(Pin4, 1023-Speed); // digitalWriteからanalogWriteに変更。電圧制御します。 } void MotorCCW(int Speed) { // 2→1回転をCCW(反時計回り)と定義 digitalWrite(Pin1, LOW); digitalWrite(Pin2, HIGH); analogWrite(Pin3, 1023-Speed); // digitalWriteからanalogWriteに変更。電圧制御します。 digitalWrite(Pin4, HIGH); } void setup() { pinMode(Pin1, OUTPUT); pinMode(Pin2, OUTPUT); pinMode(Pin3, OUTPUT); pinMode(Pin4, OUTPUT); } void loop() { // 停止(解放) MotorOpen(); delay(Time); // 1→2回転、徐々に加速 for (int i=0;i<=1023;i++) { MotorCW(i); delay(5); } delay(Time); // 停止(ブレーキ) MotorStop(); delay(Time); // 2→1回転、徐々に加速 for (int i=0;i<=1023;i++) { MotorCCW(i); delay(5); } delay(Time); // 停止(ブレーキ) MotorStop(); delay(Time); } /*****************************************************************/ ``` 複雑な速度コントロールを必要とするモーター制御を行いたいのであれば、是非Hブリッジ回路を使いこなせるようになっておきましょう。 FETの選定から行える様になるには更に豊富な電子回路の知識が必要になりますので、こういったワンパッケージ化されたブリッジモジュールで対応しているモデルを選ぶところから始めると良いと思います。 モーターやセンサーが使いこなせる様になってきましたので、そろそろ実際に動き回る物の製作にチャレンジしていきたいと思います。 