본문 바로가기

Raspberry Pi/Step Motor, Web 01

IoT, Setpping Motor Control

라즈베리파이, 아두이노를 이용하여 웹에서 스테핑모터를 제어하는 예


스테핑모터는 그 이름에서도 암시하는 것처럼, 한 스텝만큼의 각도 단위로 회전량을 제어할 수 있는 특성을 가진 모터를 말한다. 이용자가 모터의 회전각도와 회전속도, 회전방향을 제어할 수 있기 때문에 다양한 기기에 응용되고 있다. 여기서는 웹페이지에서 스테핑모터의 각도와 회전속도를 제어할 수 있도록 라즈베리파이와 아두이노, 그리고 스테핑모터와 스테핑모터 제어보드를 활용해보려고 한다. 물론 휴대전화기에서도 웹브라우저를 이용하면 스테핑모터를 제어할 수 있는 것은 당연한 것이다. 

우선 저가의 스테핑 모터와 제어보드를 구입하여 아두이노를 통해 제어하는 방법을 알아보고 웹페이지에서 콘트롤이 가능하도록 확장해보려고 한다. 이 내용에 이어지는 부분은 여기를 눌러 참조하세요


준비

라즈베리파이 B+, 라즈베리파이에 아두이노 개발환경 설치, Node.js 설치, Node-Serialport 설치

아두이노 UNO,

스테핑모터(28BYJ-48), 스테핑모터 제어보드(ULN2003) , 가격 9,900원, 아두이노 호환

http://www.neromart.co.kr/goods/view?no=12858



각 디바이스 연결 개념도



스테핑모터 제품설명http://www.neromart.co.kr/goods/view?no=12858 )

제품설명 페이지에 포함된 예제

28BYJ-48_ULN2003.zip

/* 
 Stepper Motor Control - one revolution
 
 This program drives a unipolar or bipolar stepper motor. 
 The motor is attached to digital pins 8 - 11 of the Arduino.
 
 The motor should revolve one revolution in one direction, then
 one revolution in the other direction.  
 
  
 Created 11 Mar. 2007
 Modified 30 Nov. 2009
 by Tom Igoe
 Adapted for Arduino Kit geared stepper motor (28BYJ-48) by Rudy Schlaf 2/2014
 
 */

#include <StepperAK.h> //use modified stepper library with 1000/0100/0010/0001 magnet firing sequence. Put library in your library folder.

#define gearratio 64 //1:64 gear ratio
const int stepsPerRevolution = 2048;  //the Arduino Kit motor is geared down. By experiment I determined that 2048 steps turn the shaft one round.
                                     

// instantiate a 4-wire stepper on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8,9,10,11);            

void setup() {
  // set the speed at 0.15 rpm (0.15-0.2 (dep. on particular motor) seems the fastest they can go...set it higher and it stops moving, just makes noises):
  myStepper.setSpeed(0.15*gearratio);//the motor appears to be geared down 1/64, meaning that the speed needs to be set 64x.
  // initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  // step one revolution  in one direction:
   Serial.println("clockwise");
  myStepper.step(stepsPerRevolution);
  delay(500);
  
   // step one revolution in the other direction:
  Serial.println("counterclockwise");
  myStepper.step(-stepsPerRevolution);
  delay(500); 
}



아두이노 개발환경에 외부 라이브러리 설치하기

이 제품을 사용하려면 제공되는 파일을 다운로드하고 그 안에 포함된 라이브러리를 사용해야 한다.

설치된 아두이노 개발환경의 libraries 디렉토리에 외부 라이브러리를 복사해 넣으면 된다.

라즈베리파이에 아두이노 개발환경을 설치한 경우, 필자의 라즈베리파이 버전은 B+인데 다음과 같은 경로에 아두이노 개발환경이 설치된 것을 확인할 수 있었다

/usr/share/arduino/libraries

위에서 다운로드한 스테핑모터용 라이브러리는 위의 libraries 디렉토리에 복사해 넣으면 된다.

