아두이노 강좌 #32 스텝 모터 28BYJ-48 5V 라이브러리 없이 동작 - 여자 방식 비교
Lucy Archive
Lucy 2023
2020. 9. 2. 00:16

Arduino Uno 28BYJ-48 5VArduino Uno 28BYJ-48 5V

Arduino Uno : Step Motor 28BYJ48 5V without Libarary

지난 포스트에서 스텝 모터의 동작 원리에 대해 설명하였습니다. 아두이노에서 스텝모터를 제어하기 위해 지원되는라이브러리를 사용하면 쉽게 제어가 가능합니다. 하지만, 이번 포스트에서는 아두이노에서 많이 사용되는 스텝 모터

28BYJ48 의 동작 원리를 알아보고, 동작 원리대로 라이브러리 없이 스텝 모터를 제어하는 코드를 소개

합니다. 스텝 모터의 기본 동작 원리는 하단의 이전 포스트를 참고해주세요.

Stepper Motor 28BYJ48

28BYJ-48-5V는 아두이노 입문자가 많이 사용하는 스텝 모터(Stepper Motor 또는 Step Motor)중의 하나로 5선식 유니폴라 방식의 스텝 모터 입니다. 스텝 모터는 모터의 한 바퀴를 여러 스텝으로 나누어, 모터 회선의 정밀한 제어가 필요할 때 사용됩니다. 아래는 그림은 28BYJ-48와 이 모터와 함께 사용되는 모터 드라이브 모듈입니다.

28BYJ-48 5V 스텝 모터와 ULN2003 드라이버 모듈28BYJ-48 5V 스텝 모터와 ULN2003 모터 드라이버 모듈

28BYJ-48 5V 주요 스펙

아래는 28BYJ-48 의 스펙의 일부를 정리한 내용입니다. 자세한 스펙은 하단의 [각주:1]데이터 시트 링크를 참조해주세요.

  • Rated Voltage : 5V
  • Number of Phase : 4 - Unipolar Type
  • Speed Variation Ratio : 1/64
  • Stide Angle : 5.625º/64
  • DC Resistance : 50Ω±7%(25℃)
  • Idle In-traction Frequency : > 600Hz
  • Idle Out-traction Frequency : > 1000Hz


Step 수

데이터 시트에서 명기된 Speed Variation Ratio 와 Stride Angle 은 정확히 무엇을 말하는지 모르겠지만, (검색해도 잘 나오지 않음) Stride Angle 은 1 Step(입력 펄스)당 Rotor 가 회전하는 최소각을 의미하고, Speed Variation Ratio 는 로터(모터의 중심)와 연결된 중심축의 기어에서 최종 회전 축까지의 기어비가 1/64 임을 의미하는 것으로 추정됩니다. 즉, 결론적으로 이 모터를 한바퀴 돌리기 위해 64 x 64 = 4096 펄스(Step) 입력이 있어야 한다는 의미입니다. 같은 말이지만, 1바퀴를 4096 Step 으로 정밀하게 제어가 가능하는 의미가 됩니다..

저는 모터 전문가가 아니라서 통상적으로 Step Motor 의 데이터 시트를 이렇게 작성하는 지는 모르겠지만, 이 모듈을 구글링 해보면 실제 모델과 데이터 시트와는 차이가 있어 보입니다. 아래의 영상을 보면 Stator 는 총 4 x 8 = 32개가 있으며, 기어비는 정확하게 63.68395 입니다.

이 말은 이전 시간의 1상 여자, 2상 여자 방식(Full-Step Mode)으로 이 스텝 모터를 제어하는 경우 1바퀴당 32 x 63.68395 = 2037 스텝으로 제어 할 수 있고, 1-2상 여자 방식(Half-Step) 으로 이 스텝 모터를 제어하는 경우 1바퀴당 64 x 63.68395 = 4075 스텝으로 제어 할 수 있습니다.

드라이브 회로

아래는 28BYJ-48 5V 와 보통 함께 사용하는 모터 드라이브 모듈입니다. 모듈에 사용된 IC는 ULN2003 으로 총 7개의 채널을 가지고 각각의 채널에 달링턴 회로가 적용 되었습니다. 이 모듈을 사용하는 이유는 스텝모터를 구동하는 충분한 전류를 공급하게 위해서 사용 됩니다. 아두이노에 사용되는 Atmega328 의 경우 최대 출력 전류가 대략 20mA 로, 대략 200mA 로 구동되는 스텝모터를 직접 제어 할 수 없습니다. 그래서 이 별도의 모터 드라이브 회로가 필요합니다.

ULN2003 내부ULN2003 내부

회로도 및 연결

28BYJ-48 5V 를 테스트 하기 위해 아두이노 우노 보드와 아래와 같이 연결 하였습니다. Arduino Pin Mapping 은 편하신 대로하고, 코드에서 수정하셔도 됩니다. 

Arduino Uno 28BYJ-48 연결 회로도 및 연결 예시Arduino Uno 28BYJ-48 연결 회로도 및 연결 예시


예제 소개

