AccelStepper解読

accelstepper arduino 開発

arduinoにて、複数ステッピングモータを制御するのにAccelStepperというライブラリがあり、結構更新されている。参考できる部分がないか調べる。
自分がダウンロードしたときは、ver1.58で、MultiStepper.hという物も含まれていた。
ファイル内にある。docファイルに、ホームページの仕様ページのhtmlが入っているが、MultiStepperのリンクが切れていたので、調べる際は、ネットで調べて出てくるこちらのページから調べることにした。
AccelStepper
英語でグループがあり質問等がたくさんある。
https://groups.google.com/forum/#!forum/accelstepper

日本だと、こちらの方が何回かに分けて使用した際の状態を載せている。
sliverlaboratory
後は、こちらの方は、単品で使用した際で、少し説明をしてくわえて、コードを書いてくれている。
ProgramResource.net


・単品作動

ProgramResource.netさんの方で公開されているプログラムを変更して試しに使ってみた。変更点は、ドライバーの出力ピン設定をCNCシールドに合わせたこと、ENABLE出力設定8ピンにした。マイクロステップを使用していなかったので、その欄を削除。スイッチを12ピンのつけていないときは動かないようにif (digitalRead(12) == LOW) {をHIGHに変更した。

#include <AccelStepper.h>

AccelStepper stepper1(1,2,5);//x軸ドライバー設定
int stepperspeed = 700;
int movetopos;
char cmd;
float cyclelen = 400;//2*20 one cycle length 使用しないため、そのままにした。
float steps = 200; //steps for 360 degree
#define switchpin 12;

void setup(){
        pinMode(8,OUTPUT);//ENABLE設定
        digitalWrite(8,LOW);
        delay(1000);

        stepper1.setMaxSpeed(stepperspeed*100);
        stepper1.setAcceleration(1000.0);
        stepper1.move(1);
        stepper1.setSpeed(stepperspeed);

        Serial.begin(9600);
        Serial.println("Ready [s###]/[m###]/[d##(cm)]");
}

void loop(){
        if (Serial.available()) {
                cmd = Serial.read();
                movetopos = Serial.parseInt();
                if (cmd == 's') {
                        stepperspeed = movetopos;
                        Serial.print("speed ");
                        Serial.println(movetopos);
                }else if (cmd == 'm') {
                        Serial.print("move ");
                        Serial.println(movetopos);
                        stepper1.move(movetopos);
                        stepper1.setSpeed(stepperspeed);
                }else if (cmd == 'd') {
                        Serial.print("move ");
                        Serial.print(movetopos);
                        Serial.print("cm : ");
                        int movesteps = (int)((((float)movetopos*100)/cyclelen)*steps);
                        Serial.println(movesteps);
                        stepper1.move(movesteps);
                        stepper1.setSpeed(stepperspeed);
                }
        }
        if (digitalRead(12) == HIGH) {
                Serial.println("100cm feed");
                int movesteps = (int)((((float)10000)/cyclelen)*steps);
                stepper1.move(movesteps);
                stepper1.setSpeed(stepperspeed);
                while (stepper1.distanceToGo() != 0)
                        stepper1.runSpeedToPosition();
                stepper1.move(0);
        }

        stepper1.runSpeedToPosition();
}



サンプル例として、
 MultiStepperと MultipleStepperがあるが、MultipleStepperは、フルステップ、ハーフステップ等の違いをみるプログラムかと思われる。そのためMultiStepperをベースに話を進めていく。
AccelStepper stepper1(AccelStepper::FULL4WIRE, 2, 3, 4, 5);

の内容は、stepper1は、
モータの数、モータの数を増やしていくとstepper2、stepper3・・・と一緒に増やす。最大10個まで。

FULL4WIREは、ステップ、ステッピングモータの線数の指定欄で、3線のフルステップ、3線のハーフステップ等を選べる。使用するステップに合わせて変える。
書き方は、3線のフルステップの場合、FULL3WIRE又は、3でよい。
下に対応表を書く。

FUNCTION = 0, DRIVER = 1, FULL2WIRE = 2, FULL3WIRE = 3,
  FULL4WIRE = 4, HALF3WIRE = 6, HALF4WIRE = 8

2, 3, 4, 5は、
出力ピンの設定で、例だとFULL4WIREで4線なので、2,3,4,5となっている。
今回モータドライバーを使うため、ドライバーに繋がっているSTEP/DIRのピンの数字を2つ書くだけでよい。

stepper1.setMaxSpeed(100);マックススピード100だと遅すぎたせいか動かなかった。1000程で動くようになった。setspeedで事足りている。制御上で変更可能範囲?

steppers.addStepper(stepper1);モータのマネジメントに追加する

void loop() 内
long positions[2]; ポジションの保存数使うモータ数に合わせればよい。

positions[0] = 1000;  ポジション指定

steppers.moveTo(positions); 絶対値のポジションに移動、現在値から100ステップ移動したいという時は、run()を使えばよい。

steppers.runSpeedToPosition(); わからない。runSpeed()等と何が違うか、なぜ必要かわからない。

・複数作動・位置指定

何はともあれ、動かすために、プログラムを書いた。速度・加速度に関して、不明なところがあるが、それぞれの絶対位置に移動するプログラムを書けた。
ポジションを4か所設定してあるが、これをコメントアウトして、元々コメントアウトされている。シリアル通信の部分を戻してあげると、それぞれのモータを好きな絶対値に移動できる。


// MultiStepper.pde
// -*- mode: C++ -*-
// Use MultiStepper class to manage multiple steppers and make them all move to
// the same position at the same time for linear 2d (or 3d) motion.

#include <AccelStepper.h>
#include <MultiStepper.h>

// EG X-Y position bed driven by 2 steppers
// Alas its not possible to build an array of these with different pins for each :-(
AccelStepper stepper1(AccelStepper::DRIVER, 2,5);//x
AccelStepper stepper2(AccelStepper::DRIVER, 3,6);//y
AccelStepper stepper3(AccelStepper::DRIVER, 4,7);//z
AccelStepper stepper4(AccelStepper::DRIVER, 12,13);//a

char cmd;
int movetopos;
int movetopos1;
int movetopos2;
int movetopos3;
int movetopos4;
// Up to 10 steppers can be handled as a group by MultiStepper
MultiStepper steppers;

void setup() {
        pinMode(8,OUTPUT);//ENABLE
        digitalWrite(8,LOW);
        Serial.begin(9600);
        // Configure each stepper
        stepper1.setMaxSpeed(500);    //setが複数ある場合遅いほうに合わさった。
        stepper2.setMaxSpeed(500);
        stepper3.setMaxSpeed(500);
        stepper4.setMaxSpeed(500);

        // Then give them to MultiStepper to manage
        steppers.addStepper(stepper1);
        steppers.addStepper(stepper2);
        steppers.addStepper(stepper3);
        steppers.addStepper(stepper4);
}

void loop() {
        long positions[4]; // Array of desired stepper positions

        // if (Serial.available()) {
        //         cmd = Serial.read();
        //         if (cmd == 'a') {
        //                 Serial.print("1motor ");
        //                 movetopos1 = Serial.parseInt();
        //                 Serial.println(movetopos1);
        //         }else if (cmd == 'b') {
        //                 Serial.print("2motor ");
        //                 movetopos2 = Serial.parseInt();
        //                 Serial.println(movetopos2);
        //         }else if (cmd == 'c') {
        //                 Serial.print("3motor ");
        //                 movetopos3 = Serial.parseInt();
        //                 Serial.println(movetopos3);
        //         }else if (cmd == 'd') {
        //                 Serial.print("4motor ");
        //                 movetopos4 = Serial.parseInt();
        //                 Serial.println(movetopos4);
        //         }
        // }

//--------------------------ここから、下点線までコメントアウトして、上のif文をだしてあげると、シリアル通信で好きな位置にそれぞれ移動可能
        positions[0] = 200;//増やした分毎回全部のモータ位置を指定しないと止まる。
        positions[1] = 400;
        positions[2] = 400;
        positions[3] = 400;
        steppers.moveTo(positions);
        steppers.runSpeedToPosition();    // Blocks until all are in position
        delay(1000);

        // Move to a different coordinate
        positions[0] = -100;
        positions[1] = -50;
        positions[2] = -100;
        positions[3] = -200;
        steppers.moveTo(positions);
        steppers.runSpeedToPosition();    // Blocks until all are in position
        delay(1000);

//---------------------------------------------
        positions[0] = movetopos1;
        positions[1] = movetopos2;
        positions[2] = movetopos3;
        positions[3] = movetopos4;
        steppers.moveTo(positions);
        steppers.runSpeedToPosition(); // Blocks until all are in position
        delay(1000);
}