보다 자세한 아두이노 외부 라이브러리 설치법은 여기 링크를 눌러 참조하면 된다



스테핑 모터(28BYJ-48)의 상세사양을 통해 알 수 있는 한 스텝에 해당하는 각도의 크기

감속비 : 1/64

한 스텝에 해당하는 회전각도(보폭각도) : 5.625˚ / 64 = 0.087890625˚

1회전당 스텝수 : 360˚ / 0.087890625˚ = 4096 스텝

이 스텝모터의 상세사양에 따른 계산상으론 4096 스텝을 실행(회전)해야만 스텝모터의 축이 1회전하는 것으로 볼 수 있다. 그러나 제공된 예제에서는 그 절반인 2048 스텝을 1회전으로 간주하고 사용하고 있는 것을 확인할 수 있다. 이 스텝모터는 Half-Step Switching Sequence 라는 방법을 사용할 경우에는 4096 스텝이 1회전에 해당하는 것으로 보이며, Half-Step Switching Sequence 를 사용하지 않는 경우에는 4096의 절반인 2048스텝이 1회전을 완성하는 것으로 이해된다. 예제 코드를 보면 분명히 Half-Step Switching Sequence 방법을 사용하지 않고 있음을 알 수 있다. Half-Step Switching Sequence에 대한 개념은 위에서 제시된 상세사양 부분의 표를 보면 알 수 있다


Half-Step Switching Sequence 를 적용하지 않는 경우에는 한 스텝의 각도가 위에서 계산한 [5.625˚ / 64] 의 2배이므로 다음과 같이 한 스텝에 해당하는 각도와 1회전을 완성하는 스텝수를 계산할 수 있다

한 스텝에 해당하는 회전각 : 5.625˚ / 64 * 2 = 0.17578125˚

1회전에 해당하는 총 스텝수 : 360˚ / 0.17578125˚ = 2048 스텝



예제코드 분석

myStepper.setp(2048); 이 모터에 설정된 한 스텝 각도씩 2048번 연속 회전하라

스테핑 모터는 한번에 회전하는 각도가 제품마다 일정하게 지정되어 있는데 위의 예제에 있는 설명과 스텝모터의 상세사양을 보면 2048 스텝을 반복 회전하면 모터의 축이 한바퀴를 회전하게 된다는 것을 알 수 있다. 그러나 속도를 올려서 myStepper.setSpeed(0.16*gearratio) 정도로 설정하고 테스트하면 제대로 회전하지 못하는 것으로 관찰되는데 이는 속도가 너무 높으면 어떤 스텝은 실행될 여유가 없어서 건너 뛰는 경우가 발생하기 때문이다. 그러므로 적정 속도를 넘지 않아야 한다는 점도 주의해야 할 것이다


myStepper.setp(-2048); 반대방향으로 한 스텝씩 2048 스텝을 연속 회전하라


gearratio : 감속비(1/64) : 내장된 모터가 64회 회전할 때 외부 축은 1회전한다

myStepper.setSpeed(0.15*gearratio) : 테스트 결과 감속비의 0.15배의 속도로 설정할 경우 가장 빠르고 안정적으로 회전하는 것으로 관찰된다 이 모터의 속도 설정은 0.04*64 ~ 0.15*64 일 때 안정적으로 작동하는 것으로 보인다.



아래의 loop() 함수가 한번 실행될 때마다 스테핑 모터는 정회전 360도, 역회전 360도를 반복하게 된다

void loop() {
  // step one revolution  in one direction:
  Serial.println("clockwise");
  myStepper.step(stepsPerRevolution); //한 방향으로 2048 스텝(1회전)을 완료할 때까지 이 라인에서 프로세스가 멈춘다
  delay(500);
   
   // step one revolution in the other direction:
  Serial.println("counterclockwise");
  myStepper.step(-stepsPerRevolution); //역 방향으로 2048 스텝(1회전)을 완료할 때까지 이 라인에서 프로세스가 멈춘다
  delay(500);
}



