(아두이노) 스텝모터 28BYJ-48 이해하기
아두이노 기본 키트에 딸려오는 5V 스텝모터 28BYJ-48이 궁금해서 이번에 좀 들여다보니 상당히 재미있는 녀석이었다.
최근에 같은 곳에서 구입한 2개는 회전 방향이 서로 같았는데, 아두이노 기본 키트에 들어 있는 녀석은 최근 것과는 회전 방향이 반대였다.
기본으로 깔리는 examples를 좀 들여다 보다가, '심심한 녹칸다' 채널에서 자세히 설명해놓은 게 있어서 도움이 되었다.
[아두이노#618] arduino에 accelstepper 라이브러리로 스탭모터(28byj-48)와 드라이버(uln2003)를 마이크로스탭으로 제어하는 방법!(녹칸다의 아두이노)
https://www.youtube.com/live/5-aWJF_npLQ?si=25GQqnn8X5y8B93Z
아두이노 센서 쉴드 v50을 사용하고 있었는데 오작동이 좀 되길래, 우노 보드만 사용했더니 잘 진행이 되었다.
아울러 이 스텝모터의 기본 원리와 작동 방식을 설명하는 글을 보고는 꽤 도움이 되었다.
https://m.blog.naver.com/darknisia/221652111026
아래는 이 블로그를 보면서 타이핑해본 코드다. 마이크로세컨즈 단위로 적용을 해보았는데 결국 1 밀리세컨즈가, 작동 가능한 가장 짧은 딜레이였다.
#define my_delay 1
#define delay_function2 delayMicroseconds(1000)
#define delay_function delay(1)
int IN1 = 2;
int IN2 = 3;
int IN3 = 4;
int IN4 = 5;
void setup() {
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
}
void loop() {
for (int i = 0; i < 512; i++) { // 8 * 512 = 4096 steps per one revolution
// 1
digitalWrite(IN1, 0); // blue
digitalWrite(IN2, 0); // pink
digitalWrite(IN3, 0); // yellow
digitalWrite(IN4, 1); // orange
delay_function;
// 2
digitalWrite(IN1, 0);
digitalWrite(IN2, 0);
digitalWrite(IN3, 1);
digitalWrite(IN4, 1);
delay_function;
// 3
digitalWrite(IN1, 0);
digitalWrite(IN2, 0);
digitalWrite(IN3, 1);
digitalWrite(IN4, 0);
delay_function;
// 4
digitalWrite(IN1, 0);
digitalWrite(IN2, 1);
digitalWrite(IN3, 1);
digitalWrite(IN4, 0);
delay_function;
// 5
digitalWrite(IN1, 0);
digitalWrite(IN2, 1);
digitalWrite(IN3, 0);
digitalWrite(IN4, 0);
delay_function;
// 6
digitalWrite(IN1, 1);
digitalWrite(IN2, 1);
digitalWrite(IN3, 0);
digitalWrite(IN4, 0);
delay_function;
// 7
digitalWrite(IN1, 1);
digitalWrite(IN2, 0);
digitalWrite(IN3, 0);
digitalWrite(IN4, 0);
delay_function;
// 8
digitalWrite(IN1, 1);
digitalWrite(IN2, 0);
digitalWrite(IN3, 0);
digitalWrite(IN4, 1);
delay_function;
}
delay(2000);
}
위 반복문을 2차원 배열을 통해 좀 단순화해보았다. 이런 식으로 꼼꼼하게 함수들을 만들어나가면 이 스텝 모터의 라이브러리가 되는 것이겠지. 아무튼 accelstepper 라이브러리가 꽤 쓸만한 녀석 같다. 좀 큰 스텝 모터인 nema17과 그 드라이버 보드도 구입해야겠는데...
steps_8_forward 함수에서 속도를 10으로 (즉 내부에서 딜레이 타임 100 밀리세컨즈, 0.1초) 돌려보니까 개미처럼 천천히 기어가는 것이 참 재미있다. 언뜻 보기에는 안 돌아가는 것 같았는데 오래동안 놔두니 한바퀴 돌긴 한다. ㅋㅋ
int IN1 = 2;
int IN2 = 3;
int IN3 = 4;
int IN4 = 5;
bool switching_sequence[8][4] = { {0, 0, 0, 1}, {0, 0, 1, 1},
{0, 0, 1, 0}, {0, 1, 1, 0}, {0, 1, 0, 0}, {1, 1, 0, 0}, {1, 0, 0, 0}, {1, 0, 0, 1} };
void steps_8_forward(int motor_speed__) {
for (int i = 0; i < 8; i++) {
digitalWrite(IN1, switching_sequence[i][0]);
digitalWrite(IN2, switching_sequence[i][1]);
digitalWrite(IN3, switching_sequence[i][2]);
digitalWrite(IN4, switching_sequence[i][3]);
delay(1000/motor_speed__);
}
}
void steps_8_backward(int motor_speed__) {
for (int i = 7; i >= 0; i--) {
digitalWrite(IN1, switching_sequence[i][0]);
digitalWrite(IN2, switching_sequence[i][1]);
digitalWrite(IN3, switching_sequence[i][2]);
digitalWrite(IN4, switching_sequence[i][3]);
delay(1000/motor_speed__);
}
}
void setup() {
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
}
void loop() {
for (int i = 0; i < 512; i++) { // 8 * 512 = 4096 steps per one revolution
steps_8_forward(1000);
}
delay(2000);
for (int i = 0; i < 512; i++) {
steps_8_backward(1000);
}
}
결과
https://youtube.com/shorts/kZ9Spf931aQ?si=33jL0Hs2B2z6V2LG