아두이노 코딩 : 스텝 모터 위치 제어 28BYJ-48 5V
Lucy Archive
Lucy 2023
2020. 9. 2. 23:37

28BYJ-48 5V 스텝 모터 위치 제어28BYJ-48 5V 스텝 모터 위치 제어

Arduino Uno : 28BYJ-48 Position Control Using Serial

아두이노 우노에서 시리얼 통신을 이용하여 Step Motor 28BYJ-48 5V 모듈의 위치를 제어

하는 예제입니다. 이번 예제는 아두이노에서 제공되는 Servo 라이브러리를 사용할 예정입니다. 스텝 모터의 구동 방식에 대해 궁금하신 분은 하단의 관련 포스트를 참고해주세요.

Hardware

준비물

본 예제의 구성품은 아래와 같습니다.

  • Arduino Uno x 1EA
  • Step Motor 28BYJ-48 5V x 1EA
  • ULN2003 Motor Driver Module x 1EA
  • Jumper WIres

회로도 및 연결

Arduino 28BYJ-48 연결 회로도Arduino 28BYJ-48 연결 회로도

ULN2003 모듈과 아두이노 우노 연결은 다른 핀으로 연결 하셔도 무방합니다.

예제 : 스텝모터 위치제어

시리얼 통신으로 각도를 입력하면 Step Motor 가 각도만큼 회전하고, 초기 위치를 0º 기준으로 현재 각도를 출력 합니다. 각도 입력은 int 범위로 한정합니다. 각도는 스텝 모터에서 읽을 수 있는 것은 아니고, 출력 신호를 기억하고 계산하여 현재 각도를 계산합니다. 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <Stepper.h>
 
#define BUADRATE 9600
 
#define IN1 11 // IN1
#define IN2 10 // IN2
#define IN3 9 // IN3
#define IN4 8 // IN4
#define STEPS 2048 // 1봐퀴 스텝수
#define RPM 10 // 10 이하로 설정을 권장 
 
// Stepper 클래스 객체 생성
Stepper myStepper(STEPS, IN1, IN3, IN2, IN4);
// 시리얼 포트로 angle 값을 저장할 문자열
String myString;
int angle = 0// 현재 각도를 저장할 전역 변수
int flag = 0// 시리얼 통신으로 각도 입력시 활성 flag
 
void setup(){
    myStepper.setSpeed(RPM);
    Serial.begin(BUADRATE);
    while(!Serial){
        ;
    }
    delay(1000);
    Serial.println("Program Start..");
    Serial.print("Input Angle >> ");
}
 
void loop(){
    int temp;
    if(flag == 1){   
        temp = myString.toInt();
        // angle 은 현재 추가된 각도를 계속 저장 0 ~ 360도 단위
        angle = (angle + temp) % 360
        // temp 의 각도를 step 으로 변환
        temp = toStep(temp);
        myString = "";
        myStepper.step(temp);
        Serial.print("Present Angle : ");
        Serial.println(angle);
        delay(20);
        Serial.print("Input Angle >> ");
        flag = false;
    }
    delay(100);
}
 
void serialEvent()
{
    char cTemp = (char)Serial.read();
    // 시리얼 포트에서 입력 받을 수 있는 문자는 숫자, Backspace, - 기호만 허용
    if (isDigit(cTemp) || cTemp == '\b'|| cTemp == '-'){
        myString += cTemp;
    }
    // 엔터 입력시 각도를 다 입력 한 것으로 침
    else if(cTemp == '\n'){
        flag = true;
    }
    // 아무 값 입력없이 Enter 를 치면 경고 메세지 출력
    else if(cTemp == '\r'){
        if (myString == "") ErrorHadler();
    }
    else /* if (cTemp < '0' || cTemp > '9') */{
        ErrorHadler();
    }
}
// 시리얼 통신으로 부터 입력 받은 각도를 step 으로 변환
// CW, CCW 각도 모두 사용 가능
// 360도를 초과할 때도 처리 가능
int toStep(int angle){
    int quotient = angle / 360;
    int remainder = angle % 360;
    remainder = map(remainder, -360360-20482048);
    if(abs(quotient) > 0)
        return (2048 * quotient) + remainder;
    else
        return remainder;
}
 
void ErrorHadler()
{
    Serial.print('\r');
    Serial.print('\n');
    Serial.println("Error! Input Angle Number..");
    myString = "";
    Serial.print("Input Angle >> ");
}
cs

코드 설명

📌 35 Line angle = ( angle + temp ) % 360 : angle 변수에 변경될 스텝 모터의 절대 각도를 저장합니다. temp는 시리얼 통신으로 입력 받은 각도입니다.

📌 49~66 Line serialEvent() : 시리얼 수신 버퍼에 데이터가 있는 경우 호출 되는 함수로 시리얼통신으로 숫자가 입력 후 엔터가 입력되면 flag 를 true 로 활성화합니다. 

📌 71~79 Line toStep() : 시리얼 통신으로 입력 받은 숫자를 턴 수로 반환합니다. ±360º 이상 입력 된 숫자도 처리하기 하도록 코드를 작성하였습니다. 

📌 81~88 Line ErrorHandler() : 시리얼 통신으로 정상적인 각도(숫자) 값이 들어오지 않은 경우 에러를 출력하는 함수 입니다.


실행 결과

위 예제를 실행하면 아래 영상과 같이 시리얼 통신으로 각도를 입력 받은 만큼 스텝모터가 회전하고 현재의 각도를 반환합니다. 

마무리

이번 포스트에서는 Stepper 모터 사용 응용 예제로 위치를 제어하는 코드를 소개하였습니다. 스텝 모터 라이브러리 자체에 위치를 기억하는 기능이 있는 것은 아니고,

출력한 데이터를 기억하고, 초기 상태를 기준으로 상대 각도를 기억하는 방식으로 구현

하였습니다.

끝까지 읽어 주셔서 감사합니다.😄

관련포스트

👉 아두이노 시리얼 통신 관련글 목록 보기

👉 아두이노 STEPPER MOTOR 관련글 목록 보기

👉 아두이노 모터 관련글 목록 보기

👉 아두이노 관련글 전체 목록 보기