제공된 라이브러리에 포함된 또 다른 예제를 분석해보면 스테핑 모터의 회전방향과 속도를 결정하는 원리를 알 수 있다.

/******************************************
	PURPOSE:	Running a stepper motor with the Arduino
	Created by      Rudy Schlaf after a sketch by Sam Leong
	DATE:		1/2014
*******************************************/

#define pin1  8//these are the Arduino pins that we use to activate coils 1-4 of the stepper motor
#define pin2  9
#define pin3  10
#define pin4  11

#define delaytime 80   //delay time in ms to control the stepper motor delaytime.
                      //Our tests showed that 8 is about the fastest that can yield reliable operation w/o missing steps
                   

void setup() {
  // initialize the 8 pin as an output:
  pinMode(pin1, OUTPUT);
  pinMode(pin2, OUTPUT); 
  pinMode(pin3, OUTPUT); 
  pinMode(pin4, OUTPUT);
}

void loop(){
  int numberOfSteps = 48;
  step_OFF();         //turning all coils off
  while(numberOfSteps>0){
    forward();        //going forward
    numberOfSteps -- ;//counting down the number of steps
  }
  delay(2000);
  
  step_OFF();         //turning all coils off
  numberOfSteps = 48;
  while(numberOfSteps>0){
    backward();       //going backward
    numberOfSteps -- ;//counting down the number of steps
  }
  delay(2000);
}



위의 코드에서 사용된 함수는 또 다른 파일에 다음과 같이 정의되어 있다

아래의 내용에서 알 수 있는 것은 스테핑 모터의 회전방향은 4개의 단자에 전달되는 입력신호의 순서에 따라 결정된다는 것이다. 또한 스테핑 모터의 회전속도는 4개의 단자에 전달되는 신호의 시간적 간격에 따라 결정된다는 것도 아울러 알 수 있다. 회전량(각)은 적용한 스텝의 수에 따라 정해진다는 것도 알 수 있다.

//these functions set the pin settings for each of the four steps per rotation of the motor (keepp in mind that the motor in the kit is geared down,
//i.e. there are many steps necessary per rotation

void Step_A(){
  digitalWrite(pin1, HIGH);//turn on coil 1 
  digitalWrite(pin2, LOW); 
  digitalWrite(pin3, LOW); 
  digitalWrite(pin4, LOW); 
}
void Step_B(){
  digitalWrite(pin1, LOW); 
  digitalWrite(pin2, HIGH);//turn on coil 2
  digitalWrite(pin3, LOW); 
  digitalWrite(pin4, LOW); 
}
void Step_C(){
  digitalWrite(pin1, LOW); 
  digitalWrite(pin2, LOW); 
  digitalWrite(pin3, HIGH); //turn on coil 3
  digitalWrite(pin4, LOW); 
}
void Step_D(){
  digitalWrite(pin1, LOW); 
  digitalWrite(pin2, LOW); 
  digitalWrite(pin3, LOW); 
  digitalWrite(pin4, HIGH); //turn on coil 4
}
void step_OFF(){
  digitalWrite(pin1, LOW); //power all coils down
  digitalWrite(pin2, LOW); 
  digitalWrite(pin3, LOW); 
  digitalWrite(pin4, LOW); 
}

//these functions run the above configurations in forward and reverse order
//the direction of a stepper motor depends on the order in which the coils are turned on.
void forward(){//one tooth forward
  Step_A();
  delay(delaytime);
  Step_B();
  delay(delaytime);
  Step_C();
  delay(delaytime);
  Step_D();
  delay(delaytime);
}

void backward(){//one tooth backward
  Step_D();
  delay(delaytime);
  Step_C();
  delay(delaytime);
  Step_B();
  delay(delaytime);
  Step_A();
  delay(delaytime);
}


내용이 너무 길어진 관계로 웹에서 서버모터를 제어하는 예제는 다른 페이지에 작성합니다 여기를 눌러 참조하면 됩니다