アフィリエイト広告
アフィリエイト広告

ブラシ付モータ FA-130RA を Hブリッジ回路で PWM制御する (2) / スケッチを描く

ブラシ付モータ FA-130RA-2270 を回します。モータのドライブは Hブリッジ回路を使用し、PWM で速度を制御します。

前回は、モータを回すための回路をつくりました。ポイントは、PWM信号の周波数をどうするか、でしたね。

ブラシ付モータ FA-130RA を Hブリッジ回路で PWM制御する (1) / 回路をつくる
ブラシ付モータ FA-130RA-2270 (*1) を回します。モータのドライブは Hブリッジ回路を使用し、PWMで速度を制御します。 (*1) マブチモータとおなじ品番ですが、秋月電子通商で購入した MERCURY MOTOR 製の互換...

今回はモータを制御するスケッチを描きます。

ブラシ付モータの動作のようす

図2. ブラシ付モータ動作のようす

スケッチのまえに、ブラシ付モータ FA-130RA の動いているようすです。

タミヤのシングルギヤボックス (4速タイプ) を回してみました。減速比は 114.7:1 ですので、1.5V時の出力回転数は 79rpm です。

Arduino からのデモ出力で、モーター電圧 0.9~1.5V で回転させています。回転が遅いので弱々しくみえますけど、トルクもそれなりにあります。軸を指でつまむ程度では止まりません。

動画では、正転減速〜逆転加速〜逆転減速〜正転加速を繰り返しています。低速時の動き、反転切り換えなど、当初考えていたよりもうまくいったかなと思っています。

ブラシ付モータ FA-130RA PWM制御のためのスケッチ

何をどう動かすかは、まだ決めていません。
とりあえず、ボリュームで回転数を調整できるようにしましょう。ボリュームの中点で停止、右へ回すと正転、左へ回すと逆転する。つまり、2.5V ±2.5V の電圧を与えることで、正転、逆転を連続的に行おうというしかけ。Arduino から、正転、逆転の切り換え信号と、速度制御用信号を出力します。

  1. // Brushed Dc-Motor Control v.0.92 2023.1.12 meyon
  2. class BrushedMotor {
  3. private:
  4.   const byte potentiometerPin = A0;
  5.   const byte forwardPin = 3;
  6.   const byte reversalPin = 4;
  7.   const byte pwmOutputPin = 5;
  8.   const int forwardArea = 517; // Forward above this value
  9.   const int reversalArea = 506; // Reversal below this value
  10.   const int minimumSetVariable = 100; // Value at startup
  11.   const int maximumSetVariable = 255; // Value at maximum speed

クラス宣言と、定数の定義。

forwardArea は、ボリュームから与えられる値が、この値より大きいとき正転します。reversalArea は、この値より小さい時に逆転。その間の値では停止します。
1023 ≧ forwradArea > reversalArea ≧ 0 にしてくださいませ、エラー判定とかしてませんので。

minimumSetVariable は、モータが始動するときの最低出力デューティ比です。値が小さいと、電流は流れますが、モータが起動できません。maximumSetVariable は、最高速時の出力デューティ比。255 が最大回転数です。
だいたい、100 でモータ電圧 0.9V、145 で1.5Vになります。

  1. public:
  2.   BrushedMotor() {
  3.     pinMode(forwardPin, OUTPUT);
  4.     pinMode(reversalPin, OUTPUT);
  5.   }

コンストラクタ。ピンモードの設定を行ないます。
ちなみに、モータを複数台にするときは、ピン指定を引数にして渡すとよいですね。

  1.   void obtainSetPoint(bool *p_setFwd, bool *p_setRev, int *p_setDr) {
  2.     static bool forward = LOW;
  3.     static bool reversal = LOW;
  4.     static int dutyRatio = 0;
  5.     int inputValue = analogRead(potentiometerPin);
  6.     if(forwardArea <= inputValue) {
  7.       forward = HIGH;
  8.       reversal = LOW;
  9.       dutyRatio = map(inputValue, forwardArea, 1023, 0, 255);
  10.     } else if (reversalArea >= inputValue) {
  11.       forward = LOW;
  12.       reversal = HIGH;
  13.       dutyRatio = map(inputValue, 0, reversalArea, 255, 0);
  14.     } else {
  15.       forward = HIGH;
  16.       reversal = HIGH;
  17.       dutyRatio = 0;
  18.     }
  19.   *p_setFwd = forward;
  20.   *p_setRev = reversal;
  21.   *p_setDr = constrain(dutyRatio, 0, 255);
  22.   }

設定値を取得する関数です。ボリュームの値によって、正転、逆転の信号と出力デューティ比を返します。

引数としてポインタを指定し、変数の値をポインタの示すアドレスに格納することで、値を戻しています。
C言語では、関数の戻り値はひとつだけです。ここでは 3つの値を返してほしいので、ポインタを利用しました。ポインタを使わずに、グローバル変数を使うことでも可能ですが、まぁ、グローバル変数はなにかと嫌われてるようですし (^_^;)

  1.   int calculateManipulationValue(int duty) {
  2.     static int setVar = 0;
  3.     static int SV = 0;
  4.     static int MVn = 0;
  5.     setVar = map(duty, 0, 255, minimumSetVariable, maximumSetVariable);
  6.     SV = constrain(setVar, minimumSetVariable, maximumSetVariable);
  7.     MVn = SV;
  8.     return MVn;
  9.   }

出力デューティ比から操作目標値、操作量を算出する関数です。
現状では出力デューティ比をそのまま操作量にしています。つまり、実質何もしていない。この部分を、たとえば回転数をフィードバックさせるとか、PID制御するとか、今後の検討項目です。

  1.   void operateMotor(int setFwd, int setRev, int manVar) {
  2.     digitalWrite(forwardPin, setFwd);
  3.     digitalWrite(reversalPin, setRev);
  4.     analogWrite(pwmOutputPin, manVar);
  5.   }
  6. };

