
Arduinoなどのマイコンからライブラリ無しでステッピングモーターを回転制御してみたいと思います。前回は1相/2相励磁を行いました。今回は1-2相励磁とマイクロステップ制御を試してみます。
1相/2相励磁のおさらい
1相/2相励磁のおさらいから。ステップのイメージです。
1相励磁

コイル順番に通電しまう。4ステップで1サイクルです。
2相励磁

2つのコイルに同時に通電します。4ステップで1サイクルは1相と同様ですが、回転の位相がずれているイメージ。前回までのおさらいはここまでで。以下から1-2相励磁で実際に制御していこうと思います。
1-2相励磁
まずは1-2相励磁の概要から。
1-2相励磁概要
1-2相励磁は、1相と2相を合体させます。

ステップ | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
A相 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
B相 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
A^相 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 |
B^相 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |
ステップは倍の8ステップで1サイクルとなります。
回路
回路は前回(1相/2相)と同じそのままです。


Hブリッジ回路にDRV8835を使用してます。
プログラム(1-2相励磁)
//2025/07/13 imo Lab. //2相励磁/1-2相励磁 ステッピングモーター制御 RaspberryPi Pico //https://garchiving.com #define A1 15 #define A2 14 #define B1 13 #define B2 12 uint8_t type; void setup() { Serial.begin(115200); analogWriteFreq(60000); pinMode(12, OUTPUT); pinMode(13, OUTPUT); pinMode(14, OUTPUT); pinMode(15, OUTPUT); } void loop() { if (Serial.available() > 0) { type = Serial.read(); } if (type == '1') { //2相励磁 Serial.println("2phase"); motorControl(1, 1, 0, 0); motorControl(0, 1, 1, 0); motorControl(0, 0, 1, 1); motorControl(1, 0, 0, 1); } if (type == '2') { //1-2相励磁 Serial.println("1-2phase"); motorControl(1, 0, 0, 0); motorControl(1, 1, 0, 0); motorControl(0, 1, 0, 0); motorControl(0, 1, 1, 0); motorControl(0, 0, 1, 0); motorControl(0, 0, 1, 1); motorControl(0, 0, 0, 1); motorControl(1, 0, 0, 1); } } void motorControl(bool a, bool b, bool c, bool d) { uint8_t power = 185; analogWrite(A1, a * power); analogWrite(B1, b * power); analogWrite(A2, c * power); analogWrite(B2, d * power); if (type == '1') delay(10); if (type == '2') delay(5); }
シリアル通信で「1」、「2」を送信することで2相と1-2相を切り替えることができます。ステップ数の違いで回転速度が変わってしまうので、delayを変えて速度が変わらないようにしてます。
動作確認

2相励磁の動画です。見た感じだけでは1-2相励磁との違いは全くわかりません。若干振動(騒音)が違う感じです。
続いてマイクロステップです。
マイクロステップ
マイクロステップ概要

左図が先ほどの1-2相励磁で8ステップで1サイクル。右図がマイクロステップの16ステップ(1/4ステップ)を図示してます。マイクロステップはこのようにステップ数をどんどん細かくしていきます。64ステップ(1/16ステップ)くらいまでが一般的のようです。

先ほどのプログラムではスイッチは単純にON/OFF(A相、B相に流す電流は同じ)です。なので2相(合成ベクトル)の時は√2倍の磁束になってます。ほんとは1/√2倍に出力を抑えた方がいいのかも。でマイクロステップはA相、B相に負荷する電流(電圧)の比率を変えてステップ数を増やします。

1/4ステップのA/B相コイルに流す電流パターンのイメージ。ブラシレスモーターの正弦波駆動(ベクトル制御)になんか似てます。

1/16ステップの電流パターンです。見るからに滑らかに回転しそう。
プログラム
//2025/07/14 imo Lab.
//ステッピングモーター マイクロステップ(2~16)
//https://garchiving.com
#define A1 15
#define A2 14
#define B1 13
#define B2 12
float deg, step;
int16_t interval;
void setup() {
Serial.begin(115200);
analogWriteFreq(60000);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
pinMode(14, OUTPUT);
pinMode(15, OUTPUT);
}
void loop() {
if (Serial.available() > 0) {
uint8_t type;
type = Serial.read();
if (type == '1') { // 1/2
step = 45;
interval = 4096;
}
if (type == '2') { // 1/4
step = 22.5;
interval = 2048;
}
if (type == '3') { // 1/8
step = 11.25;
interval = 1024;
}
if (type == '4') { // 1/16
step = 5.625;
interval = 512;
}
if (type == '5') { // 1/32
step = 2.8125;
interval = 256;
}
}
float val1 = sin(deg * PI / 180.0);
float val2 = cos(deg * PI / 180.0);
float val3 = sin(deg * PI / 180.0);
float val4 = cos(deg * PI / 180.0);
val1 > 0 ? val1 = val1 : val1 = 0;
val2 > 0 ? val2 = val2 : val2 = 0;
val3 < 0 ? val3 = val3 : val3 = 0;
val4 < 0 ? val4 = val4 : val4 = 0;
deg == 360.0 - step ? deg = 0.0 : deg += step;
motorControl(val1, val2, abs(val3), abs(val4));
delayMicroseconds(interval);
}
void motorControl(float a, float b, float c, float d) {
float power = 185.0;
analogWrite(A1, a * power);
analogWrite(B1, b * power);
analogWrite(A2, c * power);
analogWrite(B2, d * power);
}
シリアル通信で、ハーフステップから1/32ステップまで切り替えられるようにしてます。ソース掲載しておいてなんですがあまりこのソースコードは使わない方がいいかも。モーターが回転することは現物でも確認したのですがなんかマイクロステップがきちんと機能してるのか怪しいです。
気になる所はぼちぼちあるのですが、今回はステッピングモーター仕組みのが分かれば、ということでこれ以上ソースコードを触るのは止めます。
回転確認

回転とステップの違いは肌間隔でも確認できたのですが、A4988を使用した方がマイクロステップが明らかに滑らかに回転します。ソースコードで気になる所はあるのですが修正するのが面倒なのととりあえず回転はできたのでこれで良しとします。
単純に回転させるだけであれば割と簡単ですが、やはりいろいろと奥が深く難しい所もたくさんありそう。特に理由やこだわりが無ければ専用のドライバモジュールなどを使用した方が良さそうです。
コメント