前回はサーボをポテンショメーターで制御しました。
今回はステッピングモーターの制御を学びましょう!
ステッピングモーターとは
ステッピングモーターは、電子パルス信号を角度変位または直線変位に変換するオープンループ制御デバイスです。モーターに過負荷が掛かっていない状態では、モータの速度および停止位置はパルス信号の周波数とパルス数にのみ依存し、DCモーターのように負荷の変化によって影響を受けることはありません。以下に、小型の4相減速ステッピングモーターを示します:
- オープンループ制御: 操作対象(この場合、モーター)からのフィードバックを受けずに制御を行う方式。
- パルス信号: デジタル信号の一種で、一定間隔で発生する高電圧と低電圧の繰り返し。
- 減速ステッピングモーター: 歯車などを内蔵し、回転の出力を減速させているステッピングモーター。トルクが高くなる。
4相ステッピングモーターの電子回路図は次のとおりです
ステッピングモーターの外側ケース(またはハウジング)はステーターであり、ステーターの内側にはローターがあります。通常、ステーター上にはモーターの相数の整数倍の独立したコイルが存在します。ステーターが電力供給されると、電磁場が形成され、ローター表面の対応する凸状の溝あるいは窪みを吸引します。ローターは通常、鉄または永久磁石でできています。従って、ステッピングモーターは、ステーターのコイルに順番に電力を供給することで(一連の「ステップ」または段階的な動きを生成して)駆動することができます。
一般的な制御手順は以下のとおりです。
上記の説明では、ステッピングモーターは一度に一定の角度回転し、これを1ステップと呼びます。回転ステップ数を制御することで、ステッピングモーターの回転角度を制御できます。2つのステップ間の時間を制御することで、ステッピングモーターの回転速度を制御できます。時計回りに回転するときは、コイルに電力を供給する順序はA→B→C→D→A→……です。ローターはこの順序に従って回転し、1ステップずつ前進します。これを「四歩四拍(4ステップ4パート)」と呼びます。もしコイルに逆順で電力を供給した場合、D→C→B→A→D→ … となると、ローターは反時計回りに回転します。
ステッピングモーターを制御する別の方法もあります。たとえば、A相に接続し、次にAB相に接続すると、ステーターがABの中央に配置され、これを「ハーフステップ」と呼びます。この方法により、ステッピングモーターの安定性が向上し、ノイズが低減します。コイルへの電力供給のシーケンスは、A→AB→B→BC→C→CD→D→DA→A → …のようになり、ロータはこのシーケンスに従って0.5ステップずつ回転します。これを、「四歩八拍(4ステップ8パート)」と呼びます。逆に、コイルに逆順で電力を供給すると、ステッピングモーターは反対方向に回転します。
今回のキットで提供されるステッピングモーターのステーターには32個の磁極があります。したがって、1周を完了するには32回のフルステップが必要です。ステッピングモーターのローター(または出力シャフト)は、減速ギアのセットに接続されており、減速比は1:64です。したがって、最終出力シャフトは1周するのに32 X 64 = 2048ステップを必要とします。
ULN2003 ステッピングモータードライバーについて
ULN2003ステッピングモータードライバは、ステッピングモーターを駆動するために、弱い信号をより強力な制御信号に変換するために使用されます。下の図では、入力信号IN1-IN4が出力信号A-Dに対応しており、これらの信号の状態を示すために4つのLEDが基板に内蔵されています。 PWRインターフェースは、ステッピングモータの電源として使用できます。デフォルトでは、PWRとVCCは接続されています。
回路図
回路を構築する際には、ステッピングモーターの定格電圧が5Vであることに注意し、ブレッドボード電源を独立して使用してください。さらに、ブレッドボード電源はESP32-S3とグランドを共有する必要があります。
接続図
コード
/**********************************************************************
Filename : Drive Stepper Motor
Description : Use ULN2003 to drive the stepper motor.
Auther : www.freenove.com
Modification: 2022/10/25
**********************************************************************/
// Conncet the port of the stepper motor driver
int outPorts[] = {14, 13, 12, 11};
void setup() {
// set pins to output
for (int i = 0; i < 4; i++) {
pinMode(outPorts[i], OUTPUT);
}
}
void loop()
{
// Rotate a full turn
moveSteps(true, 32 * 64, 3);
delay(1000);
// Rotate a full turn towards another direction
moveSteps(false, 32 * 64, 3);
delay(1000);
}
//Suggestion: the motor turns precisely when the ms range is between 3 and 20
void moveSteps(bool dir, int steps, byte ms) {
for (unsigned long i = 0; i < steps; i++) {
moveOneStep(dir); // Rotate a step
delay(constrain(ms,3,20)); // Control the speed
}
}
void moveOneStep(bool dir) {
// Define a variable, use four low bit to indicate the state of port
static byte out = 0x01;
// Decide the shift direction according to the rotation direction
if (dir) { // ring shift left
out != 0x08 ? out = out << 1 : out = 0x01;
}
else { // ring shift right
out != 0x01 ? out = out >> 1 : out = 0x08;
}
// Output singal to each port
for (int i = 0; i < 4; i++) {
digitalWrite(outPorts[i], (out & (0x01 << i)) ? HIGH : LOW);
}
}
void moveAround(bool dir, int turns, byte ms){
for(int i=0;i<turns;i++)
moveSteps(dir,32*64,ms);
}
void moveAngle(bool dir, int angle, byte ms){
moveSteps(dir,(angle*32*64/360),ms);
}
コード解説
setup()関数とloop()関数は説明不要ですね。初期化と動きの指定、待ち時間の設定というところです。
メインの1つ目が28行目です。
moveSteps関数はステッピングモーターの回転方向、回転ステップ数、そして回転スピードを制御することができます。既にご存じのとおり、ステッピングモーターは1回転するために32*64ステップを要します。回転速度はパラメータ ms によって決まります。ms が大きいほど回転速度は遅くなりますなります。モーターの回転スピードには、モーター自身によって決定される範囲があります。私たちの実験によると、ms の値は3〜20に限定されます。
void moveSteps(bool dir, int steps, byte ms) {
for (unsigned long i = 0; i < steps; i++) {
moveOneStep(dir); // Rotate a step
delay(constrain(ms,3,20)); // Control the speed
}
}
次にmoveOneStep()関数を見てみましょう。
moveOneStep()関数 は、ステッピングモーターを時計回りまたは反時計回りに回転させるために使用されます。パラメータ dir は回転方向を示します。dir が true を返すと、ステッピングモーターは時計回りに回転し、そうでなければ反時計回りに回転します。
静的なバイト型変数を定義し、モーターの回転方向に応じて変数値を計算します。さらに、キーワード static を使用して、ステッピングモーターの前回ステップの位置状態を保存します。変数の最下位4ビットを使って、4つのピンの出力状態を制御します。
void moveOneStep(bool dir) {
// Define a variable, use four low bit to indicate the state of port
static byte out = 0x01;
// Decide the shift direction according to the rotation direction
if (dir) { // ring shift left
out != 0x08 ? out = out << 1 : out = 0x01;
}
else { // ring shift right
out != 0x01 ? out = out >> 1 : out = 0x08;
}
// Output singal to each port
for (int i = 0; i < 4; i++) {
digitalWrite(outPorts[i], (out & (0x01 << i)) ? HIGH : LOW);
}
}
変数out
の役割: 4つの出力ピン(outPorts[]
)の状態を制御しており、最下位4ビットがそれぞれ一つの出力ピンに対応しています。
ビットシフトによる制御: out
変数の値を左または右にビットシフトし、出力ピンの状態を循環的に変化させます。これによりステッピングモーターが回転します。
このコードにおけるビットシフトの動作
- リングシフトの実現:
out != 0x08 ? out = out << 1 : out = 0x01;
とout != 0x01 ? out = out >> 1 : out = 0x08;
の部分で、循環的な(リング状の)シフトを実現しています。- 左シフトの場合: ビットパターンが
1000 -> 0100 -> 0010 -> 0001 -> 1000...
のように左へ循環します。 - 右シフトの場合: ビットパターンが
0001 -> 1000 -> 0100 -> 0010 -> 0001 ...
のように右へ循環します。
- 左シフトの場合: ビットパターンが
out
変数と出力ピンの対応:out & (0x01 << 1)
の部分では、out
変数の値とビットマスクを論理積(AND)演算しています。これにより、4ビットのうち一つを選択し、その状態(HIGH または LOW)を出力します。
いかがでしょうか?動作を追いかけることができたでしょうか?もし分かりづらいところがあれば加筆していきますので、コメントをお寄せください。
次回はLCDディスプレイに文字を表示させてみましょう!
コメント