참고 : [Arduino] StepperAsync5 - 비동기 스탭 모터 라이브러리
저번에 "한 번에 2개 이상의 스테핑 모터를 제어하기"를 했었는데.......
'Stepper'라이브러리가 업데이트 많이 됐군요. ㅎㅎㅎ
버전에 맞춰 업데이트해보았습니다.
이전 글에서 'Stepper.h'는 '.step()'이 동작하는 동안 다른 동작을 할 수 없다고 이야기했습니다.
(참고 : [Arduino] 'Stepper.h'는 두개의 모터를 제어할 수 없다. )
그래서 'Stepper.h'를 수정한 라이브러를 작성하고 사용하는 방법에 대한 포스팅입니다.
기존 'Stepper'를 수정하는 방법은 이전 글에서 다뤘으므로 이 포스팅은 수정된 코드만 나열합니다.
헤더는 거의 그대로입니다.
참고 : github - StepperMulti5.h
/* StepperMulti5.h ( http://blog.danggun.net/2092 ) 이 라이브러리는 아두이노의 'Stepper.h'를 개조한 라이브러리입니다. (Stepper.h : http://arduino.cc/en/reference/stepper ) 모든 내용은 'Stepper.h'와 거의 동일합니다. (1.1.0버전 기준) */ /* * Stepper.h - Stepper library for Wiring/Arduino - Version 1.1.0 * * Original library (0.1) by Tom Igoe. * Two-wire modifications (0.2) by Sebastian Gassner * Combination version (0.3) by Tom Igoe and David Mellis * Bug fix for four-wire (0.4) by Tom Igoe, bug fix from Noah Shibley * High-speed stepping mod by Eugene Kozlenko * Timer rollover fix by Eugene Kozlenko * Five phase five wire (1.1.0) by Ryan Orendorff * * * http://www.arduino.cc/en/Tutorial/Stepper */ // ensure this library description is only included once #ifndef StepperMulti5_h #define StepperMulti5_h // library interface description class StepperMulti5 { public: // constructors: StepperMulti5(int number_of_steps, int motor_pin_1, int motor_pin_2); StepperMulti5(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4); StepperMulti5(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4, int motor_pin_5); // speed setter method: void setSpeed(long whatSpeed); // mover method: void setStep(int number_of_steps); //'loop()'안에서 이 메소드를 호출해야 한다. void moveStep(); int version(void); private: void stepMotor(int this_step); int direction; // Direction of rotation unsigned long step_delay; // delay between steps, in ms, based on speed int number_of_steps; // total number of steps this motor can take int pin_count; // how many pins are in use. int step_number; // which step the motor is on // motor pin numbers: int motor_pin_1; int motor_pin_2; int motor_pin_3; int motor_pin_4; int motor_pin_5; // Only 5 phase motor unsigned long last_step_time; // time stamp in us of when the last step was taken //스템 저장 int steps_left; }; #endif
약간 바뀐 것이 있는데.....크진 않습니다.
step_number
를
this->step_number
로 바꿔줍니다.
참고 : github - StepperMulti5.cpp
/* StepperMulti5.h ( http://blog.danggun.net/2092 ) 이 라이브러리는 아두이노의 'Stepper.h'를 개조한 라이브러리입니다. (Stepper.h : http://arduino.cc/en/reference/stepper ) 모든 내용은 'Stepper.h'와 거의 동일합니다. (1.1.0버전 기준) */ /* * Stepper.cpp - Stepper library for Wiring/Arduino - Version 1.1.0 * * Original library (0.1) by Tom Igoe. * Two-wire modifications (0.2) by Sebastian Gassner * Combination version (0.3) by Tom Igoe and David Mellis * Bug fix for four-wire (0.4) by Tom Igoe, bug fix from Noah Shibley * High-speed stepping mod by Eugene Kozlenko * Timer rollover fix by Eugene Kozlenko * Five phase five wire (1.1.0) by Ryan Orendorff * * http://www.arduino.cc/en/Tutorial/Stepper */ #include "Arduino.h" //헤더 연결 변경 #include "StepperMulti5.h" /* * two-wire constructor. * Sets which wires should control the motor. */ StepperMulti5::StepperMulti5(int number_of_steps, int motor_pin_1, int motor_pin_2) { //스탭초기화 this->steps_left = 0; this->step_number = 0; // which step the motor is on this->direction = 0; // motor direction this->last_step_time = 0; // time stamp in us of the last step taken this->number_of_steps = number_of_steps; // total number of steps for this motor // Arduino pins for the motor control connection: this->motor_pin_1 = motor_pin_1; this->motor_pin_2 = motor_pin_2; // setup the pins on the microcontroller: pinMode(this->motor_pin_1, OUTPUT); pinMode(this->motor_pin_2, OUTPUT); // When there are only 2 pins, set the others to 0: this->motor_pin_3 = 0; this->motor_pin_4 = 0; this->motor_pin_5 = 0; // pin_count is used by the stepMotor() method: this->pin_count = 2; } /* * constructor for four-pin version * Sets which wires should control the motor. */ StepperMulti5::StepperMulti5(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4) { //스탭초기화 this->steps_left = 0; this->step_number = 0; // which step the motor is on this->direction = 0; // motor direction this->last_step_time = 0; // time stamp in us of the last step taken this->number_of_steps = number_of_steps; // total number of steps for this motor // Arduino pins for the motor control connection: this->motor_pin_1 = motor_pin_1; this->motor_pin_2 = motor_pin_2; this->motor_pin_3 = motor_pin_3; this->motor_pin_4 = motor_pin_4; // setup the pins on the microcontroller: pinMode(this->motor_pin_1, OUTPUT); pinMode(this->motor_pin_2, OUTPUT); pinMode(this->motor_pin_3, OUTPUT); pinMode(this->motor_pin_4, OUTPUT); // When there are 4 pins, set the others to 0: this->motor_pin_5 = 0; // pin_count is used by the stepMotor() method: this->pin_count = 4; } /* * constructor for five phase motor with five wires * Sets which wires should control the motor. */ StepperMulti5::StepperMulti5(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4, int motor_pin_5) { //스탭초기화 this->steps_left = 0; this->step_number = 0; // which step the motor is on this->direction = 0; // motor direction this->last_step_time = 0; // time stamp in us of the last step taken this->number_of_steps = number_of_steps; // total number of steps for this motor // Arduino pins for the motor control connection: this->motor_pin_1 = motor_pin_1; this->motor_pin_2 = motor_pin_2; this->motor_pin_3 = motor_pin_3; this->motor_pin_4 = motor_pin_4; this->motor_pin_5 = motor_pin_5; // setup the pins on the microcontroller: pinMode(this->motor_pin_1, OUTPUT); pinMode(this->motor_pin_2, OUTPUT); pinMode(this->motor_pin_3, OUTPUT); pinMode(this->motor_pin_4, OUTPUT); pinMode(this->motor_pin_5, OUTPUT); // pin_count is used by the stepMotor() method: this->pin_count = 5; } /* * Sets the speed in revs per minute */ void StepperMulti5::setSpeed(long whatSpeed) { this->step_delay = 60L * 1000L * 1000L / this->number_of_steps / whatSpeed; } /* * Moves the motor steps_to_move steps. If the number is negative, * the motor moves in the reverse direction. */ void StepperMulti5::setStep(int steps_to_move) { //전역 번수에 스탭을 저장한다. this->steps_left = abs(steps_to_move); // how many steps to take // determine direction based on whether steps_to_mode is + or -: if (steps_to_move > 0) { this->direction = 1; } if (steps_to_move < 0) { this->direction = 0; } //스탭을 진행 한다. moveStep(); } /* * loop안에서 호출하여 스탭모터의 동작을 제어한다. */ void StepperMulti5::moveStep() { // decrement the number of steps, moving one step each time: // while -> if // 'while'의 역할을 'loop'가 대신 해주기 때문에 여기서는 'while'가 필요없다. //while (steps_left > 0) if(this->steps_left > 0) { unsigned long now = micros(); // move only if the appropriate delay has passed: if (now - this->last_step_time >= this->step_delay) { // get the timeStamp of when you stepped: this->last_step_time = now; // increment or decrement the step number, // depending on direction: if (this->direction == 1) { this->step_number++; if (this->step_number == this->number_of_steps) { this->step_number = 0; } } else { if (this->step_number == 0) { this->step_number = this->number_of_steps; } this->step_number--; } //스탭 남은 개수를 전역변수에 저장한다. this->steps_left--;// decrement the steps left: // step the motor to step number 0, 1, ..., {3 or 10} if (this->pin_count == 5) stepMotor(this->step_number % 10); else stepMotor(this->step_number % 4); } } } /* * Moves the motor forward or backwards. */ void StepperMulti5::stepMotor(int thisStep) { if (this->pin_count == 2) { switch (thisStep) { case 0: // 01 digitalWrite(motor_pin_1, LOW); digitalWrite(motor_pin_2, HIGH); break; case 1: // 11 digitalWrite(motor_pin_1, HIGH); digitalWrite(motor_pin_2, HIGH); break; case 2: // 10 digitalWrite(motor_pin_1, HIGH); digitalWrite(motor_pin_2, LOW); break; case 3: // 00 digitalWrite(motor_pin_1, LOW); digitalWrite(motor_pin_2, LOW); break; } } if (this->pin_count == 4) { switch (thisStep) { case 0: // 1010 digitalWrite(motor_pin_1, HIGH); digitalWrite(motor_pin_2, LOW); digitalWrite(motor_pin_3, HIGH); digitalWrite(motor_pin_4, LOW); break; case 1: // 0110 digitalWrite(motor_pin_1, LOW); digitalWrite(motor_pin_2, HIGH); digitalWrite(motor_pin_3, HIGH); digitalWrite(motor_pin_4, LOW); break; case 2: //0101 digitalWrite(motor_pin_1, LOW); digitalWrite(motor_pin_2, HIGH); digitalWrite(motor_pin_3, LOW); digitalWrite(motor_pin_4, HIGH); break; case 3: //1001 digitalWrite(motor_pin_1, HIGH); digitalWrite(motor_pin_2, LOW); digitalWrite(motor_pin_3, LOW); digitalWrite(motor_pin_4, HIGH); break; } } if (this->pin_count == 5) { switch (thisStep) { case 0: // 01101 digitalWrite(motor_pin_1, LOW); digitalWrite(motor_pin_2, HIGH); digitalWrite(motor_pin_3, HIGH); digitalWrite(motor_pin_4, LOW); digitalWrite(motor_pin_5, HIGH); break; case 1: // 01001 digitalWrite(motor_pin_1, LOW); digitalWrite(motor_pin_2, HIGH); digitalWrite(motor_pin_3, LOW); digitalWrite(motor_pin_4, LOW); digitalWrite(motor_pin_5, HIGH); break; case 2: // 01011 digitalWrite(motor_pin_1, LOW); digitalWrite(motor_pin_2, HIGH); digitalWrite(motor_pin_3, LOW); digitalWrite(motor_pin_4, HIGH); digitalWrite(motor_pin_5, HIGH); break; case 3: // 01010 digitalWrite(motor_pin_1, LOW); digitalWrite(motor_pin_2, HIGH); digitalWrite(motor_pin_3, LOW); digitalWrite(motor_pin_4, HIGH); digitalWrite(motor_pin_5, LOW); break; case 4: // 11010 digitalWrite(motor_pin_1, HIGH); digitalWrite(motor_pin_2, HIGH); digitalWrite(motor_pin_3, LOW); digitalWrite(motor_pin_4, HIGH); digitalWrite(motor_pin_5, LOW); break; case 5: // 10010 digitalWrite(motor_pin_1, HIGH); digitalWrite(motor_pin_2, LOW); digitalWrite(motor_pin_3, LOW); digitalWrite(motor_pin_4, HIGH); digitalWrite(motor_pin_5, LOW); break; case 6: // 10110 digitalWrite(motor_pin_1, HIGH); digitalWrite(motor_pin_2, LOW); digitalWrite(motor_pin_3, HIGH); digitalWrite(motor_pin_4, HIGH); digitalWrite(motor_pin_5, LOW); break; case 7: // 10100 digitalWrite(motor_pin_1, HIGH); digitalWrite(motor_pin_2, LOW); digitalWrite(motor_pin_3, HIGH); digitalWrite(motor_pin_4, LOW); digitalWrite(motor_pin_5, LOW); break; case 8: // 10101 digitalWrite(motor_pin_1, HIGH); digitalWrite(motor_pin_2, LOW); digitalWrite(motor_pin_3, HIGH); digitalWrite(motor_pin_4, LOW); digitalWrite(motor_pin_5, HIGH); break; case 9: // 00101 digitalWrite(motor_pin_1, LOW); digitalWrite(motor_pin_2, LOW); digitalWrite(motor_pin_3, HIGH); digitalWrite(motor_pin_4, LOW); digitalWrite(motor_pin_5, HIGH); break; } } } /* version() returns the version of the library: */ int StepperMulti5::version(void) { return 5; }
이제 테스트 코드를 만들어 봅시다.
참고 : github - StepperMulti5_Examples.ino
#include <StepperMulti5.h> StepperMulti5 stepper(200, 12, 11, 10, 9); StepperMulti5 stepper2(200, 7, 6, 5, 4); void setup() { Serial.begin(9600); stepper.setSpeed(30); stepper2.setSpeed(60); } void loop() { if (Serial.available()) { int steps = Serial.parseInt(); if(steps != 0) { stepper.setStep(steps); stepper2.setStep(steps); //stepper.setStep(200); //stepper2.setStep(200); Serial.print("steps : "); Serial.println(steps); } } stepper.moveStep(); stepper2.moveStep(); }
이제 테스트를 해봅시다.
완성된 샘플 : Github - Arduino_StepperMulti5/
라이브러리 다운로드 :
이제는 라이브러리에 출력 버전이 있네요.
출력 버전에 맞춰 이름을 바꿀 예정입니다.