이 아두이노 튜토리얼에서는 A4988 스테퍼 드라이버를 사용하여 스테퍼 모터를 제어하는 방법을 배웁니다.
A4988은 양극성 스테퍼 모터 제어용 마이크로스테핑 드라이버로, 내장된 트랜슬레이터로 쉽게 조작할 수 있습니다. 즉, 컨트롤러의 단 2개 핀(회전 방향 제어용 1개, 스텝 제어용 1개)으로 스테퍼 모터를 제어할 수 있습니다.
드라이버는 5가지 스텝 해상도를 제공합니다: 풀스텝, 하프스텝, 쿼터스텝, 8분스텝, 16분스텝. 또한 전류 출력을 조절하는 포텐셔미터, 과열 방지 열적 셧다운, 교차 전류 보호 기능이 있습니다.
로직 전압은 3~5.5V이며, 최대 상전류는 양호한 추가 냉각 시 2A, 방열판이나 냉각 없이 연속 사용 시 상당 1A입니다.
A4988 스테퍼 드라이버 핀아웃
드라이버 핀아웃을 자세히 살펴보고 스테퍼 모터와 컨트롤러에 연결해 보겠습니다. 오른쪽 아래 2핀은 드라이버 전원용 VDD와 GND로, 3~5.5V 전원 공급 장치에 연결하며 여기서는 아두이노 보드(5V)를 사용합니다. 다음 4핀은 모터 연결용: 1A, 1B는 모터의 한 코일, 2A, 2B는 다른 코일에 연결. 모터 전원용 다음 2핀은 GND와 VMOT로, 8~35V 전원 공급 장치에 연결하며 드라이버 보드를 전압 스파이크로부터 보호하기 위해 최소 47µF 디커플링 커패시터가 필요합니다.
다음 2핀인 Step과 Direction이 모터 움직임을 제어하는 실제 핀입니다. Direction 핀은 모터 회전 방향을 제어하며 마이크로컨트롤러의 디지털 핀(여기서는 아두이노 4번 핀)에 연결합니다. Step 핀으로 마이크로스텝을 제어하며, 이 핀에 펄스가 하나 전송될 때마다 모터가 한 스텝 움직입니다. 즉, A4988 드라이버의 내장 트랜슬레이터가 모든 것을 처리하므로 복잡한 프로그래밍, 위상 시퀀스 테이블, 주파수 제어 라인 등이 필요 없습니다. 이 2핀은 내부적으로 어떤 전압에도 풀업되지 않으므로 프로그램에서 플로팅 상태로 두지 않아야 합니다.
다음은 SLEEP 핀으로, 로우 로직 시 보드를 슬립 모드로 전환하여 모터 미사용 시 전력 소비를 최소화합니다.
RESET 핀은 트랜슬레이터를 미리 정의된 홈 상태(Home state)로 설정합니다. 이 홈 상태 또는 홈 마이크로스텝 위치는 A4988 데이터시트의 그림에서 확인할 수 있습니다. 이는 모터가 시작하는 초기 위치이며 마이크로스텝 해상도에 따라 다릅니다. 이 핀 입력이 로우 로직이면 모든 STEP 입력이 무시됩니다. RESET 핀은 플로팅 핀이므로 프로그램에서 제어할 의도가 없다면 SLEEP 핀에 연결하여 높게 유지하고 보드를 활성화해야 합니다.
다음 3핀(MS1, MS2, MS3)은 위 진리표에 따라 5가지 스텝 해상도 중 하나를 선택합니다. 이 핀들은 내부 풀다운 저항이 있어 연결하지 않으면 풀스텝 모드로 동작합니다.
마지막 ENABLE 핀은 FET 출력을 켜거나 끄는 데 사용됩니다. 하이 로직이면 출력이 비활성화된 상태로 유지됩니다.
이 아두이노 튜토리얼에 필요한 부품
스테퍼 모터 (NEMA17)
A4988 스테퍼 드라이버
12V 2A 어댑터
파워 잭
아두이노 보드
브레드보드와 점퍼 와이어
회로도
완전한 회로도입니다. 풀스텝 모드로 사용하므로 3개 MS 핀은 연결하지 않고, 드라이버의 Direction과 Step 핀을 아두이노 3, 4번 핀에, GND와 5V로 드라이버에 전원 공급. 100µF 커패시터로 디커플링, 12V 1.5A 어댑터로 모터 전원 공급. NEMA 17 양극성 스테퍼 모터 사용: A, C 와이어를 1A, 1B 핀에, B, D 와이어를 2A, 2B 핀에 연결.
A4988 전류 제한
모터 연결 전 드라이버의 전류 제한을 조정하여 모터의 전류 제한 내에 있는지 확인해야 합니다. 보드의 포텐셔미터로 기준 전압을 조정하고 다음 공식을 고려합니다:
하지만 이 공식은 A4988 드라이버 보드 제조사마다 다를 수 있어 항상 정확하지는 않습니다. 제 경우를 시연해 보겠습니다: 포텐셔미터를 조정하여 0.6V 기준 전압을 측정했습니다. 전류 제한은 0.6×2 = 1.2A가 되어야 합니다.
풀스텝 모드 사용 시 데이터시트에 따르면 코일 전류가 전류 제한의 70%만 도달할 수 있으므로 1.2A × 0.7 = 0.84A입니다. 이를 확인하기 위해 Step 핀에 지속적인 하이 로직을 보내는 간단한 코드를 업로드하고(전류를 더 잘 관찰하기 위해), 미터를 모터 한 코일과 직렬로 연결하여 전원을 켰습니다. 측정된 값은 0.5A로, 제 경우 공식이 정확하지 않았습니다.
아두이노와 A4988 코드
예제 코드입니다. 먼저 Step과 Direction 핀을 정의합니다. 아두이노 3, 4번 핀으로 stepPin, dirPin으로 명명하고 설정 섹션에서 출력으로 정의합니다.
/* 간단한 스테퍼 모터 제어 예제 코드
* by Dejan Nedelkovski, www.HowToMechatronics.com
*/
// 핀 번호 정의
const int stepPin = 3;
const int dirPin = 4;
void setup() {
// 두 핀을 출력으로 설정
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
}
void loop() {
digitalWrite(dirPin, HIGH); // 특정 방향으로 모터 회전 활성화
// 한 바퀴 회전을 위한 200 펄스 생성
for (int x = 0; x < 200; x++) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin, LOW);
delayMicroseconds(500);
}
delay(1000); // 1초 대기
digitalWrite(dirPin, LOW); // 회전 방향 변경
// 두 바퀴 회전을 위한 400 펄스 생성
for (int x = 0; x < 400; x++) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin, LOW);
delayMicroseconds(500);
}
delay(1000);
}
루프 섹션에서 먼저 Direction 핀을 하이 상태로 설정하여 모터가 특정 방향으로 움직이게 합니다. for 루프로 모터가 한 바퀴 회전하게 합니다. 드라이버가 풀스텝 모드이고 스테퍼 모터의 스텝 각도가 1.8도(200 스텝)이므로, Step 핀에 200 펄스를 보내야 한 바퀴 회전합니다. for 루프는 200회 반복되며 각 반복마다 Step 핀을 하이/로우로 설정하여 펄스를 만듭니다. 각 digitalWrite 사이의 지연에서 모터 속도가 결정됩니다.
한 바퀴 회전 후 1초 대기, dirPin을 로우로 설정하여 방향 변경, 400회 반복 루프로 두 바퀴 회전. 마지막에 1초 더 대기. 코드를 업로드하여 작동 확인해 보세요.
이 튜토리얼을 위해 포텐셔미터로 모터 속도를 제어하는 예제도 만들었습니다:
/* 간단한 스테퍼 모터 제어 예제 코드
* by Dejan Nedelkovski, www.HowToMechatronics.com
*/
const int stepPin = 3;
const int dirPin = 4;
int customDelay, customDelayMapped;
void setup() {
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
digitalWrite(dirPin, HIGH); // 특정 방향으로 모터 회전 활성화
}
void loop() {
customDelayMapped = speedUp(); // 커스텀 speedUp 함수에서 지연 값 가져오기
// 포텐셔미터에 따른 커스텀 지연으로 펄스 생성, 모터 속도 결정
digitalWrite(stepPin, HIGH);
delayMicroseconds(customDelayMapped);
digitalWrite(stepPin, LOW);
delayMicroseconds(customDelayMapped);
}
// 포텐셔미터 읽기 함수
int speedUp() {
int customDelay = analogRead(A0); // 포텐셔미터 읽기
int newCustom = map(customDelay, 0, 1023, 300, 4000); // 0~1023을 원하는 지연 값(300~4000)으로 변환
return newCustom;
}