//==============================================================
// MotorBank BLC-20 / BLC-30 아두이노 예제 V3.2
// 기능: PWM 20kHz 속도제어 + 방향 + 브레이크 + 가감속(Slope)
// + 시리얼 모니터 명령 제어 (V3.1 대비 추가)
// 보드: Arduino Uno (검증 기준)
//
// [사전 준비] 라이브러리 매니저에서 설치:
// 1) TimerOne 2) MsTimer2
//
// [결선]
// D9 -> PWM(속도) 입력
// D4 -> Direction(방향) 입력
// D2 -> Brake(브레이크) 입력
// GND -> 드라이버 GND (반드시 공통)
//
// [시리얼 모니터 사용법] (9600bps, "새 줄" 설정)
// f80 : 정방향 80% 속도 r50 : 역방향 50% 속도
// s : 감속 정지(속도 0) b1 : 브레이크 ON b0 : 브레이크 OFF
// p3 : 가감속 기울기 1~10 (숫자 클수록 빠르게 가감속)
//==============================================================
#include <TimerOne.h>
#include <MsTimer2.h>
const int PWM_PIN = 9;
const int DIR_PIN = 4;
const int BRAKE_PIN = 2;
volatile int DutyRef = 0; // 목표 듀티 -1024~1024 (-100%~100%)
volatile int Duty = 0; // 현재 듀티(가감속 반영)
int Slope = 5; // 가감속 단계 1~10
void flash() { // 가감속: 목표까지 1스텝씩 접근
if (Duty < DutyRef) Duty++;
else if (Duty > DutyRef) Duty--;
if (Duty > 0) {
Timer1.setPwmDuty(PWM_PIN, 1024 - Duty);
digitalWrite(DIR_PIN, LOW);
} else if (Duty < 0) {
Timer1.setPwmDuty(PWM_PIN, 1024 + Duty);
digitalWrite(DIR_PIN, HIGH);
} else {
Timer1.setPwmDuty(PWM_PIN, 1024); // 속도 0
}
}
void applySlope() {
MsTimer2::stop();
MsTimer2::set(10 / constrain(Slope, 1, 10), flash);
MsTimer2::start();
}
void setup() {
Serial.begin(9600);
Timer1.initialize();
Timer1.pwm(PWM_PIN, 0);
Timer1.setPeriod(50); // 50us -> PWM 20kHz
Timer1.setPwmDuty(PWM_PIN, 1024); // 정지 상태로 시작
pinMode(DIR_PIN, OUTPUT); digitalWrite(DIR_PIN, LOW);
pinMode(BRAKE_PIN, OUTPUT); digitalWrite(BRAKE_PIN, HIGH); // 브레이크 해제 상태
applySlope();
Serial.println(F("BLC-20/30 ready. f80 r50 s b1 b0 p5"));
}
void loop() {
if (!Serial.available()) return;
String cmd = Serial.readStringUntil('\n');
cmd.trim();
if (cmd.length() == 0) return;
char c = cmd.charAt(0);
int v = cmd.substring(1).toInt();
switch (c) {
case 'f': DutyRef = constrain(v, 0, 100) * 1024L / 100; Serial.print(F("FWD ")); Serial.println(v); break;
case 'r': DutyRef = -constrain(v, 0, 100) * 1024L / 100; Serial.print(F("REV ")); Serial.println(v); break;
case 's': DutyRef = 0; Serial.println(F("STOP(slope)")); break;
case 'b': digitalWrite(BRAKE_PIN, v ? LOW : HIGH); Serial.println(v ? F("BRAKE ON") : F("BRAKE OFF")); break;
case 'p': Slope = constrain(v, 1, 10); applySlope(); Serial.print(F("Slope ")); Serial.println(Slope); break;
default: Serial.println(F("? f80 r50 s b1 b0 p5"));
}
}
//==============================================================
// MotorBank BLC-20R4 아두이노 RS485(Modbus RTU) 예제 V1.0
// 기능: RS485 통신으로 기동/속도/방향/브레이크 제어
// 보드: Arduino Uno + RS485 컨버터 모듈(MAX485 등)
// 근거: BLC-20R4 사용설명서 & RS485 Modbus 프로토콜 (CRC 예제 6건 검증 일치)
//
// [드라이버 설정] 제어 스위치를 Int로 설정 (RS485 제어 조건)
// [통신 설정] 9600bps, No Parity, 8 Data, 1 Stop (제품 기본값)
//
// [결선 - MAX485 모듈 기준]
// 모듈 RO -> D10 (아두이노 수신)
// 모듈 DI -> D11 (아두이노 송신)
// 모듈 DE+RE(묶어서) -> D3 (송신 시 HIGH)
// 모듈 A/B -> 드라이버 485 A/B (통신 안 되면 A/B 교차 시도)
// 모듈 VCC -> 5V, GND -> 공통 GND
//
// [시리얼 모니터 사용법] (9600bps, "새 줄" 설정)
// i : RS485 통신모드 기동(0x0023) - 전원 인가 후 최초 1회 필수!
// f80 : CW 방향 + 속도 80% r50 : CCW 방향 + 속도 50%
// s : 속도 0 b1/b0 : 브레이크 High/Low
//
// [주의]
// - 방향값: 상세 예시 기준 0x0000=CCW, 0x0001=CW 적용
// (설명서 요약표의 "1CW/2CCW" 표기와 상이 - 예시 프레임(CRC 검증됨) 기준 채택)
// - RS485 반이중 특성상 자기 송신 에코가 수신될 수 있어 코드에서 버림 처리함
//==============================================================
#include <SoftwareSerial.h>
const int RS485_RX = 10; // <- 모듈 RO
const int RS485_TX = 11; // -> 모듈 DI
const int RS485_EN = 3; // DE+RE
const byte DEV_ADDR = 0x01; // 제어기 주소(출고 기본 0x01)
SoftwareSerial rs485(RS485_RX, RS485_TX);
uint16_t crc16(const byte *data, byte len) { // Modbus CRC16
uint16_t crc = 0xFFFF;
for (byte j = 0; j < len; j++) {
crc ^= data[j];
for (byte i = 8; i != 0; i--) {
if (crc & 0x0001) { crc >>= 1; crc ^= 0xA001; }
else crc >>= 1;
}
}
return crc;
}
// Function 0x06: 레지스터 1개 쓰기 (기동/속도/방향/브레이크 공용)
void write06(uint16_t reg, uint16_t val) {
byte f[8];
f[0] = DEV_ADDR; f[1] = 0x06;
f[2] = reg >> 8; f[3] = reg & 0xFF;
f[4] = val >> 8; f[5] = val & 0xFF;
uint16_t c = crc16(f, 6);
f[6] = c & 0xFF; // CRC Low 먼저 (문서 예제 검증 순서)
f[7] = c >> 8; // CRC High
while (rs485.available()) rs485.read(); // 수신버퍼 비우기
digitalWrite(RS485_EN, HIGH); // 송신 모드
rs485.write(f, 8);
rs485.flush();
digitalWrite(RS485_EN, LOW); // 수신 모드
// 응답 수신(에코가 먼저 들어오면 8바이트 버리고 다음 8바이트가 실제 응답)
byte buf[16]; byte n = 0;
unsigned long t0 = millis();
while (millis() - t0 < 300 && n < 16) {
if (rs485.available()) buf[n++] = rs485.read();
}
Serial.print(F("TX:"));
for (byte i = 0; i < 8; i++) { Serial.print(' '); if (f[i] < 16) Serial.print('0'); Serial.print(f[i], HEX); }
Serial.print(F(" | RX(")); Serial.print(n); Serial.print(F("B):"));
for (byte i = 0; i < n; i++) { Serial.print(' '); if (buf[i] < 16) Serial.print('0'); Serial.print(buf[i], HEX); }
Serial.println();
}
void setup() {
Serial.begin(9600);
rs485.begin(9600); // 9600 N81 (제품 기본)
pinMode(RS485_EN, OUTPUT);
digitalWrite(RS485_EN, LOW);
Serial.println(F("BLC-20R4 RS485 ready."));
Serial.println(F("i(기동,최초1회) f80 r50 s b1 b0"));
}
void loop() {
if (!Serial.available()) return;
String cmd = Serial.readStringUntil('\n');
cmd.trim();
if (cmd.length() == 0) return;
char c = cmd.charAt(0);
int v = constrain(cmd.substring(1).toInt(), 0, 100);
switch (c) {
case 'i': write06(0x0023, 0x0000); Serial.println(F("RS485 mode start")); break; // 기동(필수)
case 'f': write06(0x0025, 0x0001); write06(0x0024, v); break; // CW + 속도
case 'r': write06(0x0025, 0x0000); write06(0x0024, v); break; // CCW + 속도
case 's': write06(0x0024, 0); break; // 속도 0
case 'b': write06(0x0026, v ? 1 : 0); break; // 브레이크
default: Serial.println(F("? i f80 r50 s b1 b0"));
}
}
<485통신 제어>
<아두이노 제어>
<아날로그 제어>