본 포스트에서 28BYJ-48를 테스트 하기 위해 1상 여자 방식, 2상 여자 방식, 1-2상 여자 방식으로 코드를 작성 후 결과를 비교 할 예정입니다. 토크는 제가 따로 측정 할 수 있는 방법이 없어, 여자 방식에 따른 스텝수와 얼마나 빠르게 모터를 돌릴 수 있는지 비교 하겠습니다. 여자 방식에 대한 내용은 하단의 이전 포스트를 참고해주세요.

1상 여자 One Phase on Full Step

1상 여자 방식은 아래와 같이 스테이더 하나씩 여자하며 로터를 회전 시키는 방식 입니다.

1상 여자 One Phase on Full Step1상 여자 One Phase on Full Step

코드 : 1상여자

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
#define motorPin1 11 // IN1
#define motorPin2 10 // IN2
#define motorPin3 9 // IN3
#define motorPin4 8 // IN4
 
#define step 2048 // 1봐퀴 스텝수
 
// 모터 회전 Loop 문 구현을 간단하게 하기위해 핀 배열 선언
int pinArray[4= { motorPin1, motorPin2, motorPin3, motorPin4 };
// CW 시계방향 데이터 전송
int CW[4= {
                0b1000,
                0b0100,
                0b0010,
                0b0001
            };
 
int CCW[4= {
                0b0001,
                0b0010,
                0b0100,
                0b1000
            };
 
void setup(){
    // 스텝모터 드라이브 보드의 IN 연결핀 출력으로 설정
    for(int i = 0 ; i < 4 ; i++ ) pinMode(pinArray[i], OUTPUT);
}
 
void loop(){
    // CW방향 1바퀴 후, CCW 1바퀴 
    int temp;
    for(int i = 0 ; i < step ; i++)
    {
        temp = i % 4;
        digitalWrite(pinArray[0], bitRead(CW[temp], 0));
        digitalWrite(pinArray[1], bitRead(CW[temp], 1));
        digitalWrite(pinArray[2], bitRead(CW[temp], 2));
        digitalWrite(pinArray[3], bitRead(CW[temp], 3));
        delay(3);
    }
    delay(1000);
 
    for(int i = 0 ; i < step ; i++)
    {
        temp = i % 4;
        digitalWrite(pinArray[0], bitRead(CCW[temp], 0));
        digitalWrite(pinArray[1], bitRead(CCW[temp], 1));
        digitalWrite(pinArray[2], bitRead(CCW[temp], 2));
        digitalWrite(pinArray[3], bitRead(CCW[temp], 3));
        delay(3);
    }
    delay(1000);
}
cs

코드 설명

📌 1~4Line : Pin Mappaing 을 위한 선언문 입니다. 본 포스트의 연결 법과 다른 경우 수정 가능합니다.

📌 11~23Line : 1상 여자 방식으로 구동하기 위한 데이터 배열 입니다. CW는 시계반향, CCW 는 반시계방향의 여자방식 코드입니다.

📌 30~54Line loop() : CW방향으로 3ms 간격마다 2048 스텝을 인가 후 1000ms 쉬고 CCW 방향으로 회전을 반복합니다.

모터 부하가 없는 상태에서, 각 스텝 간격이 최소 3ms 이상이어야 정상적으로 동작합니다.

2상 여자 Two Phase on Full Step

2상 여자 방식은 아래와 같이 스테이더 두개씩 동시에 여자하며 로터를 회전 시키는 방식 입니다.

2상 여자 Two Phase on Full Step2상 여자 Two Phase on Full Step

코드 : 2상여자

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
#define motorPin1 11 // IN1
#define motorPin2 10 // IN2
#define motorPin3 9 // IN3
#define motorPin4 8 // IN4
 
#define step 2048 // 1바퀴 스텝수
 
// 모터 회전 Loop 문 구현을 간단하게 하기위해 핀 배열 선언
int pinArray[4= { motorPin1, motorPin2, motorPin3, motorPin4 };
// CW 시계방향 데이터 전송
int CW[4= {
                0b1100,
                0b0110,
                0b0011,
                0b1001
            };
 
int CCW[4= {
                0b1001,
                0b0011,
                0b0110,
                0b1100
            };
 
void setup(){
    // 스텝모터 드라이브 보드의 IN 연결핀 출력으로 설정
    for(int i = 0 ; i < 4 ; i++ ) pinMode(pinArray[i], OUTPUT);
}
 
void loop(){
    // CW방향 1바퀴 후, CCW 1바퀴 
    int temp;
    for(int i = 0 ; i < step ; i++)
    {
        temp = i % 4;
        digitalWrite(pinArray[0], bitRead(CW[temp], 0));
        digitalWrite(pinArray[1], bitRead(CW[temp], 1));
        digitalWrite(pinArray[2], bitRead(CW[temp], 2));
        digitalWrite(pinArray[3], bitRead(CW[temp], 3));
        delay(2);
    }
    delay(1000);
 
    for(int i = 0 ; i < step ; i++)
    {
        temp = i % 4;
        digitalWrite(pinArray[0], bitRead(CCW[temp], 0));
        digitalWrite(pinArray[1], bitRead(CCW[temp], 1));
        digitalWrite(pinArray[2], bitRead(CCW[temp], 2));
        digitalWrite(pinArray[3], bitRead(CCW[temp], 3));
        delay(2);
    }
    delay(1000);
}
cs

코드 설명

위의 1상여자 방식 코드에서 11, 18 Line 의 CW, CCW 배열의 데이터만 변경 되었습니다. 

모터 부하가 없는 상태에서, 각 스텝 간격이 최소 2ms 이상이어야 정상적으로 동작합니다.

1-2상 여자 One Tow Phase on Half Step

1-2상 여자 방식은 아래와 같이 1상 여자 방식과 2상여자 방식을 결합한 방식입니다.

1-2상 여자 One Tow Phase on Half Step1-2상 여자 One Tow Phase on Half Step

코드 : 1-2상 여자

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
#define motorPin1 11 // IN1
#define motorPin2 10 // IN2
#define motorPin3 9 // IN3
#define motorPin4 8 // IN4
 
#define step 4096 // 1바퀴 스텝수
 
// 모터 회전 Loop 문 구현을 간단하게 하기위해 핀 배열 선언
int pinArray[4= { motorPin1, motorPin2, motorPin3, motorPin4 };
// CW 시계방향 데이터 전송
int CW[8= {
                0b1000,
                0b1100,
                0b0100,
                0b0110,
                0b0010,
                0b0011,
                0b0001,
                0b1001
            };
 
int CCW[8= {
                0b1000,
                0b1001,
                0b0001,
                0b0011,
                0b0010,
                0b0110,
                0b0100,
                0b1100
            };
 
void setup(){
    // 스텝모터 드라이브 보드의 IN 연결핀 출력으로 설정
    for(int i = 0 ; i < 4 ; i++ ) pinMode(pinArray[i], OUTPUT);
}
 
void loop(){
    // CW방향 1바퀴 후, CCW 1바퀴 
    int temp;
    for(int i = 0 ; i < step ; i++)
    {
        temp = i % 8;
        digitalWrite(pinArray[0], bitRead(CW[temp], 0));
        digitalWrite(pinArray[1], bitRead(CW[temp], 1));
        digitalWrite(pinArray[2], bitRead(CW[temp], 2));
        digitalWrite(pinArray[3], bitRead(CW[temp], 3));
        delay(1);
    }
    delay(1000);
 
    for(int i = 0 ; i < step ; i++)
    {
        temp = i % 8;
        digitalWrite(pinArray[0], bitRead(CCW[temp], 0));
        digitalWrite(pinArray[1], bitRead(CCW[temp], 1));
        digitalWrite(pinArray[2], bitRead(CCW[temp], 2));
        digitalWrite(pinArray[3], bitRead(CCW[temp], 3));
        delay(1);
    }
    delay(1000);
}
cs

코드 설명

📌 6 Line : 1-2상 여자 방식은 Half Step 구동 방식으로 Full Step 구동 방식보다 1step 당 로터의 이동 각도가 1/2로, 스텝수는 2배입니다.

📌 11~31 Line : 1-2상 여자 구현을 위해 CW, CCW 배열의 데이터를 변경하였습니다.

1-2상 여자 방식으로 코드를 구현한 경우 1바퀴 스텝 수가 4096 이고, 스텝 간격 1ms 이상에서 정상적으로 동작합니다.


결과 비교

아두이노 우노로 3가지 여자 방식의 코드를 사용하여 28BY48 구동한 결과 1바퀴의 스텝 수 최소 스텝 시간 가격이 다른 것을 확인 할 수 있었습니다. 이 모터를 실제 사용 할 경우 샤프트에 부하에 따라 속도는 조정 되어야 합니다.

결과 비교

  • 1상여자(Full Step)
    • Steps / 1-Turn : 2048
    • Step 최소 간격 : 3ms
  • 2상여자(Full Step)
    • Steps / 1-Turn : 2048
    • Step 최소 간격 : 2ms
  • 1-2상여자(Half Step)
    • Steps / 1-Turn : 4096
    • Step 최소 간격 : 1ms

동작 화면


마무리

본 포스트에서

28BYJ-48 5V 스텝 모터를 간략히 소개하고, Arduino Uno 로 3가지 여자 방식의 코드를 소개

하였습니다. 3가지 여자 방식에 따라 1바퀴 스텝수, 최고 회전 속도 등의 차이를 보였습니다. 실제 스텝 모터를 사용하는 경우 속도, 토크, 전력소모등의 우선 순위에 따라 여자 방식이 선정되어야 할 것입니다. 포스트를 쓰다 보니 한 포스트에 너무 많은 내용을 적으려 해서, 설명이 좀 부족한 감이 있지만 이후에 추가적인 예제를 작성 할 예정이니 함께 참고해주세요.

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

관련포스트

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

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

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


  1. 데이터시트 : https://datasheetspdf.com/pdf-file/1006817/Kiatronics/28BYJ-48/1 [본문으로]