Files
fori_zltech_motor_test/doc/02-communication-protocol.md
Dongubak 2f21d86193 Add ZLAC8015D driver docs, IMU integration plan, and reference resources
Documents the ZLAC8015D V4 dual-channel driver (hardware spec, RS485
Modbus register map, 4WD skid-steer system architecture, the
xbox_motor_control.cpp control loop, and error/troubleshooting) under
doc/, plus a phased plan for adding IMU-based heading/slip feedback
(doc/06) informed by Clearpath Husky's sensor fusion stack and
skid-steer ICR literature. QnA/ records the Q&A that refined that plan.
Also adds the underlying manual PDFs and reference links under
resource/ that the docs cite.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-16 00:17:24 +09:00

17 KiB
Raw Permalink Blame History

02. RS485 통신 프로토콜 & 레지스터 맵

출처: resource/ZLAC8015D V4 Series RS485 Communication Version 1.06-20251111.pdf, xbox_motor_control.cpp

2.1 시리얼 포트 설정

항목
프로토콜 Modbus RTU
보드레이트 115200 bps (기본값, 코드에서 사용) — 9600/19200/38400/57600/128000 선택 가능
데이터 비트 8
패리티 None
스톱 비트 1
드라이버 주소 범위 1 ~ 127 (본 프로젝트: 드라이버#1=1, 드라이버#2=2)

xbox_motor_control.cppSerialPort::openPort()가 termios로 위 설정(8N1, RAW 모드, VTIME=1 → 0.1s read timeout)을 그대로 구성한다.

2.2 Modbus 프레임 포맷

[슬레이브 주소 1B][기능코드 1B][데이터 N B][CRC16 2B (Low,High 순)]

CRC는 표준 Modbus CRC16(다항식 0xA001, 초기값 0xFFFF) — calcCRC16()이 이를 그대로 구현.

지원 기능 코드

기능 코드 에러 응답 코드
다중 레지스터 읽기 0x03 0x83
단일 레지스터 쓰기 0x06 0x86
다중 레지스터 쓰기 0x10 0x90
에러 코드 이름 의미
0x01 Illegal function code 지원하지 않는 기능 코드
0x02 Illegal data address 잘못된 레지스터 주소
0x03 Illegal data value 잘못된 데이터 값

코드 구현 매핑

클래스 함수 기능 코드 용도
SerialPort::readRegs() 0x03 피드백/상태/전류한계 조회
SerialPort::writeReg() 0x06 제어워드/모드/브레이크 등 단일 레지스터 쓰기
SerialPort::writeRegs() 0x10 가감속시간, 목표속도(L/R 동시) 쓰기

응답 검증은 CRC16 재계산 + 슬레이브 주소 일치 여부로 이루어지며(writeReg/writeRegs/readRegs 모두 동일), 브로드캐스트(slave==0)일 때는 응답을 기다리지 않는다(--bcast 옵션).

읽기 타임아웃은 25ms(100Hz=10ms 주기 루프 안에서 여유를 둔 값), 쓰기 응답 타임아웃은 50ms로 설정되어 있다.

2.3 코드가 실제로 사용하는 레지스터 (초기화/제어/피드백 경로)

주소 이름 방향 코드 사용처
0x200D Control mode W initDriver(): 3 = 속도 제어 모드 고정
0x200E Control word W initDriver(): 0x0006 알람 클리어 → 0x0007 Disable → (가감속 설정 후) 0x0008 Enable
0x2080 / 0x2081 가속시간 좌/우 W initDriver(acl_ms)writeRegs(0x2080,{acl,acl})로 2레지스터 동시 기록 (기본 150ms)
0x2082 / 0x2083 감속시간 좌/우 W initDriver(dcl_ms)writeRegs(0x2082,{dcl,dcl})로 동시 기록 (기본 150ms)
0x2088 / 0x2089 목표속도 좌/우 (RPM, I16, ±3000) W setRPMs(): 매 틱 writeRegs(0x2088,{l,r})로 좌/우 동시 지령
0x201A 출력단자 B0 (좌 브레이크) W setBrakes(): 0=해제, 1=잠금
0x201B 출력단자 B1 (우 브레이크) W setBrakes(): 좌와 동일 값 동시 기록
0x2033 / 0x2034 좌 정격전류 / 좌 최대전류 (0.1A) R/W readCurrentLimits()로 조회, setMaxCurrent()0x2034만 기록
0x2063 / 0x2064 우 정격전류 / 우 최대전류 (0.1A) R/W 좌와 동일 패턴 (우 채널)
0x20A5 ~ 0x20AE 에러코드~토크 (아래 표 참고) R readFeedback()10레지스터 연속 읽기(0x03, count=10)로 한 번에 확보

readFeedback()의 10레지스터 연속 읽기 상세 (0x20A5 시작, count=10)

offset 주소 이름 코드 내 변수 스케일
0 0x20A5 에러코드(좌) err_l 비트마스크 (그대로)
1 0x20A6 에러코드(우) err_r 비트마스크 (그대로)
2 0x20A7 실제위치 상위16비트(좌) val_l 상위 int32_t 합성 → l_tick
3 0x20A8 실제위치 하위16비트(좌) val_l 하위
4 0x20A9 실제위치 상위16비트(우) val_r 상위 int32_t 합성 → r_tick
5 0x20AA 실제위치 하위16비트(우) val_r 하위
6 0x20AB 실제속도(좌), 단위 0.1r/min vl × 0.1fl_fb (RPM)
7 0x20AC 실제속도(우), 단위 0.1r/min vr × 0.1fr_fb (RPM)
8 0x20AD 실제토크/전류(좌), 단위 0.1A tl × 0.1fl_torque_a (A)
9 0x20AE 실제토크/전류(우), 단위 0.1A tr × 0.1fr_torque_a (A)

이 한 번의 통신으로 에러코드·엔코더 위치(주행거리 계산용)·속도 피드백·전류(부하 진단용)를 모두 얻기 때문에, 100Hz 루프에서 드라이버 1대당 통신 1회(읽기)+1회(쓰기)만 필요하다. 2대 드라이버 × 2회 = 틱당 최대 4회 왕복, comm_ms로 HUD에 실측 소요시간을 표시한다.

위치(0x20A7~0x20AA)는 엔코더 라인수 1024 기준 4체배(quadrature)로 회전당 1024 × 4 = 4096이 아니라, README 기준 실측 16,384 ticks/rev를 사용한다 (ZLLG80ASM250-4096-B 모터명의 4096은 엔코더 라인수이며, 4체배 카운팅 시 4096 × 4 = 16384가 된다. 0x2030/0x2060 "Encoder line" 파라미터 공장 기본값 1024와는 별개로, 실제 장착된 ZLLG80ASM250-4096-B 모터는 라인수 4096 사양이므로 드라이버의 Encoder line 파라미터가 모터 사양(4096)에 맞춰 설정되어 있어야 meters_per_tick 계산이 정확하다. 드라이버 실측정격전류가 15A인 것도 이 모터의 정격과 일치.)

2.4 에러코드 (0x20A5 / 0x20A6)

의미 코드 내 한글 표기
0x0000 정상 (No error) (없음)
0x0001 과전압 (Over voltage) 과전압
0x0002 저전압 (Under voltage) 저전압
0x0004 과전류 (Over current) 과전류
0x0008 과부하 (Over load) 과부하
0x0010 전류 이상 (예약) 전류이상(예약)
0x0020 엔코더 오차 (Encoder out of tolerance) 엔코더오차
0x0040 속도 이상 (예약) 속도이상(예약)
0x0080 기준전압 오류 (Reference voltage error) 기준전압오류
0x0100 EEPROM 오류 EEPROM오류
0x0200 홀센서 오류 홀센서오류
0x0400 모터 과열 모터과열
0x0800 엔코더 오류 엔코더오류
0x2000 속도설정 오류 (지령속도가 정격속도 초과) 속도설정오류

여러 비트가 동시에 서면 코드가 "+"로 이어붙여 표시한다 (decodeDriverError()). 드라이버 알람 상세 진단과 대응은 05-error-troubleshooting.md 참고.

2.5 제어워드(0x200E)와 초기화 시퀀스

의미
0x05 비상 정지 (Emergency stop)
0x06 알람 클리어 (Clear fault)
0x07 정지 (Stop / Disable)
0x08 활성화 (Enable)
0x10 동기 시작 (Start Synchronous, 포지션 모드 전용)
0x11 좌측 단독 시작 (Start Left, 포지션 모드)
0x12 우측 단독 시작 (Start Right, 포지션 모드)

MotorDriver::initDriver()의 실제 시퀀스 (각 단계 사이 30ms 대기):

  1. 0x200E0x0006 (알람 클리어)
  2. 0x200E0x0007 (Disable)
  3. 0x200D3 (속도 제어 모드)
  4. 0x2080/0x2081 ← 가속시간 (좌우 동시, 기본 150ms)
  5. 0x2082/0x2083 ← 감속시간 (좌우 동시, 기본 150ms)
  6. 0x200E0x0008 (Enable)
  7. setBrakes(true) — 초기 상태는 브레이크 잠금

이 프로젝트는 속도 제어 모드(Profile Velocity Mode)만 사용하며, 포지션/토크 모드 관련 레지스터 (0x208A~0x208F, 0x2090/0x2091 등)는 사용하지 않는다. 참고용으로 §2.7에 전체 표를 남긴다.

2.6 전류 한계 레지스터

주소 이름 단위 기본값 범위
0x2033 좌 정격전류 0.1A 150 (15.0A) 0-150
0x2034 좌 최대전류 0.1A 300 (30.0A) 0-300
0x2063 우 정격전류 0.1A 150 (15.0A) 0-150
0x2064 우 최대전류 0.1A 300 (30.0A) 0-300

readCurrentLimits()가 시작 시 1회 조회해 콘솔에 출력하고, --max_current_a 인자 (기본 20.0A)로 최대전류를 4바퀴 동일하게 낮춘다. 정격전류(150=15A)는 쓰지 않고 최대전류만 변경한다 — 근거와 튜닝 배경은 05-error-troubleshooting.md 참고.

2.7 전체 레지스터 주소록 (Address Directory, 매뉴얼 §4 원문 기준)

공통 상수 (Left/Right 공통)

주소 이름 접근 기본값 설명
2000h Communication offline time RW/S 0 ms, 0-32000. 시간 내 통신 없으면 정지
2001h RS485 Node ID RW/S 1 1-127
2002h RS485 Baud Rate RW/S 2 1:128000 2:115200 3:57600 4:38400 5:19200 6:9600
2003h Input signal status RO 0 bit0-1: X0-X1 입력 레벨
2004h Output signal status RO 0 bit0-1: Y0-Y1 출력 레벨
2005h Clear feedback position RW 0 0 무효, 1 좌, 2 우, 3 좌우 (미저장)
2006h Reset absolute zero point RW 0 0 무효, 1 좌, 2 우, 3 좌우 (미저장)
2007h Shaft state after power on RW/S 0 0 Enable 안 됨/락 안 됨, 1 Enable 안 됨/락
2008h Maximum motor speed RW/S 1000 r/min, 1-1000
2009h Register parameter settings RW 0 0 무효, 1 공장 초기화
200Ah CAN Node ID RW/S 1 1-127
200Bh CAN Baud rate RW/S 1 0:1000 1:500 2:250 3:125 4:100 Kbit/s
200Ch Parking mode RW/S 0 0 Close, 1 Open
200Dh Control mode RW/S 0 0 undefined, 1 위치(상대), 2 위치(절대), 3 속도, 4 토크
200Eh Control word RW 0 §2.5 참고
200Fh Sync/Async control status RW/S 0 0 동기, 1 비동기
2010h RW 레지스터 EEPROM 저장 여부 RW 0 0 무효, 1 저장
2011h Quick stop control RW/S 5 5 정지, 6 감속시간 적용 급정지, 7 감속시간 미적용 급정지
2012h Close operation control RW/S 1 0 무효, 1 정상정지
2013h Disable control RW/S 1 0 무효, 1 정지(switch on 상태로)
2014h Halt control RW/S 1 1 정지, 2 감속 급정지, 3 무감속 급정지
2016h Input effective level RW/S 0 bit0 X0, bit1 X1 (0 기본 High, 1 반전 Low)
2017h Input X0 function RW/S 9 0 none, 1-8 NC, 9 비상정지
2018h Input X1 function RW/S 0
2019h Output effective level RW/S 0 bit0 Y0, bit1 Y1, bit2 B0, bit3 B1
201Ah 출력 B0 (좌 브레이크) RW/S 0 0 Open, 1 Close — 코드 사용
201Bh 출력 B1 (우 브레이크) RW/S 0 0 Open, 1 Close — 코드 사용
201Ch Output Y0 function RW/S 0 0 undefined, 1 알람신호, 2 상태신호, 3 목표위치도달(예약)
201Dh Output Y1 function RW/S 0
201Eh 드라이버 온도 보호 임계값 RW/S 800 0.1℃, 0-1200
201Fh Alarm PWM 처리 방식 RW/S 0 0 close, 1 open
2020h Overload 처리 방식 RW/S 0 0 close, 1 open
2021h I/O 비상정지 처리 모드 RW/S 0 0 축고정(우선I), 1 댐핑(우선II), 2 축해제(우선III); low8=INPUT1 high8=INPUT2
2022h Given speed resolution RW/S 1 1:1RPM ... A:0.1RPM
2023h Velocity overshoot RW/S 1 0 close, 1 open
2024h Regen resistance value RW/S 50 0.1Ω, 0-1000
2025h Regen resistance power RW/S 100 W, 0-1000
2026h Regen opening voltage RW/S 650 0.1V, 360-750
2027h Regen close voltage RW/S 600 0.1V, 310-700
2028h Regen function control RW/S 1 0 close, 1 open
2029h Default running direction RW/S 0 0 CW, 1 CCW

좌모터 파라미터 (2030h204Ah) / 우모터 파라미터 (2060h207Ah, 좌+0x30 오프셋)

좌 주소 우 주소 이름 접근 기본값 설명
2030h 2060h Encoder line RW/S 1024 0-4096
2031h 2061h Hall offset angle RW/S 0 1°, -360~360
2032h 2062h Overload factor RW/S 200 %, 0-300
2033h 2063h 정격전류 RW/S 150 0.1A, 0-150 — 코드 사용
2034h 2064h 최대전류 RW/S 300 0.1A, 0-300 — 코드 사용
2035h 2065h Overload protection time RW/S 300 10ms, 0-6553
2036h 2066h Position following error threshold RW/S 409 10counts, 1-6553
2037h 2067h Velocity smoothing factor RW/S 1000 0-30000
2038h 2068h Current Loop Kp RW/S 600 0-30000
2039h 2069h Current Loop Ki RW/S 300 0-30000
203Ah 206Ah Feedforward output smoothing RW/S 100 0-30000
203Bh 206Bh Torque output smoothing RW/S 100 0-30000
203Ch 206Ch Velocity Loop Kp RW/S 500 0-30000
203Dh 206Dh Velocity Loop Ki RW/S 100 0-30000
203Eh 206Eh Velocity Loop Kf RW/S 500 0-30000
203Fh 206Fh Position Loop Kp RW/S 100 0-30000
2040h 2070h Position Loop Kf RW/S 50 0-30000
2043h 2073h Initial velocity (속도모드) RW/S 1 r/min, 1-250
2044h 2074h Initial velocity (위치모드) RW/S 1 r/min, 1-250
2045h 2075h Motor poles RW/S 15 4-64
2046h 2076h Over temperature threshold RW/S 800 0.1℃, 0-1200
2047h-204Ah 2077h-207Ah Velocity observer coefficients 1-4 RW/S 1000/750/350/1000 0-30000

제어 파라미터 (2080h~2091h)

주소 이름 접근 기본값 설명
2080h S자 가속시간(좌) RW/S 500ms 0-32767ms — 코드 사용 (150ms)
2081h S자 가속시간(우) RW/S 500ms 0-32767ms — 코드 사용 (150ms)
2082h S자 감속시간(좌) RW/S 500ms 0-32767ms — 코드 사용 (150ms)
2083h S자 감속시간(우) RW/S 500ms 0-32767ms — 코드 사용 (150ms)
2084h 급정지 감속시간(좌) RW/S 10ms 0-32767ms
2085h 급정지 감속시간(우) RW/S 10ms 0-32767ms
2086h 토크 슬로프(좌) RW/S 300ms mA/s(1/1000초 단위)
2087h 토크 슬로프(우) RW/S 300ms
2088h 목표속도(좌) RW 0 I16, r/min, ±3000 — 코드 사용, 매 틱 기록
2089h 목표속도(우) RW 0 I16, r/min, ±3000 — 코드 사용, 매 틱 기록
208Ah/208Bh 목표위치 상/하위(좌) RW 0 포지션 모드 전용 (미사용)
208Ch/208Dh 목표위치 상/하위(우) RW 0 포지션 모드 전용 (미사용)
208Eh/208Fh 최대속도(좌/우, 포지션모드) RW/S 120 r/min 포지션 모드 전용 (미사용)
2090h/2091h 목표토크(좌/우) RW 0 mA, ±30000 — 토크 모드 전용 (미사용)

읽기 전용 상태 (20A0h~20B0h)

주소 이름 단위/범위 코드 사용 여부
20A0h Software version - 미사용
20A1h Bus voltage 0.01V 미사용 (배터리 전압 모니터링에 활용 가능)
20A2h Status word L:bit7-6, R:bit15-14 → 00 해제/40 축고정/80 비상정지/C0 알람; bit0(L)/bit8(R) 0정지 1구동 미사용
20A3h Hall input state 0-7 (0,7이면 홀 오류), high8=좌 low8=우 미사용
20A4h Motor temperature 1℃, -55~120, high8=좌 low8=우 미사용 (과열 사전감지에 활용 가능)
20A5h 에러코드(좌) 비트마스크 (§2.4) 코드 사용
20A6h 에러코드(우) 비트마스크 (§2.4) 코드 사용
20A7h/20A8h 실제위치 상/하위(좌) counts, I16×2 코드 사용l_tick
20A9h/20AAh 실제위치 상/하위(우) counts, I16×2 코드 사용r_tick
20ABh 실제속도(좌) 0.1r/min 코드 사용l_fb
20ACh 실제속도(우) 0.1r/min 코드 사용r_fb
20ADh 실제토크/전류(좌) 0.1A, ±300 코드 사용l_torque_a
20AEh 실제토크/전류(우) 0.1A, ±300 코드 사용r_torque_a
20AFh Software connected status 01 미사용
20B0h Driver temperature 0.1℃, -550~1200 미사용 (과열 사전감지에 활용 가능)

미사용이지만 유용한 레지스터: 20A1h(버스 전압), 20A4h/20B0h(모터/드라이버 온도)는 현재 코드가 읽지 않는다. 배터리 저전압 경보나 열 관리 기능을 추가하려면 readFeedback()의 연속 읽기 범위를 확장하거나 별도 저빈도 폴링을 추가하는 것을 검토할 수 있다.