| 드라이버 신호 | 연결 (공통 캐소드/직결 기준) |
|---|---|
| PUL (STEP) | 아두이노 D9 |
| DIR | 아두이노 D6 |
| EN | 아두이노 D5 (극성은 드라이버 설명 확인) |
| 신호 GND / 모터 전원 | 아두이노 GND 공통 / 드라이버 전원 단자에 별도 공급 |
//==============================================================
// RMRT 중공 로터리 액추에이터 + 2상 스텝모터 아두이노 펄스 제어 예제 V1.0
// 적용: RMRT60(42각) / RMRT85·RMRT130(56각) / RMRT200(86각) + 결합 스텝모터
// 드라이버: MSD-224 등 펄스·방향(PUL/DIR/EN) 방식 2상 스텝 드라이버
// 보드: Arduino Uno
//
// [결선 - 공통 캐소드(직결) 기준] ※ 드라이버 상세페이지 결선도 우선
// 드라이버 PUL(STEP) -> D9 / DIR -> D6 / EN -> D5 / 신호 GND -> 아두이노 GND
// 모터 전원(DC24V 등)은 드라이버 전원 단자로 별도 공급, GND 공통
//
// [★반드시 맞춰야 하는 3가지 상수 - 각도 정확도를 결정합니다]
// MICROSTEP : 드라이버 DIP 스위치의 분주 설정과 반드시 동일하게 (권장 8~16)
// MSD-224는 1~32분주, MSD-228N 등 상위 드라이버는 고분주 지원.
// ※고분주일수록 같은 RPM에 필요한 펄스 주파수가 비례 상승 -
// 이 예제(소프트 펄스)는 약 16kHz가 상한이므로 고분주에서는 속도 제한
// GEAR : 구매하신 감속비 (1/5 -> 5, 1/10 -> 10)
// STEPS_REV : 모터 기본 스텝수 (1.8도 2상 = 200. 0.9도 모터면 400)
// -> 이 값이 하나라도 실물과 다르면 지령 각도와 실제 각도가 어긋납니다
//
// [시리얼 모니터 사용법] (9600bps, "새 줄" 설정)
// e / E : 드라이버 Enable / Disable (Disable 시 축이 자유 회전)
// f300 : CW 연속 회전, 출력축 30.0RPM (0.1RPM 단위)
// r150 : CCW 연속 회전, 출력축 15.0RPM
// s : 정지
// g9000 : CW 90.00도 회전 (0.01도 단위, 출력축 기준)
// G9000 : CCW 90.00도 회전
// i6 : 인덱싱 - 출력축 360/6 = 60.00도씩 CW 분할 이동
//
// [중공축 주의] 축 내부로 통과시키는 케이블은 모터 결선과 별개입니다 - 회전부와
// 간섭 없는지, 케이블 직경이 중공 구경에 맞는지 조립 전에 확인하세요.
// [오픈루프 주의] 스텝모터는 부하가 토크를 넘으면 탈조(위치 이탈)합니다.
// 부하가 크면 속도를 낮추고, 아래 RAMP 구간을 늘려 가감속을 완만하게 하세요.
//==============================================================
const int PIN_PUL = 9, PIN_DIR = 6, PIN_EN = 5;
#define EN_ACTIVE LOW // Enable 극성 - 드라이버별 상이 (동작 반대면 HIGH로)
#define EN_IDLE HIGH
const unsigned int STEPS_REV = 200; // 모터 기본 스텝수 (1.8도 = 200)
const unsigned int MICROSTEP = 8; // ★드라이버 DIP 분주와 동일하게
const unsigned int GEAR = 5; // ★구매 감속비: 1/5 -> 5, 1/10 -> 10
const unsigned long STEPS_OUT_REV = (unsigned long)STEPS_REV * MICROSTEP * GEAR; // 출력축 1회전 스텝
const unsigned int RAMP_STEPS = 400; // 가감속 구간(스텝) - 탈조 시 늘리세요
const unsigned int US_START = 1200; // 기동 스텝 간격(us) - 느리게 시작
unsigned int usRun = 500; // 연속 회전 목표 스텝 간격(us)
bool running = false; bool enabled = false;
unsigned long lastStepUs = 0;
void stepOnce(unsigned int us) {
digitalWrite(PIN_PUL, HIGH); delayMicroseconds(4);
digitalWrite(PIN_PUL, LOW); delayMicroseconds(us - 4);
}
// 사다리꼴 가감속으로 지정 스텝 수 이동
void moveSteps(unsigned long steps, bool cw) {
digitalWrite(PIN_DIR, cw ? HIGH : LOW);
delayMicroseconds(20);
unsigned long ramp = min((unsigned long)RAMP_STEPS, steps / 2);
for (unsigned long i = 0; i < steps; i++) {
unsigned int us = usRun;
if (i < ramp) us = US_START - (unsigned long)(US_START - usRun) * i / ramp;
else if (i >= steps - ramp) us = US_START - (unsigned long)(US_START - usRun) * (steps - 1 - i) / ramp;
stepOnce(us);
}
}
// 출력축 RPM(0.1 단위) -> 스텝 간격(us)
unsigned int rpmToUs(long rpm01) {
// us = 60e6 / (rpm * STEPS_OUT_REV), rpm = rpm01/10
unsigned long us = 600000000UL / ((unsigned long)rpm01 * STEPS_OUT_REV);
return (unsigned int)constrain(us, 60UL, 60000UL); // 과속·과저속 보호
}
void setup() {
Serial.begin(9600);
pinMode(PIN_PUL, OUTPUT); pinMode(PIN_DIR, OUTPUT); pinMode(PIN_EN, OUTPUT);
digitalWrite(PIN_EN, EN_IDLE); // 시작은 Disable (안전)
Serial.println(F("RMRT + step driver ready. (V1.0)"));
Serial.print(F("출력축 1회전 = ")); Serial.print(STEPS_OUT_REV); Serial.println(F(" 스텝"));
Serial.println(F("명령: e/E f300 r150 s g9000 G9000 i6"));
}
void loop() {
// 연속 회전 처리 (non-blocking)
if (running && micros() - lastStepUs >= usRun) {
lastStepUs = micros();
digitalWrite(PIN_PUL, HIGH); delayMicroseconds(4); digitalWrite(PIN_PUL, LOW);
}
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 'e': digitalWrite(PIN_EN, EN_ACTIVE); enabled = true; Serial.println(F("Enable")); break;
case 'E': running = false; digitalWrite(PIN_EN, EN_IDLE); enabled = false; Serial.println(F("Disable")); break;
case 'f': case 'r':
if (!enabled) { Serial.println(F("먼저 e로 Enable 하세요")); return; }
if (v < 1) { Serial.println(F("속도를 입력하세요 (예 f300 = 30.0RPM)")); return; }
digitalWrite(PIN_DIR, c == 'f' ? HIGH : LOW);
usRun = rpmToUs(v); running = true;
Serial.print(F("연속 회전 ")); Serial.print(v / 10.0); Serial.println(F(" RPM (출력축)"));
break;
case 's': running = false; Serial.println(F("정지")); break;
case 'g': case 'G': {
if (!enabled) { Serial.println(F("먼저 e로 Enable 하세요")); return; }
running = false;
unsigned long steps = (unsigned long)((unsigned long long)v * STEPS_OUT_REV / 36000ULL);
moveSteps(steps, c == 'g');
Serial.print(F("이동 완료: ")); Serial.print(v / 100.0); Serial.println(F(" 도"));
break;
}
case 'i': {
if (!enabled) { Serial.println(F("먼저 e로 Enable 하세요")); return; }
if (v < 2 || v > 360) { Serial.println(F("분할 수 2~360 (예 i6)")); return; }
running = false;
moveSteps(STEPS_OUT_REV / v, true);
Serial.print(F("인덱스 이동: ")); Serial.print(360.0 / v); Serial.println(F(" 도"));
break;
}
default: Serial.println(F("? e/E f300 r150 s g9000 G9000 i6")); return;
}
}



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