//==============================================================
// 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"));
}
}
PG42-NK247E-01


상품이 장바구니에 담겼습니다.
바로 확인하시겠습니까?
상품이 찜 리스트에 담겼습니다.
바로 확인하시겠습니까?