예제코드
*****************************************************************************************************************
구동드라이버 내장형의 경우 내장된 드라이버의 설계에 따라 HIGH LOW부분이 다릅니다.
따라서 일부 모터는 브레이크 LOW에서만 구동이 되고 일부 모터는 HIGH에서만 구동이 됩니다.
듀티비 또한 설계의 영향에 따라 다를수 있습니다.
일부 내장형 모터일 겨웅 브레이크 케이블이 없을 경우 또 다르게 표현됩니다.
결론적으로 모터에 내장된 설계에 따라 코드가 다르게 사용되는 부분 꼭 참고바라며
테스트를 통해 제어기와 친해지기 바랍니다.
영상참고
https://www.youtube.com/watch?v=8jv-MR4ktTI
https://www.youtube.com/shorts/o6YA6spkBow?feature=share
*****************************************************************************************************************
주소수정 02 06 0020 0001
주소읽기 01 03 0020 0001
통신속도 수정 01 10 0021 0002 04 00002580
통신속도 읽기 01 03 0021 0002
485통신 기동 브레이크 LOW 속도 0%
01 06 0023 0000
485통신 기동 브레이크 LOW 속도 100%
01 06 0023 0001
485통신 기동 브레이크 HIGH 속도 0%
01 06 0023 0002
485통신 기동 브레이크 HIGH 속도 100%
01 06 0023 0003
듀티비설정 100%
01 06 0024 0064
듀티비설정
01 06 0024 0050
듀티비설정
01 06 0024 0040
듀티비설정 0%
01 06 0024 0000
정회전 01 06 0025 0001
역회전 01 06 0025 0002
ACC-10(가변저항기+스위치*2) 별도구매
상품이 장바구니에 담겼습니다.
바로 확인하시겠습니까?
상품이 찜 리스트에 담겼습니다.
바로 확인하시겠습니까?