참고 : [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/
라이브러리 다운로드 :
이제는 라이브러리에 출력 버전이 있네요.
출력 버전에 맞춰 이름을 바꿀 예정입니다.