モータの制御をおこなう関数。
正転、逆転の操作信号と、PWM信号のデューティ比制御信号を出力してるだけ。

  1. BrushedMotor brushedMotor;
  2. void setup() {
  3. }
  4. void loop() {
  5.   static int manipulatedVariable = 0;
  6.   static bool setForward = LOW;
  7.   static bool setReversal = LOW;
  8.   static int setDutyRatio = 0;
  9.   brushedMotor.obtainSetPoint(&setForward, &setReversal, &setDutyRatio);
  10.   manipulatedVariable = brushedMotor.calculateManipulationValue(setDutyRatio);
  11.   brushedMotor.operateMotor(setForward, setReversal, manipulatedVariable);
  12. }

オブジェクトの生成と、setup()関数、loop()関数。
設定値を取得して、操作量を計算、モータを操作する、そんだけです。特段に変わったことがあるわけではありません。お好きに描いていただければよかろうかと。
ちなみに、フル回転からのフル反転とか、0.1秒間隔での連続反転とか、ブラシ付モータに優しくないことも、できちゃいます。ただ、せめて切り換え時にブレーキかけてやってくださいね。

77行目では、各変数のアドレスを引数として渡しています。
ちなみに、78行目では、ふつーに return で戻り値を返してます。戻り値がひとつなので、これでいいんですけど、統一感、ないなぁ。どーなんだろ?

ブレッドボードのようす

図1. ブラシ付モータ FA-130RA PWM制御 ブレッドボードのようす

実験中のブレッドボードです。

上のヒートシンクが 3つ並んでいるのが電源部。NJM317 のヒートシンクは熱くなります。2SA1725 のほうは少し暖かに。NJM7805 のはなくてもいいです。

3Vの表示があるラインが Hブリッジ回路です。MOSFETも発熱しないので、放熱は考慮してません。ハードな動作させるときは、ちょっと注意したほうがよいかも、です。

その下が 25KHz PWM発振回路と、Hブリッジの制御ロジック。Arduino は NANO互換機です。

製作後記

今回は、ブラシ付モータ FA-130RA-2270 を Hブリッジ回路で駆動し、PWM で速度を制御する回路とスケッチをつくりました。当初思っていた以上に、安定して制御できているようです。

この回路では、正転、逆転の切り換え信号と、速度制御用の 0 ~ 3.5V のアナログ電圧を与えることで、ブラシ付モータの回転制御ができます。回転数などをアナログ信号でフィードバックすればよいので、簡単な速度一定制御とかなら、Arduino を使わなくても可能です。いろいろ応用できるかなぁと、思ってます。

タイトルとURLをコピーしました