본 드라이버는 엔코더 피드백 내장형(클로즈드루프)입니다. 엔코더는 아두이노가 아니라
드라이버에 연결하며(위치 보정은 드라이버가 자동 수행), 아두이노는 펄스·방향을 보내고
EX(위치 도달)·ALM(알람) 출력을 읽어 실제 정착 여부를 확인합니다 —
일반 오픈루프 스텝과 달리 "보낸 만큼 실제로 갔는지"를 코드로 검증할 수 있는 것이 이 제품의 핵심 가치입니다.
사용하실 모터의 각 사이즈에 맞는 드라이버를 선택하세요:
업로드 전 확인 3가지: ①DIP SW6=OFF(펄스+방향 단일 펄스 모드 — 본 예제 기준)
②DIP SW1~SW4의 회전당 스텝 수(기본 4000)를 코드의 STEPS_PER_REV와 일치
③엔코더 선을 드라이버 단자에 색상대로 연결(EB+주황 / EB−주황흰 / EA+청 / EA−청흰 / VCC빨강 / GND흑).
아두이노 결선: D9→PUL+ / D6→DIR+ / D7→EX+ / D8→ALM+, 각 − 단자는 아두이노 GND(ENA는 기본 미연결).
제어 신호는 5V 보드(우노) 기준이며 3.3V 보드는 오작동 사례가 있어 레벨 변환(5V)을 권장합니다.
시리얼 모니터(9600bps, "새 줄")에서 m4000(CW 4000펄스 이동 후 도달 확인) /
M4000(CCW) / f2000·r500(연속 회전) / s(정지) /
a(알람·도달 상태)로 조작합니다.
회전속도(rpm) = 펄스 주파수 × 60 ÷ 회전당 스텝 수.
//==============================================================
// MotorBank MSD-ER2 시리즈(엔코더 클로즈드루프 스텝 드라이버) 아두이노 예제 V1.0
// 적용: MSD-22ER2 / MSD-34ER2 계열 (펄스+방향 제어, 엔코더 피드백 내장형)
// 기능: 위치 이동(펄스 카운트) + EX(위치 도달) 확인 / 연속 회전 / ALM(알람) 감시
// 보드: Arduino Uno (5V 보드 권장)
//
// [클로즈드루프 구조 이해]
// 엔코더는 아두이노가 아니라 "드라이버"에 연결합니다(위치 보정은 드라이버가 자동 수행).
// 아두이노는 ①펄스/방향을 보내고 ②EX(위치 도달)·ALM(알람) 출력을 읽어
// "실제로 지령 위치에 정착했는지"를 확인합니다 — 이것이 엔코더를 활용하는 방법입니다.
//
// [드라이버 결선]
// 아두이노 D9 -> PUL+ / D6 -> DIR+ / GND -> PUL-, DIR- (ENA는 기본 미연결)
// 드라이버 EX+ -> D7, EX- -> GND (위치 도달 신호, 포토커플러 출력)
// 드라이버 ALM+ -> D8, ALM- -> GND (알람 신호, 포토커플러 출력)
// 엔코더 -> 드라이버 단자에 색상대로: EB+주황 / EB-주황흰 / EA+청 / EA-청흰 / VCC빨강 / GND흑
//
// [DIP 스위치 필수 확인]
// SW6 = OFF (펄스+방향 단일 펄스 모드 - 본 예제 기준)
// SW1~SW4 = 회전당 스텝 수 (기본 4000). 아래 STEPS_PER_REV를 실제 설정값과 맞추세요.
// 모터 회전속도(rpm) = 펄스 주파수 x 60 / 회전당 스텝 수
//
// [시리얼 모니터 사용법] (9600bps, "새 줄" 설정)
// m4000 : CW로 4000펄스 이동 후 EX(위치 도달) 확인 M4000 : CCW로 이동
// f2000 : CW 연속 회전 2000Hz r500 : CCW 연속 500Hz s : 정지
// a : ALM·EX 현재 상태 표시
//==============================================================
const int PUL_PIN = 9, DIR_PIN = 6;
const int EX_PIN = 7, ALM_PIN = 8;
const long STEPS_PER_REV = 4000; // DIP SW1~SW4 설정값과 일치시킬 것
void setup() {
pinMode(DIR_PIN, OUTPUT);
pinMode(PUL_PIN, OUTPUT);
pinMode(EX_PIN, INPUT_PULLUP); // 포토커플러 도통 시 LOW
pinMode(ALM_PIN, INPUT_PULLUP);
Serial.begin(9600);
Serial.println(F("MSD-ER2 ready. m4000 M4000 f2000 r500 s a"));
}
bool alarmOn() { return digitalRead(ALM_PIN) == LOW; }
// 지정 펄스 수만큼 이동(주파수 고정 2kHz) 후 EX로 도달 확인
void moveSteps(bool cw, long steps) {
if (alarmOn()) { Serial.println(F("!! ALM 상태 - 이동 취소 (전원·결선 확인)")); return; }
digitalWrite(DIR_PIN, cw ? HIGH : LOW);
delayMicroseconds(10); // DIR 확정 후 최소 5us 대기(타이밍 규격)
for (long i = 0; i < steps; i++) {
digitalWrite(PUL_PIN, HIGH);
delayMicroseconds(240); // 펄스폭 >= 2.5us 충족, 약 2kHz
digitalWrite(PUL_PIN, LOW);
delayMicroseconds(240);
}
Serial.print(cw ? F("CW ") : F("CCW ")); Serial.print(steps); Serial.print(F("펄스 송신 완료. "));
// EX(위치 도달) 신호 대기 - 클로즈드루프이므로 "펄스 완료"와 "실제 정착"은 다를 수 있음
unsigned long t0 = millis();
while (millis() - t0 < 2000) {
if (digitalRead(EX_PIN) == LOW) { Serial.println(F("위치 도달 확인(EX)")); return; }
}
Serial.println(F("EX 신호 미확인 - EX 결선 또는 부하 상태 점검"));
}
void loop() {
if (alarmOn()) { /* 필요 시 알람 시 정지 로직 추가 위치 */ }
if (!Serial.available()) return;
String cmd = Serial.readStringUntil('\n');
cmd.trim();
if (cmd.length() == 0) return;
char c = cmd.charAt(0);
long v = cmd.substring(1).toInt();
switch (c) {
case 'm': moveSteps(true, constrain(v, 1, 1000000)); break;
case 'M': moveSteps(false, constrain(v, 1, 1000000)); break;
case 'f': digitalWrite(DIR_PIN, HIGH); delayMicroseconds(10);
tone(PUL_PIN, constrain(v, 1, 20000));
Serial.print(F("CW ")); Serial.print(v); Serial.println(F("Hz")); break;
case 'r': digitalWrite(DIR_PIN, LOW); delayMicroseconds(10);
tone(PUL_PIN, constrain(v, 1, 20000));
Serial.print(F("CCW ")); Serial.print(v); Serial.println(F("Hz")); break;
case 's': noTone(PUL_PIN); Serial.println(F("STOP")); break;
case 'a': Serial.print(F("ALM: ")); Serial.print(alarmOn() ? F("알람!") : F("정상"));
Serial.print(F(" / EX: ")); Serial.println(digitalRead(EX_PIN) == LOW ? F("도달") : F("-")); break;
default: Serial.println(F("? m4000 M4000 f2000 r500 s a"));
}
}
작성: MotorBank 기술팀 · 아두이노 우노 기준 · 최종 업데이트: 2026-08-14
구매 전 필독 — 호환·결선·신호 자주 묻는 질문
Q. 어떤 모터와 사용할 수 있나요? 타사 스텝모터도 되나요?
1000CPR 엔코더가 장착된 스텝모터 전용 클로즈드루프 드라이버입니다(엔코더 없는 일반 스텝모터 사용 불가).
구매 시 42각용(NEMA17) / 56각용(NEMA23)을 정확히 선택하세요 — 56각 타입을 42각 모터에 사용하면 발열이 심해질 수 있습니다.
당사 1000CPR 엔코더 스텝모터(NK 시리즈)와의 조합으로 테스트·검증되어 있으며,
타사 모터는 엔코더 사양(1000CPR)·결선이 맞아야 하고 당사에서 동작을 보증하기 어렵습니다 —
사용 예정 모터의 모델명·엔코더 사양을 상품문의에 남겨 주시면 확인을 도와드립니다.
Q. RS232 단자로 통신 제어나 엔코더 값 읽기가 되나요?
아니요. RS232 단자는 당사 제품 설계 시 스펙 설정에 쓰는 내부용이며,
통신 제어·엔코더 값 수신 용도로는 지원되지 않습니다(통신 프로토콜·PC 소프트웨어 미제공).
본 제품의 제어는 펄스(PLS) + 방향(DIR) 신호 방식입니다 — 위치 보정은 드라이버가
엔코더 피드백으로 내부에서 자동 수행하므로, 상위 장치는 일반 스텝 드라이버와 똑같이 펄스만 주면 됩니다.
Q. 제어 신호에 3.3V(라즈베리파이·ESP32)를 직접 연결해도 되나요?
안 됩니다. 제어 신호(PLS/DIR/ENA)는 5~24V를 준수해야 합니다.
3.3V를 직결하면 모터가 아주 미세한 스텝만 움직이는 등 오동작합니다.
아두이노(5V 출력)는 바로 연결 가능하고, 3.3V 계열 보드는 레벨 변환(5V) 회로를 거쳐 연결하세요.
Q. 신호 타이밍 기준을 알려주세요. (데이터시트 표기 정정 포함)
① ENA는 DIR보다 5ms 앞서 High가 되어야 합니다 — 단, 기본 사용 시 ENA는 연결하지 않아도 됩니다.
② DIR은 PLS 하강엣지보다 최소 5μs 전에 High/Low가 확정되어 있어야 합니다.
데이터시트의 t1 표기(5μs/5ms 혼재)는 위 기준이 맞습니다. 아울러 데이터시트에 있는
A/B 알고리즘 선택 기능은 현행 제품에서 제거되었으니 참고하세요.
Q. PEND(위치결정 완료) 출력은 언제 나오나요?
PEND는 입력된 펄스 지령만큼 모터가 실제로 도달했음을 엔코더로 확인했을 때 출력되는 위치결정 완료 신호입니다.
클로즈드루프 제품이므로 "펄스를 다 보낸 시점"과 "모터가 실제 정착한 시점"이 다를 수 있고,
상위 컨트롤러는 PEND를 보고 다음 동작의 시작 타이밍을 판단하는 용도로 사용합니다.
구체적인 판정 조건은 매뉴얼을 참고하시고,
적용 구성에서의 동작 확인이 필요하면 상품문의로 남겨 주세요.
Q. 드라이버가 타는(소손) 사고를 예방하려면?
소손의 대부분은 두 가지에서 나옵니다: ①전원 +/− 극성 반대 연결
②정격전류의 20% 이상 초과 설정·운전. 통전 전 극성을 재확인하고, 전류 설정은 모터 정격에 맞추세요.
(참고로 축을 손으로 돌릴 때 생기는 역기전력만으로 소손되는 경우는 드뭅니다.)
전원 인가 직후 타는 냄새·이상 점멸이 있으면 즉시 전원을 차단하고 재인가하지 마세요 — 증상과 결선 사진을 상품문의로 보내 주시면 확인해 드립니다.
Q. 기존 MSD-23ER2를 쓰다가 교체하려면? / 브레이크 단자는요?
기존 MSD-23ER2 사용자는 56각용을 선택하시면 대체 사용이 가능합니다.
또한 2025년 11월 출고분부터 브레이크 단자가 없는 버전으로 출고되고 있으니,
브레이크 단자를 사용하던 구성이라면 주문 전에 상품문의로 확인해 주세요.
작성: MotorBank 기술팀 · 실제 고객 문의와 기술 문서를 바탕으로 작성 · 최종 업데이트: 2026-08-14
25년 11월부터 브레이크 단자가 없는 버전으로 출고됩니다
구매 시 42각/56각 선택을 꼭 신중하게 부탁드립니다
56각타입을 42각모터에 사용하실 경우 발열이 심해질 수 있습니다
기존 MSD-23ER2사용하시던 분은 56각용으로 구매해주시면 됩니다
RS232단자는 당사에서 제품설계시 스펙설정용이며 실제로 RS232제어는 현재는 불가능한 단계입니다