モータシリーズ第 3 弾、今回はステッピングモータを回してみましょう。
ステッピングモータは、ジャンク箱にあったミネベアミツミの PM42L-048 らしき物。DC24V の 2-2 相励磁、ユニポーラ定電圧駆動という仕様です。たぶん、です。
ステッピングモータについては、ググって下さい。ステッピングモータの回し方についても、ググって下さい m(_ _;)m
まぁ簡単に言うと、内部に 4 つのコイルがあるので、決められた順番に通電するだけです。
前回は、押しボタンスイッチを使ってコイルに順番に通電し、モータが回転することを確認しました。
今回は、こいつを回すための回路を作り、Arduino で制御してみます。
ユニポーラ駆動回路
押しボタンスイッチを押すと、ステッピングモータが正転・逆転するってだけですが、何をするにしても、モータの駆動回路はこのまま利用できます。
スイッチングは Nch MOSFET 2SK4017 (60V 5A) を使いました。FET の駆動は Arduino の出力 5V でできます。
モータの電源は DC24V ですが、ないので、DC12V にしてます。普通に回ります。12V でも電力大きいので、モータは触れないほど熱くなります。連続通電時は火傷に注意です。
ちなみに、許容表面温度は 105℃ です。お湯、沸きます (^_^;)
D2~D5 はサージ電圧の保護用です。
ユニポーラ駆動のスケッチ
いろんなやり方があるんだろうなぁと思いつつ、こんなふうにしてみました。原理を理解したいので、ライブラリは使っていません。
- #define SWITCH_ON LOW
- #define SWITCH_OFF HIGH
- const byte A_1 = 8;
- const byte A_3 = 9;
- const byte B_1 = 10;
- const byte B_3 = 11;
- const byte forwardSwitchPin = 15;
- const byte reverseSwitchPin = 16;
- byte sequence[] = {B1001, B1010, B0110, B0101};
- byte numberOfPhase = sizeof(sequence) / sizeof(sequence[0]);
- void setup() {
- pinMode(A_1, OUTPUT);
- pinMode(A_3, OUTPUT);
- pinMode(B_1, OUTPUT);
- pinMode(B_3, OUTPUT);
- }
- void loop() {
- static bool forward = false;
- static bool reverse = false;
- static int phase = 0;
- static unsigned long period = 50;
- static unsigned long previousTime = millis();
- if((SWITCH_ON == digitalRead(forwardSwitchPin)) && !reverse) {
- forward = true;
- } else if((SWITCH_ON == digitalRead(reverseSwitchPin)) && !forward) {
- reverse = true;
- } else {
- forward = false;
- reverse = false;
- }
- if(forward && !reverse) {
- if(period < millis() - previousTime) {
- previousTime = millis();
- phase++;
- if((numberOfPhase - 1) < phase) phase = 0;
- }
- digitalWrite(A_1, sequence[phase]>>3&1 ? HIGH : LOW);
- digitalWrite(A_3, sequence[phase]>>2&1 ? HIGH : LOW);
- digitalWrite(B_1, sequence[phase]>>1&1 ? HIGH : LOW);
- digitalWrite(B_3, sequence[phase]>>0&1 ? HIGH : LOW);
- } else if(!forward && reverse) {
- if(period < millis() - previousTime) {
- previousTime = millis();
- phase--;
- if(0 > phase) phase = numberOfPhase - 1;
- }
- digitalWrite(A_1, sequence[phase]>>3&1 ? HIGH : LOW);
- digitalWrite(A_3, sequence[phase]>>2&1 ? HIGH : LOW);
- digitalWrite(B_1, sequence[phase]>>1&1 ? HIGH : LOW);
- digitalWrite(B_3, sequence[phase]>>0&1 ? HIGH : LOW);
- } else {
- digitalWrite(A_1, LOW);
- digitalWrite(A_3, LOW);
- digitalWrite(B_1, LOW);
- digitalWrite(B_3, LOW);
- }
- }
11 行目が励磁方式の指定です。このモータの標準は 2-2 相励磁方式です。
2-2 相励磁のシーケンスは下表のとおり。1 のときに通電、0 は非通電です。
A_1 | A_3 | B_1 | B_3 | |
1 | 1 | 0 | 0 | 1 |
2 | 1 | 0 | 1 | 0 |
3 | 0 | 1 | 1 | 0 |
4 | 0 | 1 | 0 | 1 |
このシーケンスが、
- byte sequence[] = {B1001, B1010, B0110, B0101};
のように指定されています。
もちろん、1-1 相励磁でも制御できます。その場合のシーケンスは下表のようになりますから、
A_1 | A_3 | B_1 | B_3 | |
1 | 1 | 0 | 0 | 0 |
2 | 0 | 0 | 1 | 0 |
3 | 0 | 1 | 0 | 0 |
4 | 0 | 0 | 0 | 1 |
- byte sequence[] = {B1000, B0010, B0100, B0001};
のように指定します。
1-1 相励磁では、2-2 相励磁に比較して、軸の位置が 1 ステップの半分の 3.75 度だけずれます。また、トルクが弱くなります。
もう一つ、1-2 相励磁という方式があります。1-1 相励磁と 2-2 相励磁を交互に行なうシーケンスで、
A_1 | A_3 | B_1 | B_3 | |
1 | 1 | 0 | 0 | 0 |
2 | 1 | 0 | 1 | 0 |
3 | 0 | 0 | 1 | 0 |
4 | 0 | 1 | 1 | 0 |
5 | 0 | 1 | 0 | 0 |
6 | 0 | 1 | 0 | 1 |
7 | 0 | 0 | 0 | 1 |
8 | 1 | 0 | 0 | 1 |
- byte sequence[] = {B1000, B1010, B0010, B0110, B0100, B0101, B0001, B1001};
と指定します。
1-2 相励磁ではステップ数 48 の倍のステップで 1 回転しますので、1 ステップは 3.75 度になります。
ちなみに、配列の数は 12 行目で計算しますから、シーケンスの数が増えても、スケッチの他の部分を変更する必要はありません。
25 行目は回転速度の指定で、動きがわかるように 50ms (20Hz) とゆっくり回してます。最高 2ms で回りましたが、1ms では脱調してしまいました。
28〜35 行目は押しボタンスイッチの状態検知。片方を押しているとき、反対側の押しボタンは無視するようにインターロックしています。
44~47 、56~59 行目は、シーケンスで指定したビット列を分解して、各ピンに出力しています。
63~66 行目、停止中は通電を切らないと、燃えます。
ブレッドボード
ブレッドボードの左側にある押しボタンスイッチを押すと、ステッピングモータが正転・逆転します。
中央部分に FET 。部品点数が少ないので簡単ですね。
電源は DC12V 3A のAC アダプタです。
Arduino の電源も共通にしてますが、問題なさそうです。5V 電源は Arduino の出力を使っています。
ちなみに、電解コンデンサがちらほら見えてます。
回路図には書いてませんが、ブレッドボードの電源ラインには必ず 47~100μF ぐらいのコンデンサを入れています。
おまけ:ライブラリで回す
ステッピングモータを回すのに便利なライブラリとして Stepper.h がありますので、使ってみましょう。
Arduino の入力側にボリュームを追加しておきます。ここでは押しボタンスイッチは使いません。
モータの駆動回路部分は変更ありません。
スケッチはスケッチ例 Stepper にある「MotorKnob」ですが、少し変更が必要です。
以下のスケッチは、コメント部分を取り除き、変更してあります。
- #include <Stepper.h>
- #define STEPS 48
- Stepper stepper(STEPS, 8, 9, 10, 11);
- int previous = 0;
- void setup() {
- stepper.setSpeed(30);
- }
- void loop() {
- int val = analogRead(0);
- val = map(val, 0, 1023, 0, STEPS);
- stepper.step(val - previous);
- previous = val;
- }
変更は 2 ヶ所あります。
まず、03 行のステップ数を、このステッピングモータのステップ数 48 に変更します。
次に、ボリュームからの A/D 出力をそのまま動作させるステップ値にすると、目標に到達するまでに時間がかかってしまいますので、15 行目でステップ値を制限しています。これで、ボリュームの最小〜最大でモータが 1 回転することになります。
このスケッチでは常にモータに電圧がかかるので、面白がって連続で動かしているとステッピングモータが燃えます (;´Д`)
規定の半分の 12V でさえこうなのですから、24V かけるのはちょっと怖いです。多分このモータ、プリンタのどこかの機構をガシャンと切換えるのに使っていたんじゃないかと。短時間に大きなトルクが必要で、連続稼働はしないという用途ですね。
ちなみに、モータ電源を 5V にしてもなんとか動きます。発熱が気になるときは電圧下げたほうが良さそう。トルクが小さくなるので、負荷をかけると脱調したり起動しなかったりしますが。
スケッチ例 Stepper には他のスケッチもあります。ほとんどはステップ数を変更するだけで動きますが、中にはスケッチを修正しないと動かないものも。よかったらお試し下さい。
バイポーラとして回すには
ジャンク箱にあった?モータはステッピングモータであることがわかり、ユニポーラ駆動で回すことができました。ここでは一定の電圧を印加して制御しましたので、定電圧駆動ということになります。
さて、ステッピングモータにはバイポーラ駆動というタイプもあります。ユニポーラ型はバイポーラとして動かすこともできますので、次回はこいつをバイポーラ駆動してみたいと考えています。
基本的には、DC ブラシモータでやった H ブリッジ回路と同じはずです。ゆっくり考えてみようと思います。