ブラシ付モータ FA-130RA-2270 を回します。モータのドライブは Hブリッジ回路を使用し、PWM で速度を制御します。
前回は、モータを回すための回路をつくりました。ポイントは、PWM信号の周波数をどうするか、でしたね。
今回はモータを制御するスケッチを描きます。
ブラシ付モータの動作のようす
スケッチのまえに、ブラシ付モータ FA-130RA の動いているようすです。
タミヤのシングルギヤボックス (4速タイプ) を回してみました。減速比は 114.7:1 ですので、1.5V時の出力回転数は 79rpm です。
Arduino からのデモ出力で、モーター電圧 0.9~1.5V で回転させています。回転が遅いので弱々しくみえますけど、トルクもそれなりにあります。軸を指でつまむ程度では止まりません。
動画では、正転減速〜逆転加速〜逆転減速〜正転加速を繰り返しています。低速時の動き、反転切り換えなど、当初考えていたよりもうまくいったかなと思っています。
ブラシ付モータ FA-130RA PWM制御のためのスケッチ
何をどう動かすかは、まだ決めていません。
とりあえず、ボリュームで回転数を調整できるようにしましょう。ボリュームの中点で停止、右へ回すと正転、左へ回すと逆転する。つまり、2.5V ±2.5V の電圧を与えることで、正転、逆転を連続的に行おうというしかけ。Arduino から、正転、逆転の切り換え信号と、速度制御用信号を出力します。
- // Brushed Dc-Motor Control v.0.92 2023.1.12 meyon
- class BrushedMotor {
- private:
- const byte potentiometerPin = A0;
- const byte forwardPin = 3;
- const byte reversalPin = 4;
- const byte pwmOutputPin = 5;
- const int forwardArea = 517; // Forward above this value
- const int reversalArea = 506; // Reversal below this value
- const int minimumSetVariable = 100; // Value at startup
- const int maximumSetVariable = 255; // Value at maximum speed
クラス宣言と、定数の定義。
forwardArea は、ボリュームから与えられる値が、この値より大きいとき正転します。reversalArea は、この値より小さい時に逆転。その間の値では停止します。
1023 ≧ forwradArea > reversalArea ≧ 0 にしてくださいませ、エラー判定とかしてませんので。
minimumSetVariable は、モータが始動するときの最低出力デューティ比です。値が小さいと、電流は流れますが、モータが起動できません。maximumSetVariable は、最高速時の出力デューティ比。255 が最大回転数です。
だいたい、100 でモータ電圧 0.9V、145 で1.5Vになります。
- public:
- BrushedMotor() {
- pinMode(forwardPin, OUTPUT);
- pinMode(reversalPin, OUTPUT);
- }
コンストラクタ。ピンモードの設定を行ないます。
ちなみに、モータを複数台にするときは、ピン指定を引数にして渡すとよいですね。
- void obtainSetPoint(bool *p_setFwd, bool *p_setRev, int *p_setDr) {
- static bool forward = LOW;
- static bool reversal = LOW;
- static int dutyRatio = 0;
- int inputValue = analogRead(potentiometerPin);
- if(forwardArea <= inputValue) {
- forward = HIGH;
- reversal = LOW;
- dutyRatio = map(inputValue, forwardArea, 1023, 0, 255);
- } else if (reversalArea >= inputValue) {
- forward = LOW;
- reversal = HIGH;
- dutyRatio = map(inputValue, 0, reversalArea, 255, 0);
- } else {
- forward = HIGH;
- reversal = HIGH;
- dutyRatio = 0;
- }
- *p_setFwd = forward;
- *p_setRev = reversal;
- *p_setDr = constrain(dutyRatio, 0, 255);
- }
設定値を取得する関数です。ボリュームの値によって、正転、逆転の信号と出力デューティ比を返します。
引数としてポインタを指定し、変数の値をポインタの示すアドレスに格納することで、値を戻しています。
C言語では、関数の戻り値はひとつだけです。ここでは 3つの値を返してほしいので、ポインタを利用しました。ポインタを使わずに、グローバル変数を使うことでも可能ですが、まぁ、グローバル変数はなにかと嫌われてるようですし (^_^;)
- int calculateManipulationValue(int duty) {
- static int setVar = 0;
- static int SV = 0;
- static int MVn = 0;
- setVar = map(duty, 0, 255, minimumSetVariable, maximumSetVariable);
- SV = constrain(setVar, minimumSetVariable, maximumSetVariable);
- MVn = SV;
- return MVn;
- }
出力デューティ比から操作目標値、操作量を算出する関数です。
現状では出力デューティ比をそのまま操作量にしています。つまり、実質何もしていない。この部分を、たとえば回転数をフィードバックさせるとか、PID制御するとか、今後の検討項目です。
- void operateMotor(int setFwd, int setRev, int manVar) {
- digitalWrite(forwardPin, setFwd);
- digitalWrite(reversalPin, setRev);
- analogWrite(pwmOutputPin, manVar);
- }
- };
モータの制御をおこなう関数。
正転、逆転の操作信号と、PWM信号のデューティ比制御信号を出力してるだけ。
- BrushedMotor brushedMotor;
- void setup() {
- }
- void loop() {
- static int manipulatedVariable = 0;
- static bool setForward = LOW;
- static bool setReversal = LOW;
- static int setDutyRatio = 0;
- brushedMotor.obtainSetPoint(&setForward, &setReversal, &setDutyRatio);
- manipulatedVariable = brushedMotor.calculateManipulationValue(setDutyRatio);
- brushedMotor.operateMotor(setForward, setReversal, manipulatedVariable);
- }
オブジェクトの生成と、setup()関数、loop()関数。
設定値を取得して、操作量を計算、モータを操作する、そんだけです。特段に変わったことがあるわけではありません。お好きに描いていただければよかろうかと。
ちなみに、フル回転からのフル反転とか、0.1秒間隔での連続反転とか、ブラシ付モータに優しくないことも、できちゃいます。ただ、せめて切り換え時にブレーキかけてやってくださいね。
77行目では、各変数のアドレスを引数として渡しています。
ちなみに、78行目では、ふつーに return で戻り値を返してます。戻り値がひとつなので、これでいいんですけど、統一感、ないなぁ。どーなんだろ?
ブレッドボードのようす
実験中のブレッドボードです。
上のヒートシンクが 3つ並んでいるのが電源部。NJM317 のヒートシンクは熱くなります。2SA1725 のほうは少し暖かに。NJM7805 のはなくてもいいです。
3Vの表示があるラインが Hブリッジ回路です。MOSFETも発熱しないので、放熱は考慮してません。ハードな動作させるときは、ちょっと注意したほうがよいかも、です。
その下が 25KHz PWM発振回路と、Hブリッジの制御ロジック。Arduino は NANO互換機です。
製作後記
今回は、ブラシ付モータ FA-130RA-2270 を Hブリッジ回路で駆動し、PWM で速度を制御する回路とスケッチをつくりました。当初思っていた以上に、安定して制御できているようです。
この回路では、正転、逆転の切り換え信号と、速度制御用の 0 ~ 3.5V のアナログ電圧を与えることで、ブラシ付モータの回転制御ができます。回転数などをアナログ信号でフィードバックすればよいので、簡単な速度一定制御とかなら、Arduino を使わなくても可能です。いろいろ応用できるかなぁと、思ってます。