누리로봇 SF시리즈 CANopen 프로토콜
1. 문서 개요 (Document Overview)
1.1 목적 (Purpose)
본 문서는 누리로봇 SF시리즈의 CANopen/EtherCAT 통신 프로토콜을 이용하여 호스트 컨트롤러와 통신하기 위한 명령 체계, 데이터 형식 및 통신 절차를 설명합니다.
본 매뉴얼에서는 다음과 같은 내용을 제공합니다.
CANopen 통신 프로토콜의 기본 구성
CAN 메시지(Frame) 구조
제어(Command) 및 설정(Configuration) 명령
피드백(Response) 데이터 형식
통신 처리 절차 및 예제
오류 코드 및 예외 처리 방법
본 문서는 시스템 개발자, 제어 소프트웨어 개발자 및 장비 설계자를 대상으로 작성되었으며, 누리로봇 SF시리즈를 CANopen 네트워크에 연결하여 제어하기 위한 기술 자료로 활용할 수 있습니다.
1.2 적용 범위 (Scope)
본 문서는 CANopen/EtherCAT 인터페이스를 지원하는 모든 누리로봇 SF시리즈 제품에 적용됩니다.
적용 범위는 다음과 같습니다.
CANopen 기반 네트워크 구성
CAN 통신 초기화 및 Node 설정
PDO(Process Data Object) 통신
SDO(Service Data Object) 통신
NMT(Network Management) 명령
Emergency(EMCY) 메시지
Heartbeat 및 Node Monitoring
제어 명령 및 상태 피드백
파라미터 읽기 및 쓰기
오류 진단 및 예외 처리
본 문서의 예제는 일반적인 CANopen/EtherCAT 네트워크 환경을 기준으로 작성되었으며, 실제 시스템에서는 상위 제어기(PLC, IPC, Motion Controller 등)의 구현 방식에 따라 일부 절차가 달라질 수 있습니다.
또한 제품의 하드웨어 사양 또는 펌웨어 버전에 따라 일부 Object Dictionary 항목, 지원 기능 및 기본 설정 값이 변경될 수 있습니다. 최신 기능 및 변경 사항은 제품 릴리스 노트 또는 최신 펌웨어 문서를 참고하십시오.
중요
본 매뉴얼에서 설명하는 CANopen 프로토콜은 CiA 301 표준을 기반으로 구현되었습니다. 일부 제품에서는 누리로봇 SF시리즈 전용 확장 Object 및 제조사 고유 명령(Manufacturer Specific Object)을 추가로 지원할 수 있으며, 해당 내용은 본 문서의 관련 장에서 별도로 설명합니다.
2. 시스템 구성 (System Configuration)
CANopen은 CAN(Controller Area Network) 기반의 산업용 필드버스(Fieldbus) 프로토콜로, 다양한 제어 장치와 액추에이터 간의 표준화된 통신을 제공합니다. 누리로봇 SF시리즈는 CiA 301 표준을 기반으로 CANopen Slave(Node)로 동작하며, 상위 제어기(Master)로부터 명령을 수신하고 현재 상태를 주기적으로 전송합니다.
본 장에서는 누리로봇 SF시리즈 CANopen/EtherCAT 시스템의 구성 요소와 네트워크 구성 방법, 그리고 안정적인 통신을 위한 주의사항을 설명합니다.
2.1 통신 개요 (Communication Overview)
누리로봇 SF시리즈 CANopen 시스템은 하나의 CAN Bus 상에서 Master와 여러 개의 Slave Node가 통신하는 구조입니다.
각 누리로봇 SF시리즈 모듈은 고유한 Node ID를 가지며, Master는 CANopen 프로토콜을 이용하여 각 Node를 개별적으로 제어하거나 네트워크 전체를 관리할 수 있습니다.
지원하는 주요 CANopen 서비스는 다음과 같습니다.
기능 |
설명 |
|---|---|
NMT (Network Management) |
네트워크 상태 관리 |
PDO (Process Data Object) |
실시간 제어 및 피드백 데이터 전송 |
SDO (Service Data Object) |
파라미터 읽기 및 쓰기 |
EMCY (Emergency) |
오류 발생 알림 |
Heartbeat |
Node 동작 상태 모니터링 |
일반적인 통신 절차는 다음과 같습니다.
CAN Bus 초기화
Master와 Slave 연결
NMT 명령을 이용한 네트워크 시작
SDO를 이용한 초기 파라미터 설정
PDO를 이용한 실시간 제어 및 상태 피드백
Heartbeat 및 EMCY를 통한 상태 감시
2.2 네트워크 구성 예시 (Network Configuration Example)
일반적인 누리로봇 SF시리즈 CANopen 네트워크는 다음과 같이 구성됩니다.
각 누리로봇 SF시리즈 모듈은 동일한 CAN Bus에 연결되며, 모든 Node는 고유한 Node ID를 사용해야 합니다.
Master는 다음 기능을 수행합니다.
Network Start / Stop
Node 상태 관리
Motion Command 전송
Parameter 설정
Fault Reset
Feedback 모니터링
Slave(누리로봇 SF시리즈)는 다음 기능을 수행합니다.
Motion 제어
상태 정보 송신
센서 데이터 제공
오류 상태 보고
파라미터 저장
참고
하나의 CAN Bus에서는 동일한 Node ID를 사용하는 장치를 동시에 연결할 수 없습니다.
2.3 주의사항 (Precautions)
CANopen 네트워크를 안정적으로 운용하기 위해 다음 사항을 준수하십시오.
Node ID 관리
모든 누리로봇 SF시리즈 모듈은 서로 다른 Node ID를 사용해야 합니다.
중복된 Node ID는 통신 충돌 및 데이터 오류를 발생시킬 수 있습니다.
Node ID 변경 후에는 장치를 재시작하여 설정을 적용하십시오.
Baud Rate 설정
네트워크에 연결된 모든 장치는 동일한 Baud Rate를 사용해야 합니다.
Baud Rate가 서로 다를 경우 통신이 이루어지지 않습니다.
Bus Termination
CAN Bus 양 끝단에는 반드시 120 Ω 종단 저항(Termination Resistor) 을 설치해야 합니다.
Bus 중간에는 종단 저항을 설치하지 않습니다.
종단 저항이 없거나 과도하게 설치되면 통신 품질이 저하될 수 있습니다.
배선
CAN_H와 CAN_L는 반드시 Twist Pair 케이블을 사용하십시오.
전원선과 CAN 통신선을 장거리로 병행 배선하지 마십시오.
강한 전자기장이 발생하는 장비와는 충분한 거리를 유지하십시오.
전원
모든 통신 케이블은 전원이 차단된 상태에서 연결하거나 분리하십시오.
전원이 인가된 상태에서 CAN 케이블을 연결하거나 분리하면 통신 인터페이스가 손상될 수 있습니다.
네트워크 길이
CAN Bus의 최대 통신 거리는 Baud Rate에 따라 달라집니다.
Baud Rate |
권장 최대 Bus 길이 |
|---|---|
1 Mbps |
약 40 m |
500 kbps |
약 100 m |
250 kbps |
약 250 m |
125 kbps |
약 500 m |
실제 설치 환경에서는 케이블 품질, 분기 길이(Stub Length), 전자기 간섭(EMI) 등의 영향을 받을 수 있으므로 충분한 여유를 두고 설계하는 것을 권장합니다.
중요
CANopen 네트워크의 안정성은 배선 품질, 접지(Grounding), 종단 저항(Termination), 전원 공급 및 Node 설정에 크게 영향을 받습니다. 시스템 설치 후에는 반드시 통신 상태와 오류 메시지를 확인하여 정상적으로 네트워크가 동작하는지 검증하십시오.
3. 데이터 프레임 구조 (Packet Structure)
누리로봇 SF시리즈 CANopen은 Classical CAN 2.0A(Standard Frame) 를 기반으로 통신하며, 모든 데이터는 CANopen에서 정의하는 Communication Object(COB) 형식으로 전송됩니다.
각 CAN 프레임은 Identifier(COB-ID) 와 최대 8 Byte의 데이터(Data Field) 로 구성됩니다. COB-ID는 메시지의 종류와 송수신 대상(Node ID)을 나타내며, 데이터 영역에는 제어 명령, 파라미터 또는 상태 정보가 저장됩니다.
3.1 CAN Frame Format
CANopen에서는 Standard CAN Frame(11-bit Identifier)을 사용합니다.
Field |
Length |
Description |
|---|---|---|
SOF |
1 bit |
Start of Frame |
Identifier (COB-ID) |
11 bit |
CANopen Message Identifier |
RTR |
1 bit |
Remote Transmission Request |
IDE |
1 bit |
Identifier Extension (Standard Frame = 0) |
r0 |
1 bit |
Reserved |
DLC |
4 bit |
Data Length Code (0~8 Byte) |
Data |
0~8 Byte |
Payload |
CRC |
15 bit |
Error Detection |
ACK |
2 bit |
Acknowledge |
EOF |
7 bit |
End of Frame |
누리로봇 SF시리즈 CANopen은 모든 제어 및 상태 데이터를 Data Field에 저장하여 전송합니다.
3.2 COB-ID Structure
CANopen에서는 CAN Identifier를 COB-ID (Communication Object Identifier) 라고 합니다.
COB-ID는 다음과 같이 구성됩니다.
+----------------------+-----------+
| Function Code (4bit) | Node ID |
+----------------------+-----------+
(7bit)
Function Code : 메시지 종류를 정의
Node ID : 대상 장치 번호(1~127)
예를 들어 Node ID가 0x05인 경우 주요 COB-ID는 다음과 같습니다.
Message |
COB-ID |
|---|---|
NMT |
0x000 |
SYNC |
0x080 |
EMCY |
0x085 |
TPDO1 |
0x185 |
RPDO1 |
0x205 |
TPDO2 |
0x285 |
RPDO2 |
0x305 |
SDO Request |
0x605 |
SDO Response |
0x585 |
Heartbeat |
0x705 |
3.3 Data Field Format
CANopen Data Field는 최대 8 Byte까지 사용할 수 있습니다.
Byte0 Byte1 Byte2 Byte3 Byte4 Byte5 Byte6 Byte7
+-----+-----+-----+-----+-----+-----+-----+-----+
| Data Payload (0~8 Byte) |
+-----+-----+-----+-----+-----+-----+-----+-----+
Data Field의 의미는 사용하는 Communication Object에 따라 달라집니다.
예를 들어,
PDO는 제어 데이터 또는 피드백 데이터
SDO는 Index/Sub-index 및 Parameter
EMCY는 Error Code
Heartbeat는 Node State
등을 저장합니다.
3.4 Communication Object
CANopen에서는 목적에 따라 여러 종류의 Communication Object를 사용합니다.
Object |
용도 |
|---|---|
NMT |
Network 상태 제어 |
SYNC |
동기화 신호 |
PDO |
실시간 데이터 송수신 |
SDO |
Object Dictionary 접근 |
EMCY |
긴급 오류 보고 |
Heartbeat |
Node 상태 확인 |
각 Communication Object는 고유한 COB-ID를 사용하며 동시에 하나의 CAN Bus에서 공존할 수 있습니다.
3.5 PDO Packet
PDO(Process Data Object)는 실시간 제어를 위한 가장 빠른 통신 방식입니다.
특징은 다음과 같습니다.
Object Dictionary 접근 없이 직접 데이터 전송
최대 8 Byte
실시간 제어용
Motion Command 및 Feedback 전송
일반적인 PDO 패킷은 다음과 같습니다.
Byte |
내용 |
|---|---|
Byte0~1 |
Target Position 또는 Status |
Byte2~3 |
Velocity |
Byte4~5 |
Torque 또는 Current |
Byte6 |
Control / Status Flag |
Byte7 |
Reserved |
실제 데이터 배치는 PDO Mapping 설정에 따라 변경될 수 있습니다.
3.6 SDO Packet
SDO(Service Data Object)는 Object Dictionary의 데이터를 읽거나 쓰기 위한 서비스입니다.
요청(Request) 및 응답(Response) 모두 8 Byte 프레임을 사용합니다.
SDO Request
Byte |
Description |
|---|---|
Byte0 |
Command Specifier |
Byte1 |
Index (Low Byte) |
Byte2 |
Index (High Byte) |
Byte3 |
Sub-index |
Byte4~7 |
Data |
SDO Response
Byte |
Description |
|---|---|
Byte0 |
Response Code |
Byte1 |
Index (Low Byte) |
Byte2 |
Index (High Byte) |
Byte3 |
Sub-index |
Byte4~7 |
Returned Data |
SDO는 주로 다음과 같은 용도로 사용됩니다.
Parameter Read
Parameter Write
Node Configuration
Device Information 조회
3.7 Byte Order
누리로봇 SF시리즈 CANopen은 Little-Endian 데이터 형식을 사용합니다.
예를 들어 32-bit 값 0x12345678은 CAN 데이터 영역에 다음과 같이 저장됩니다.
Byte0 |
Byte1 |
Byte2 |
Byte3 |
|---|---|---|---|
0x78 |
0x56 |
0x34 |
0x12 |
멀티바이트 데이터를 해석할 때에는 Little-Endian 순서를 반드시 고려해야 합니다.
3.8 데이터 타입
Object Dictionary에서 사용하는 주요 데이터 형식은 다음과 같습니다.
Type |
Size |
Description |
|---|---|---|
BOOLEAN |
1 Byte |
논리값 |
INTEGER8 |
1 Byte |
부호 있는 8비트 |
UNSIGNED8 |
1 Byte |
부호 없는 8비트 |
INTEGER16 |
2 Byte |
부호 있는 16비트 |
UNSIGNED16 |
2 Byte |
부호 없는 16비트 |
INTEGER32 |
4 Byte |
부호 있는 32비트 |
UNSIGNED32 |
4 Byte |
부호 없는 32비트 |
REAL32 |
4 Byte |
IEEE 754 단정도 실수 |
참고
본 문서에서 설명하는 모든 CAN 데이터는 16진수(Hexadecimal)를 기준으로 표기합니다. 멀티바이트 데이터는 Little-Endian 형식을 사용하며, Object Dictionary의 데이터 타입에 따라 해석해야 합니다.
4. 명령 체계 (Command Set Overview)
누리로봇 SF시리즈 CANopen은 CiA 301 및 CiA 402(Device Profile for Drives and Motion Control)를 기반으로 명령을 처리합니다. 모든 명령은 CANopen Communication Object를 통해 전달되며, 목적에 따라 제어(Control), 설정(Configuration), 피드백(Feedback) 의 세 가지 범주로 구분됩니다.
각 명령은 CAN Bus를 통해 전송되며, 누리로봇 SF시리즈는 명령을 수신한 후 현재 동작 상태와 내부 조건을 확인하여 해당 명령을 수행하거나 오류를 반환합니다.
4.1 명령 분류
누리로봇 SF시리즈 CANopen에서 지원하는 명령은 다음과 같이 구분됩니다.
구분 |
설명 |
주요 통신 방식 |
|---|---|---|
제어 명령 (Control Command) |
액추에이터의 동작을 제어하는 명령 |
RPDO, SDO |
설정 명령 (Configuration Command) |
장치 파라미터를 설정하거나 조회하는 명령 |
SDO |
피드백 응답 (Feedback Response) |
장치의 상태 및 동작 결과를 반환하는 데이터 |
TPDO, SDO, EMCY, Heartbeat |
각 명령은 장치의 현재 NMT 상태 및 CiA 402 상태 머신(PDS FSA)에 따라 실행 가능 여부가 결정됩니다.
4.2 명령 처리 흐름
일반적인 CANopen 제어 절차는 다음과 같습니다.
Host Controller
│
│
├─① NMT Start
│
├─② Parameter Configuration (SDO)
│
├─③ Enable Operation
│
├─④ Motion Command (PDO)
│
├─⑤ Status Feedback (PDO)
│
└─⑥ Error Monitoring (Heartbeat / EMCY)
초기 통신에서는 SDO를 이용하여 필요한 파라미터를 설정하고, 운전 상태(Operational)로 전환한 후에는 PDO를 이용하여 실시간 제어를 수행하는 것을 권장합니다.
4.3 제어 명령 (Control Commands)
제어 명령은 액추에이터의 동작을 직접 제어하기 위한 명령입니다.
대표적인 제어 항목은 다음과 같습니다.
기능 |
설명 |
|---|---|
Controlword |
CiA 402 상태 제어 |
Operation Mode |
운전 모드 선택 |
Target Position |
목표 위치 지정 |
Target Velocity |
목표 속도 지정 |
Target Torque |
목표 토크 지정 |
Quick Stop |
긴급 감속 정지 |
Fault Reset |
오류 해제 |
실시간 제어가 필요한 명령은 일반적으로 RPDO를 통해 전송하며, 초기 설정이나 진단 목적의 제어는 SDO를 사용할 수 있습니다.
4.4 설정 명령 (Configuration Commands)
설정 명령은 Object Dictionary에 저장된 파라미터를 읽거나 수정하기 위한 명령입니다.
주요 설정 항목은 다음과 같습니다.
기능 |
설명 |
|---|---|
Node ID |
장치 주소 설정 |
Baud Rate |
통신 속도 설정 |
PDO Mapping |
PDO 데이터 구성 |
Heartbeat Time |
Heartbeat 주기 설정 |
Motion Parameter |
속도, 가속도 등 운전 파라미터 |
Manufacturer Parameters |
제조사 전용 파라미터 |
모든 설정 명령은 SDO를 통해 수행되며, 일부 파라미터는 장치를 재시작해야 적용될 수 있습니다.
4.5 피드백 응답 (Feedback Responses)
누리로봇 SF시리즈는 현재 운전 상태와 동작 정보를 실시간으로 제공합니다.
주요 피드백 항목은 다음과 같습니다.
항목 |
설명 |
|---|---|
Statusword |
CiA 402 상태 정보 |
Actual Position |
현재 위치 |
Actual Velocity |
현재 속도 |
Actual Torque |
현재 토크 |
Current |
모터 전류 |
Temperature |
내부 온도 |
Error Code |
오류 코드 |
Device State |
장치 상태 |
피드백은 TPDO를 이용한 주기적 전송 또는 SDO를 이용한 요청 방식으로 확인할 수 있습니다.
4.6 명령 실행 조건
모든 명령은 장치의 현재 운전 상태에 따라 실행 가능 여부가 달라집니다.
상태 |
제어 명령 |
설정 명령 |
피드백 |
|---|---|---|---|
Initialization |
✗ |
✗ |
제한적 |
Pre-operational |
✗ |
✓ |
✓ |
Operational |
✓ |
✓ |
✓ |
Stopped |
✗ |
✗ |
Heartbeat만 가능 |
PDO를 이용한 실시간 제어는 반드시 Operational 상태에서 수행해야 합니다.
4.7 오류 처리
명령 수행 중 다음과 같은 상황이 발생하면 장치는 명령을 거부하거나 오류를 반환할 수 있습니다.
지원하지 않는 Object 접근
잘못된 데이터 길이
읽기 전용(Object Read Only) 접근
허용 범위를 벗어난 값 입력
현재 상태에서 실행할 수 없는 명령
내부 장치 오류
오류 발생 시 장치는 SDO Abort Code 또는 EMCY(Emergency Message)를 통해 오류 정보를 제공합니다.
참고
본 장에서는 누리로봇 SF시리즈 CANopen 명령 체계를 개괄적으로 설명합니다. 각 명령의 데이터 형식, Object Dictionary 주소 및 사용 방법은 이후의 제5장 제어 명령, 제6장 설정 명령, 제7장 피드백 응답에서 상세히 설명합니다.
5. 제어 명령 (Control Commands)
제어 명령(Control Commands)은 누리로봇 SF시리즈의 동작을 제어하기 위한 CANopen 명령입니다. 제어 명령은 주로 CiA 402 Drive Profile을 기반으로 하며, 장치의 상태(State)를 변경하거나 목표 위치, 속도 및 토크를 지정하여 모션을 수행합니다.
실시간 제어가 필요한 데이터는 일반적으로 PDO(Process Data Object) 를 통해 전송하며, 초기 설정이나 비주기적 제어는 SDO(Service Data Object) 를 사용할 수 있습니다.
5.1 제어 순서
모션을 수행하기 위해서는 다음 순서에 따라 제어를 진행해야 합니다.
CAN 통신 연결
NMT를 Operational 상태로 전환
필요한 운전 파라미터 설정
Operation Mode 설정
Controlword를 이용하여 Servo Enable
목표값(Target Value) 전송
Statusword를 확인하여 동작 상태 모니터링
필요 시 Fault Reset 또는 Quick Stop 수행
참고
CiA 402 상태 머신(PDS FSA)의 상태 전이가 완료되지 않은 경우에는 목표 위치, 속도 또는 토크 명령이 실행되지 않을 수 있습니다.
5.2 Controlword
Controlword(Object 0x6040)는 드라이브의 상태를 제어하는 기본 명령입니다.
Controlword를 이용하여 다음과 같은 기능을 수행할 수 있습니다.
Servo Enable
Servo Disable
Quick Stop
Fault Reset
New Set-point 실행
Halt
일반적인 상태 전이 순서는 다음과 같습니다.
단계 |
Controlword |
기능 |
|---|---|---|
Shutdown |
0x0006 |
Ready to Switch On |
Switch On |
0x0007 |
Switched On |
Enable Operation |
0x000F |
Servo Enable |
Disable Voltage |
0x0000 |
Servo Disable |
Quick Stop |
0x0002 |
긴급 감속 정지 |
Fault Reset |
0x0080 |
Fault 해제 |
5.3 Operation Mode
Operation Mode(Object 0x6060)는 액추에이터의 동작 방식을 선택합니다.
지원하는 운전 모드는 다음과 같습니다.
Mode |
Value |
설명 |
|---|---|---|
Profile Position (PP) |
1 |
위치 제어 |
Profile Velocity (PV) |
3 |
속도 제어 |
Profile Torque (PT) |
4 |
토크 제어 |
Homing (HM) |
6 |
원점 복귀 |
Cyclic Synchronous Position (CSP) |
8 |
주기 동기 위치 제어 |
Cyclic Synchronous Velocity (CSV) |
9 |
주기 동기 속도 제어 |
Cyclic Synchronous Torque (CST) |
10 |
주기 동기 토크 제어 |
운전 모드는 모션 명령을 전송하기 전에 반드시 설정해야 합니다.
5.4 위치 제어
위치 제어는 목표 위치(Target Position)를 지정하여 액추에이터를 원하는 위치로 이동시키는 기능입니다.
주요 제어 항목은 다음과 같습니다.
Object |
설명 |
|---|---|
Target Position |
목표 위치 |
Profile Velocity |
이동 속도 |
Profile Acceleration |
가속도 |
Profile Deceleration |
감속도 |
Controlword |
시작 명령 |
목표 위치가 설정되면 Controlword를 이용하여 새로운 위치 명령을 실행합니다.
5.5 속도 제어
속도 제어는 목표 속도를 지정하여 일정한 속도로 회전하도록 제어합니다.
주요 제어 항목은 다음과 같습니다.
Object |
설명 |
|---|---|
Target Velocity |
목표 속도 |
Velocity Limit |
최대 속도 |
Acceleration |
가속도 |
Deceleration |
감속도 |
속도 제어는 목표 속도가 변경될 때마다 새로운 명령을 전송하여 갱신합니다.
5.6 토크 제어
토크 제어는 출력 토크를 기준으로 동작하는 운전 방식입니다.
주요 제어 항목은 다음과 같습니다.
Object |
설명 |
|---|---|
Target Torque |
목표 토크 |
Torque Limit |
최대 허용 토크 |
Current Limit |
최대 전류 제한 |
토크 제어는 외부 충돌 감지, 힘 제어 및 협동 로봇 응용 분야에서 주로 사용됩니다.
경고
토크 모드에서는 예상하지 못한 움직임이 발생할 수 있으므로 위치 제한, 속도 제한 및 전류 제한을 적절하게 설정한 후 운전하십시오.
5.7 Quick Stop
Quick Stop은 비상 상황에서 장치를 안전하게 감속 정지시키는 기능입니다.
Quick Stop 명령이 실행되면 장치는 설정된 감속도에 따라 정지하며, 즉시 Servo Power를 차단하지 않습니다.
Quick Stop 이후에는 현재 상태를 확인한 후 다시 Enable Operation을 수행해야 합니다.
5.8 Fault Reset
장치에서 Fault가 발생하면 일반적인 제어 명령은 수행되지 않습니다.
Fault Reset 명령을 이용하여 오류를 해제할 수 있으며, 오류가 제거되지 않은 경우에는 Fault 상태가 유지됩니다.
Fault Reset 절차는 다음과 같습니다.
오류 원인 제거
Statusword 확인
Fault Reset(Controlword = 0x0080) 실행
Shutdown → Switch On → Enable Operation 순으로 재진입
5.9 제어 명령 사용 시 주의사항
제어 명령을 사용할 때에는 다음 사항을 확인하십시오.
장치가 Operational 상태인지 확인합니다.
운전 모드(Operation Mode)를 먼저 설정합니다.
Controlword의 상태 전이가 정상적으로 완료되었는지 확인합니다.
목표 위치, 속도 또는 토크가 허용 범위를 초과하지 않는지 확인합니다.
Statusword를 주기적으로 모니터링하여 오류 상태를 확인합니다.
Fault 상태에서는 먼저 오류를 해제한 후 제어를 재개합니다.
중요
Controlword와 Statusword는 CiA 402 상태 머신을 기반으로 동작합니다. 각 상태에서 허용되는 제어 명령은 현재 장치 상태에 따라 달라질 수 있으므로, 명령 실행 전 Statusword를 확인하여 장치가 정상적인 운전 상태인지 확인하는 것을 권장합니다.
6. 설정 명령 (Configuration Commands)
설정 명령(Configuration Commands)은 누리로봇 SF시리즈의 통신 및 동작 파라미터를 설정하거나 조회하기 위한 명령입니다.
설정 명령은 Service Data Object(SDO) 를 이용하여 Object Dictionary에 접근하는 방식으로 수행됩니다. 이를 통해 사용자는 통신 설정, 운전 파라미터, PDO 매핑, 장치 정보 등을 읽거나 변경할 수 있습니다.
설정 명령은 일반적으로 시스템 초기화 또는 유지보수 과정에서 사용되며, 실시간 제어에는 PDO를 사용하는 것을 권장합니다.
6.1 SDO를 이용한 파라미터 접근
SDO(Service Data Object)는 Object Dictionary의 특정 Object에 접근하여 데이터를 읽거나 쓰는 CANopen 서비스입니다.
각 Object는 다음 정보로 구성됩니다.
항목 |
설명 |
|---|---|
Index |
Object 주소 |
Sub-index |
Object의 세부 항목 |
Data Type |
데이터 형식 |
Access |
Read Only(RO), Read/Write(RW) |
Default Value |
기본값 |
SDO 통신은 Client(Host Controller) 와 Server(누리로봇 SF시리즈) 간의 요청(Request)과 응답(Response) 방식으로 수행됩니다.
6.2 설정 가능한 주요 항목
누리로봇 SF시리즈 CANopen에서 일반적으로 설정 가능한 항목은 다음과 같습니다.
분류 |
내용 |
|---|---|
Communication |
Node ID, Heartbeat, PDO 설정 |
Motion Parameter |
속도, 가속도, 감속도, 토크 제한 |
Drive Configuration |
운전 모드, 제어 옵션 |
Device Information |
Firmware Version, Device Name, Vendor ID |
Manufacturer Parameter |
제조사 전용 기능 |
각 Object의 Index 및 기본값은 Object Dictionary를 참조하십시오.
6.3 SDO Write
SDO Write는 Object Dictionary의 값을 변경하는 명령입니다.
Host Controller는 다음 정보를 포함하여 요청 프레임을 전송합니다.
Byte |
내용 |
|---|---|
Byte0 |
Command Specifier |
Byte1 |
Index (Low Byte) |
Byte2 |
Index (High Byte) |
Byte3 |
Sub-index |
Byte4~7 |
Data |
장치는 요청을 정상적으로 처리하면 Write Response를 반환합니다.
예를 들어 다음과 같은 설정에 사용할 수 있습니다.
운전 모드 변경
Heartbeat 시간 설정
Motion Parameter 변경
PDO Mapping 변경
제조사 전용 파라미터 설정
쓰기 권한이 없는 Object에 접근하거나 데이터 형식이 일치하지 않으면 SDO Abort Code를 반환합니다.
6.4 SDO Read
SDO Read는 Object Dictionary의 현재 값을 읽는 명령입니다.
Host Controller는 Index와 Sub-index를 지정하여 요청을 전송하며, 장치는 해당 Object의 값을 응답 프레임으로 반환합니다.
SDO Read는 다음과 같은 정보를 확인할 때 사용됩니다.
현재 운전 모드
Status Parameter
Firmware Version
Device Information
Motion Parameter
Error Code
6.5 통신 설정
CANopen 네트워크 운용을 위해 다음과 같은 통신 관련 파라미터를 설정할 수 있습니다.
항목 |
설명 |
|---|---|
Node ID |
장치 주소 |
Heartbeat Producer Time |
Heartbeat 송신 주기 |
PDO Communication Parameter |
PDO 전송 방식 |
PDO Mapping Parameter |
PDO 데이터 구성 |
Sync Parameter |
SYNC 동기화 설정 |
일부 통신 파라미터는 장치를 재시작한 후 적용됩니다.
참고
Node ID 및 PDO 관련 설정을 변경하는 경우, 변경 사항이 네트워크 전체의 통신에 영향을 줄 수 있으므로 모든 노드의 설정을 확인한 후 적용하십시오.
6.6 운전 파라미터 설정
운전 성능과 관련된 파라미터는 SDO를 이용하여 설정할 수 있습니다.
대표적인 항목은 다음과 같습니다.
항목 |
설명 |
|---|---|
Profile Velocity |
목표 속도 |
Profile Acceleration |
가속도 |
Profile Deceleration |
감속도 |
Max Motor Speed |
최대 속도 |
Torque Limit |
최대 토크 |
Current Limit |
최대 전류 |
운전 파라미터는 선택한 Operation Mode에 따라 사용되는 항목이 달라질 수 있습니다.
6.7 PDO 설정
PDO(Process Data Object)는 실시간 데이터 교환을 위한 통신 방식이며, 전송 데이터 구성은 PDO Mapping을 통해 변경할 수 있습니다.
PDO 설정 시 다음 항목을 구성합니다.
항목 |
설명 |
|---|---|
COB-ID |
PDO Identifier |
Transmission Type |
전송 방식 |
Inhibit Time |
최소 전송 간격 |
Event Timer |
이벤트 전송 주기 |
Mapping Object |
PDO 데이터 구성 |
PDO Mapping을 변경한 경우에는 Mapping을 비활성화한 후 설정을 변경하고 다시 활성화해야 합니다.
6.8 제조사 전용 파라미터
누리로봇 SF시리즈는 CiA 301 및 CiA 402 표준 Object 외에도 제조사 전용 Object를 제공합니다.
제조사 전용 Object를 통해 다음과 같은 기능을 설정할 수 있습니다.
제품 고유 기능
진단 정보
유지보수 정보
내부 보정값
기타 확장 기능
제조사 전용 Object의 사용 방법은 본 매뉴얼의 Object Dictionary를 참조하십시오.
6.9 설정 시 주의사항
설정 명령을 사용할 때에는 다음 사항을 준수하십시오.
Object의 접근 권한(Read/Write)을 확인합니다.
데이터 형식(Data Type)에 맞는 값을 사용합니다.
허용 범위를 초과하는 값을 입력하지 않습니다.
PDO Mapping 변경 시 관련 PDO를 비활성화한 후 설정합니다.
Node ID 또는 통신 설정 변경 후에는 장치를 재시작하여 변경 사항을 적용합니다.
SDO Abort Code가 반환되면 오류 원인을 확인한 후 다시 설정을 수행합니다.
중요
일부 설정은 장치의 동작 특성과 통신 방식에 직접적인 영향을 미칩니다. 시스템 운전 중에는 통신 파라미터나 PDO Mapping과 같은 핵심 설정을 변경하지 않는 것을 권장하며, 설정 변경은 장치가 안전하게 정지된 상태에서 수행하십시오.
7. 피드백 응답 (Feedback Response)
피드백 응답(Feedback Response)은 누리로봇 SF시리즈가 현재 동작 상태, 제어 결과 및 오류 정보를 Host Controller로 전달하는 기능입니다.
피드백 데이터는 CANopen Communication Object를 통해 전송되며, 목적에 따라 다음과 같은 방식으로 제공됩니다.
TPDO (Transmit Process Data Object) : 실시간 상태 정보 전송
SDO Response : 요청한 Object의 데이터 응답
Heartbeat : 장치의 운전 상태 전송
EMCY (Emergency) : 오류 발생 시 즉시 통보
Host Controller는 이러한 응답 데이터를 이용하여 장치의 상태를 확인하고, 정상 동작 여부를 판단하거나 예외 상황에 대응할 수 있습니다.
7.1 TPDO 응답
TPDO(Transmit Process Data Object)는 누리로봇 SF시리즈가 주기적으로 또는 이벤트 발생 시 Host Controller로 전송하는 실시간 데이터입니다.
주요 피드백 항목은 다음과 같습니다.
항목 |
설명 |
|---|---|
Statusword |
장치 상태 |
Actual Position |
현재 위치 |
Actual Velocity |
현재 속도 |
Actual Torque |
현재 토크 |
Motor Current |
모터 전류 |
Temperature |
내부 온도 |
Digital Input Status |
입력 상태 |
Digital Output Status |
출력 상태 |
TPDO는 PDO Mapping 설정에 따라 전송되는 데이터 구성이 달라질 수 있습니다.
7.2 Statusword
Statusword(Object 0x6041)는 CiA 402 상태 머신(PDS FSA)의 현재 상태를 나타내는 대표적인 피드백 정보입니다.
Host Controller는 Statusword를 확인하여 장치의 운전 가능 여부와 현재 상태를 판단할 수 있습니다.
대표적인 상태는 다음과 같습니다.
상태 |
설명 |
|---|---|
Not Ready to Switch On |
초기화 중 |
Switch On Disabled |
Servo 비활성화 |
Ready to Switch On |
Servo 준비 완료 |
Switched On |
Servo ON |
Operation Enabled |
정상 운전 |
Quick Stop Active |
긴급 정지 |
Fault Reaction Active |
오류 처리 중 |
Fault |
오류 발생 |
제어 명령을 전송하기 전에 Statusword를 확인하여 장치가 Operation Enabled 상태인지 확인하는 것을 권장합니다.
7.3 실제 운전 데이터
누리로봇 SF시리즈는 현재 운전 상태를 나타내는 다양한 피드백 데이터를 제공합니다.
Object |
설명 |
|---|---|
Position Actual Value |
현재 위치 |
Velocity Actual Value |
현재 속도 |
Torque Actual Value |
현재 토크 |
Current Actual Value |
현재 전류 |
Operation Mode Display |
현재 운전 모드 |
이 데이터는 TPDO 또는 SDO Read를 통해 확인할 수 있습니다.
7.4 SDO 응답
Host Controller가 SDO Read 또는 SDO Write 요청을 전송하면 누리로봇 SF시리즈는 처리 결과를 응답 프레임으로 반환합니다.
정상적인 응답에는 요청한 Object의 데이터 또는 명령 수행 결과가 포함됩니다.
SDO Read Response
Byte |
내용 |
|---|---|
Byte0 |
Response Code |
Byte1 |
Index (Low Byte) |
Byte2 |
Index (High Byte) |
Byte3 |
Sub-index |
Byte4~7 |
Data |
SDO Write Response
Byte |
내용 |
|---|---|
Byte0 |
Response Code |
Byte1 |
Index (Low Byte) |
Byte2 |
Index (High Byte) |
Byte3 |
Sub-index |
Byte4~7 |
Reserved |
정상적으로 처리되지 않은 경우에는 SDO Abort Code가 반환됩니다.
7.5 Heartbeat
Heartbeat는 장치가 정상적으로 동작하고 있음을 주기적으로 알리는 메시지입니다.
Heartbeat 메시지를 이용하여 Host Controller는 Node의 연결 상태를 확인할 수 있습니다.
Heartbeat의 주요 목적은 다음과 같습니다.
Node 생존 여부 확인
통신 단절 감지
Network Monitoring
Heartbeat 메시지에는 현재 NMT 상태가 포함됩니다.
값 |
상태 |
|---|---|
0x00 |
Boot-up |
0x04 |
Stopped |
0x05 |
Operational |
0x7F |
Pre-operational |
Heartbeat가 설정된 시간 내에 수신되지 않으면 Host Controller는 해당 Node의 통신 이상으로 판단할 수 있습니다.
7.6 EMCY(Emergency)
EMCY(Emergency Message)는 장치 내부에서 오류가 발생했을 때 즉시 전송되는 비동기 메시지입니다.
EMCY는 다음과 같은 상황에서 발생할 수 있습니다.
과전압
저전압
과전류
과온도
Encoder 오류
Motor 오류
통신 오류
내부 시스템 오류
EMCY 메시지는 오류 발생 시 1회 전송되며, Host Controller는 Error Code를 이용하여 오류 원인을 확인할 수 있습니다.
7.7 응답 처리 절차
Host Controller는 다음 순서로 피드백을 처리하는 것을 권장합니다.
Heartbeat 수신 여부 확인
EMCY 메시지 확인
Statusword 확인
Actual Position / Velocity / Torque 확인
필요 시 SDO Read 수행
오류 발생 시 Error Code 확인 및 Fault Reset 수행
이 절차를 통해 장치의 운전 상태를 지속적으로 모니터링하고 이상 상황에 신속하게 대응할 수 있습니다.
7.8 피드백 응답 사용 시 주의사항
피드백 데이터를 사용할 때에는 다음 사항을 확인하십시오.
TPDO Mapping에 따라 전송되는 데이터 구성이 달라질 수 있습니다.
Statusword를 이용하여 장치의 현재 상태를 먼저 확인한 후 제어 명령을 수행하십시오.
Heartbeat Timeout이 발생하면 통신 상태를 점검하십시오.
EMCY 메시지를 수신한 경우에는 Error Code를 확인하고 오류 원인을 제거한 후 Fault Reset을 수행하십시오.
실시간 제어에서는 TPDO를, 비주기적 정보 조회에는 SDO Read를 사용하는 것을 권장합니다.
중요
TPDO, Heartbeat 및 EMCY는 장치의 상태를 실시간으로 파악하기 위한 핵심 피드백 메커니즘입니다. Host Controller는 이들 메시지를 지속적으로 모니터링하여 통신 이상, 장치 오류 및 운전 상태 변화를 신속하게 감지하고 적절한 예외 처리를 수행해야 합니다.
8. 통신 처리 로직 (Communication Logic)
누리로봇 SF시리즈 CANopen 시스템은 CANopen 네트워크의 초기화부터 실시간 모션 제어 및 오류 처리까지 일정한 절차에 따라 동작합니다. Host Controller는 장치의 현재 상태를 확인하면서 적절한 명령을 전송해야 하며, 누리로봇 SF시리즈는 수신한 명령을 검증한 후 처리 결과를 피드백합니다.
본 장에서는 일반적인 CANopen 통신 처리 절차와 권장 운용 방법을 설명합니다.
8.1 통신 초기화
CANopen 네트워크가 시작되면 Host Controller는 먼저 장치와 정상적으로 통신할 수 있는 환경을 구성해야 합니다.
초기화 과정은 다음 순서로 수행하는 것을 권장합니다.
CAN Bus 초기화
Baud Rate 설정
Node ID 확인
Boot-up 메시지 수신 확인
NMT 상태 확인
Boot-up 메시지를 수신하면 해당 Node가 정상적으로 초기화를 완료하고 Pre-operational 상태에 진입한 것으로 판단할 수 있습니다.
8.2 네트워크 시작
초기화가 완료되면 Host Controller는 NMT(Network Management) 명령을 이용하여 장치를 Operational 상태로 전환합니다.
일반적인 상태 전이는 다음과 같습니다.
Power ON
│
▼
Initialization
│
▼
Pre-operational
│
│ NMT Start
▼
Operational
Operational 상태에서는 PDO를 이용한 실시간 데이터 교환이 가능합니다.
8.3 파라미터 설정
실시간 제어를 시작하기 전에 필요한 운전 파라미터를 설정합니다.
일반적으로 다음 항목을 설정합니다.
설정 항목 |
통신 방식 |
|---|---|
Operation Mode |
SDO |
Motion Parameter |
SDO |
PDO Mapping |
SDO |
Heartbeat Time |
SDO |
제조사 전용 설정 |
SDO |
초기 설정은 Pre-operational 상태에서 수행하는 것을 권장합니다.
8.4 실시간 제어
장치가 Operational 상태가 되면 PDO를 이용하여 실시간 제어를 수행합니다.
일반적인 제어 순서는 다음과 같습니다.
Host Controller
│
├─ RPDO
│ Target Position
│ Target Velocity
│ Controlword
│
▼
SF시리즈
│
├─ Motion Control
│
├─ TPDO
│ Statusword
│ Actual Position
│ Actual Velocity
│
▼
Host Controller
Host Controller는 TPDO를 이용하여 현재 상태를 지속적으로 확인하며, 필요한 경우 새로운 제어 명령을 전송합니다.
8.5 상태 모니터링
실시간 운전 중에는 장치의 상태를 지속적으로 확인해야 합니다.
권장 모니터링 항목은 다음과 같습니다.
항목 |
목적 |
|---|---|
Statusword |
현재 운전 상태 확인 |
Actual Position |
위치 확인 |
Actual Velocity |
속도 확인 |
Actual Torque |
토크 확인 |
Heartbeat |
통신 상태 확인 |
EMCY |
오류 발생 확인 |
Heartbeat가 일정 시간 이상 수신되지 않으면 통신 이상으로 판단하고 적절한 복구 절차를 수행해야 합니다.
8.6 오류 처리
장치 내부에서 오류가 발생하면 EMCY(Emergency Message)를 전송합니다.
Host Controller는 EMCY를 수신하면 다음 순서로 처리하는 것을 권장합니다.
EMCY 수신
Error Code 확인
Statusword 확인
Motion 정지
오류 원인 제거
Fault Reset 수행
Enable Operation 재실행
오류가 제거되지 않은 상태에서는 장치가 Fault 상태를 유지하며, 새로운 제어 명령은 실행되지 않습니다.
8.7 권장 통신 순서
누리로봇 SF시리즈 CANopen 시스템의 권장 통신 순서는 다음과 같습니다.
Power ON
│
▼
Boot-up 확인
│
▼
NMT Start
│
▼
SDO Parameter Setting
│
▼
Enable Operation
│
▼
PDO Motion Control
│
▼
TPDO Feedback
│
▼
Heartbeat Monitoring
│
├───────────────┐
│ │
정상 운전 EMCY 발생
│ │
▼ ▼
계속 운전 Fault Reset
│
▼
Enable Operation
이 순서를 따르면 초기 설정, 실시간 제어 및 오류 복구를 일관된 절차로 수행할 수 있습니다.
8.8 통신 처리 시 권장 사항
안정적인 CANopen 통신을 위해 다음 사항을 권장합니다.
Boot-up 메시지를 수신한 후 NMT Start 명령을 전송합니다.
초기 파라미터 설정은 SDO를 이용하여 수행합니다.
실시간 제어는 PDO를 사용하고, 반복적인 SDO 접근은 최소화합니다.
Statusword와 Heartbeat를 지속적으로 모니터링합니다.
EMCY를 수신하면 즉시 오류 원인을 확인하고 적절한 복구 절차를 수행합니다.
통신 오류 또는 Heartbeat Timeout이 발생하면 네트워크 상태와 배선을 점검한 후 재초기화를 수행합니다.
중요
CANopen 시스템의 안정성은 NMT 상태 관리, SDO를 이용한 초기 설정, PDO 기반의 실시간 제어, Heartbeat를 이용한 통신 감시, EMCY 기반의 오류 처리를 올바르게 조합하여 운용하는 것에 달려 있습니다. Host Controller는 각 통신 객체의 특성을 고려하여 제어 로직을 구현하는 것을 권장합니다.
9. 예제 (Examples)
본 장에서는 Host Controller에서 누리로봇 SF시리즈를 CANopen으로 제어하기 위한 기본 예제를 제공합니다.
예제는 다음 절차를 기준으로 작성되었습니다.
NMT Start 명령 전송
Operation Mode 설정
Controlword 설정
Target Position 전송
Statusword 읽기
참고
아래 예제의 Node ID는 1을 기준으로 작성되었습니다. 실제 사용
시에는 장치에 설정된 Node ID에 맞게 COB-ID를 변경하십시오.
9.1 기본 COB-ID
Node ID가 1인 경우 주요 COB-ID는 다음과 같습니다.
항목 |
COB-ID |
|---|---|
NMT |
0x000 |
SDO Request |
0x601 |
SDO Response |
0x581 |
TPDO1 |
0x181 |
RPDO1 |
0x201 |
Heartbeat |
0x701 |
EMCY |
0x081 |
9.2 Python 예제
다음 예제는 python-can 라이브러리를 사용하여 CANopen SDO 명령을
전송하는 기본 코드입니다.
import can
import time
NODE_ID = 1
COB_NMT = 0x000
COB_SDO_TX = 0x600 + NODE_ID # Host -> SF시리즈
COB_SDO_RX = 0x580 + NODE_ID # SF시리즈 -> Host
def send_can(bus, cob_id, data):
msg = can.Message(
arbitration_id=cob_id,
data=data,
is_extended_id=False
)
bus.send(msg)
def read_response(bus, timeout=1.0):
msg = bus.recv(timeout)
if msg is None:
print("No response")
return None
print(f"RX COB-ID: 0x{msg.arbitration_id:03X}, Data: {msg.data.hex(' ').upper()}")
return msg
def sdo_write_8(bus, index, sub_index, value):
data = [
0x2F,
index & 0xFF,
(index >> 8) & 0xFF,
sub_index,
value & 0xFF,
0x00,
0x00,
0x00
]
send_can(bus, COB_SDO_TX, data)
return read_response(bus)
def sdo_write_16(bus, index, sub_index, value):
data = [
0x2B,
index & 0xFF,
(index >> 8) & 0xFF,
sub_index,
value & 0xFF,
(value >> 8) & 0xFF,
0x00,
0x00
]
send_can(bus, COB_SDO_TX, data)
return read_response(bus)
def sdo_write_32(bus, index, sub_index, value):
data = [
0x23,
index & 0xFF,
(index >> 8) & 0xFF,
sub_index,
value & 0xFF,
(value >> 8) & 0xFF,
(value >> 16) & 0xFF,
(value >> 24) & 0xFF
]
send_can(bus, COB_SDO_TX, data)
return read_response(bus)
def sdo_read(bus, index, sub_index):
data = [
0x40,
index & 0xFF,
(index >> 8) & 0xFF,
sub_index,
0x00, 0x00, 0x00, 0x00
]
send_can(bus, COB_SDO_TX, data)
return read_response(bus)
def nmt_start(bus):
# Byte0: Command, Byte1: Node ID
# 0x01 = Start Remote Node
send_can(bus, COB_NMT, [0x01, NODE_ID])
def main():
bus = can.interface.Bus(
channel="can0",
bustype="socketcan",
bitrate=1000000
)
print("NMT Start")
nmt_start(bus)
time.sleep(0.1)
print("Set Operation Mode: Profile Position Mode")
sdo_write_8(bus, 0x6060, 0x00, 0x01)
print("Shutdown")
sdo_write_16(bus, 0x6040, 0x00, 0x0006)
print("Switch On")
sdo_write_16(bus, 0x6040, 0x00, 0x0007)
print("Enable Operation")
sdo_write_16(bus, 0x6040, 0x00, 0x000F)
print("Set Target Position")
sdo_write_32(bus, 0x607A, 0x00, 5566)
print("Start Motion")
sdo_write_16(bus, 0x6040, 0x00, 0x003F)
print("Read Statusword")
sdo_read(bus, 0x6041, 0x00)
if __name__ == "__main__":
main()
9.3 Python PDO 송신 예제
다음 예제는 RPDO1을 이용하여 Controlword와 Target Position을 전송하는 예입니다.
import can
import struct
import time
NODE_ID = 1
COB_RPDO1 = 0x200 + NODE_ID
bus = can.interface.Bus(
channel="can0",
bustype="socketcan",
bitrate=1000000
)
controlword = 0x000F
target_position = 10000
# Little-Endian:
# Controlword: UINT16
# Target Position: INT32
data = struct.pack("<Hi", controlword, target_position)
# PDO Data Field는 최대 8 Byte이므로 남은 Byte는 0으로 채움
data = data + bytes(8 - len(data))
msg = can.Message(
arbitration_id=COB_RPDO1,
data=data,
is_extended_id=False
)
bus.send(msg)
print(f"TX RPDO1: COB-ID=0x{COB_RPDO1:03X}, Data={data.hex(' ').upper()}")
참고
PDO 데이터 배치는 실제 PDO Mapping 설정에 따라 달라질 수 있습니다. 위 예제는 Controlword와 Target Position이 RPDO1에 매핑되어 있다는 가정 하에 작성되었습니다.
9.4 C 예제
다음 예제는 Linux SocketCAN 환경에서 SDO Write 명령을 전송하는 기본 코드입니다.
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#define NODE_ID 1
#define COB_NMT 0x000
#define COB_SDO_TX (0x600 + NODE_ID)
#define COB_SDO_RX (0x580 + NODE_ID)
int open_can_socket(const char *ifname)
{
int s;
struct sockaddr_can addr;
struct ifreq ifr;
s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (s < 0) {
perror("socket");
return -1;
}
strcpy(ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
close(s);
return -1;
}
return s;
}
void send_frame(int s, uint16_t cob_id, uint8_t *data, uint8_t dlc)
{
struct can_frame frame;
frame.can_id = cob_id;
frame.can_dlc = dlc;
memcpy(frame.data, data, dlc);
if (write(s, &frame, sizeof(struct can_frame)) != sizeof(struct can_frame)) {
perror("write");
}
}
void nmt_start(int s)
{
uint8_t data[2] = {0x01, NODE_ID};
send_frame(s, COB_NMT, data, 2);
}
void sdo_write_8(int s, uint16_t index, uint8_t sub_index, uint8_t value)
{
uint8_t data[8] = {
0x2F,
index & 0xFF,
(index >> 8) & 0xFF,
sub_index,
value,
0x00,
0x00,
0x00
};
send_frame(s, COB_SDO_TX, data, 8);
}
void sdo_write_16(int s, uint16_t index, uint8_t sub_index, uint16_t value)
{
uint8_t data[8] = {
0x2B,
index & 0xFF,
(index >> 8) & 0xFF,
sub_index,
value & 0xFF,
(value >> 8) & 0xFF,
0x00,
0x00
};
send_frame(s, COB_SDO_TX, data, 8);
}
void sdo_write_32(int s, uint16_t index, uint8_t sub_index, uint32_t value)
{
uint8_t data[8] = {
0x23,
index & 0xFF,
(index >> 8) & 0xFF,
sub_index,
value & 0xFF,
(value >> 8) & 0xFF,
(value >> 16) & 0xFF,
(value >> 24) & 0xFF
};
send_frame(s, COB_SDO_TX, data, 8);
}
void sdo_read(int s, uint16_t index, uint8_t sub_index)
{
uint8_t data[8] = {
0x40,
index & 0xFF,
(index >> 8) & 0xFF,
sub_index,
0x00,
0x00,
0x00,
0x00
};
send_frame(s, COB_SDO_TX, data, 8);
}
int main(void)
{
int s = open_can_socket("can0");
if (s < 0) {
return 1;
}
printf("NMT Start\n");
nmt_start(s);
usleep(100000);
printf("Set Operation Mode: Profile Position Mode\n");
sdo_write_8(s, 0x6060, 0x00, 0x01);
usleep(100000);
printf("Shutdown\n");
sdo_write_16(s, 0x6040, 0x00, 0x0006);
usleep(100000);
printf("Switch On\n");
sdo_write_16(s, 0x6040, 0x00, 0x0007);
usleep(100000);
printf("Enable Operation\n");
sdo_write_16(s, 0x6040, 0x00, 0x000F);
usleep(100000);
printf("Set Target Position\n");
sdo_write_32(s, 0x607A, 0x00, 5566);
usleep(100000);
printf("Start Motion\n");
sdo_write_16(s, 0x6040, 0x00, 0x003F);
usleep(100000);
printf("Read Statusword\n");
sdo_read(s, 0x6041, 0x00);
close(s);
return 0;
}
9.5 C PDO 송신 예제
다음 예제는 RPDO1을 이용하여 Controlword와 Target Position을 전송하는 코드입니다.
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#define NODE_ID 1
#define COB_RPDO1 (0x200 + NODE_ID)
int main(void)
{
int s;
struct sockaddr_can addr;
struct ifreq ifr;
struct can_frame frame;
s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
strcpy(ifr.ifr_name, "can0");
ioctl(s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
bind(s, (struct sockaddr *)&addr, sizeof(addr));
uint16_t controlword = 0x000F;
int32_t target_position = 10000;
frame.can_id = COB_RPDO1;
frame.can_dlc = 8;
frame.data[0] = controlword & 0xFF;
frame.data[1] = (controlword >> 8) & 0xFF;
frame.data[2] = target_position & 0xFF;
frame.data[3] = (target_position >> 8) & 0xFF;
frame.data[4] = (target_position >> 16) & 0xFF;
frame.data[5] = (target_position >> 24) & 0xFF;
frame.data[6] = 0x00;
frame.data[7] = 0x00;
write(s, &frame, sizeof(struct can_frame));
printf("TX RPDO1: COB-ID=0x%03X\n", COB_RPDO1);
close(s);
return 0;
}
9.6 실행 전 확인 사항
예제 코드를 실행하기 전에 다음 사항을 확인하십시오.
항목 |
확인 내용 |
|---|---|
CAN Interface |
|
Baud Rate |
SF시리즈와 Host Controller의 Baud Rate가 동일한지 확인 |
Node ID |
코드의 Node ID와 장치 Node ID가 일치하는지 확인 |
Termination |
CAN Bus 양 끝단에 120 Ω 종단 저항 설치 |
Power |
SF시리즈 전원이 정상적으로 공급되는지 확인 |
Safety |
무부하 상태에서 먼저 테스트 수행 |
Linux SocketCAN 환경에서는 다음과 같이 CAN Interface를 설정할 수 있습니다.
sudo ip link set can0 down
sudo ip link set can0 type can bitrate 1000000
sudo ip link set can0 up
CAN 메시지를 모니터링하려면 다음 명령을 사용할 수 있습니다.
candump can0
경고
예제 코드는 통신 방법을 설명하기 위한 참고용 코드입니다. 실제 장비에 적용하기 전에는 반드시 무부하 상태에서 테스트하고, 위치 제한, 속도 제한 및 전류 제한을 설정한 후 사용하십시오.
9.7 Python CANopen 통합 예제
다음 예제는 Python canopen 모듈을 사용하여 누리로봇 SF시리즈를
제어하는 통합 예제입니다.
본 예제에는 다음 CANopen 기능이 포함되어 있습니다.
CANopen Network 연결
Node 등록
NMT Reset / Pre-operational / Operational 제어
Boot-up 및 Heartbeat 확인
EMCY 수신 처리
SDO Read / Write
SDO Abort Code 예외 처리
CiA 402 Statusword 해석
Fault Reset
Operation Mode 설정
Servo Enable Sequence
Target Position 제어
PDO Mapping 설정
RPDO 송신
TPDO 수신
Little-Endian 데이터 처리
경고
본 코드는 통신 및 제어 절차 설명용 예제입니다. 실제 장비에 적용하기 전에는 반드시 무부하 상태에서 테스트하고, 위치 제한, 속도 제한, 토크 제한 및 비상 정지 회로를 확인하십시오.
다운로드
중요
CANOpen EDS(Electronic Data Sheet)는 CANOpen 장치의 객체 사전(Object Dictionary)에 대한 정보를 기술하는 표준화된 텍스트 파일입니다. 이 파일을 통해 SF 시리즈의 장치의 기능과 구성 가능한 매개변수를 정의하고 관리할 수 있습니다.
설치
pip install canopen python-can
Linux SocketCAN을 사용하는 경우 CAN Interface를 다음과 같이 설정합니다.
sudo ip link set can0 down
sudo ip link set can0 type can bitrate 1000000
sudo ip link set can0 up
실행 예시는 다음과 같습니다.
python canopen_master.py \
--interface socketcan \
--channel can0 \
--bitrate 1000000 \
--node-id 1 \
--heartbeat-ms 1000 \
--eds sf.eds \
--run-motion \
--target-position 5566
PDO Mapping까지 설정하려면 다음 옵션을 추가합니다.
--configure-pdo --use-pdo-motion
Python Code
#!/usr/bin/env python3
"""
SF시리즈 CANopen Master Example
이 예제는 Python canopen 모듈을 사용하여 SF시리즈를 제어하는 CANopen Master 예제이다.
포함 기능:
- NMT 제어
- Boot-up / Heartbeat 확인
- EMCY 수신
- SDO Read / Write
- SDO Abort 처리
- CiA402 State Machine 처리
- Fault Reset
- Operation Mode 설정
- Servo Enable
- Profile Position 제어
- PDO Mapping 설정
- RPDO 송신
- TPDO 수신
주의:
- 실제 장비 운전 전에는 반드시 무부하 상태에서 시험할 것
- 위치 제한, 속도 제한, 전류 제한, 토크 제한을 먼저 설정할 것
- EDS 파일은 실제 사용하는 SF시리즈 모델과 펌웨어에 맞는 파일을 사용할 것
"""
from __future__ import annotations
import argparse
import logging
import signal
import struct
import sys
import time
from dataclasses import dataclass
from typing import Callable, Optional
import canopen
# ---------------------------------------------------------------------------
# CANopen Object Index
# ---------------------------------------------------------------------------
OBJ_ERROR_REGISTER = 0x1001
OBJ_STORE_PARAMETERS = 0x1010
OBJ_RESTORE_PARAMETERS = 0x1011
OBJ_PRODUCER_HEARTBEAT_TIME = 0x1017
OBJ_ERROR_CODE = 0x603F
OBJ_CONTROLWORD = 0x6040
OBJ_STATUSWORD = 0x6041
OBJ_MODES_OF_OPERATION = 0x6060
OBJ_MODES_OF_OPERATION_DISPLAY = 0x6061
OBJ_POSITION_ACTUAL_VALUE = 0x6064
OBJ_VELOCITY_ACTUAL_VALUE = 0x606C
OBJ_TARGET_TORQUE = 0x6071
OBJ_TORQUE_ACTUAL_VALUE = 0x6077
OBJ_TARGET_POSITION = 0x607A
OBJ_PROFILE_VELOCITY = 0x6081
OBJ_PROFILE_ACCELERATION = 0x6083
OBJ_PROFILE_DECELERATION = 0x6084
OBJ_TARGET_VELOCITY = 0x60FF
OBJ_WARNING_CODE = 0x3B68
OBJ_TORQUE_SENSOR = 0x3B69
# ---------------------------------------------------------------------------
# CiA402 Controlword
# ---------------------------------------------------------------------------
CW_DISABLE_VOLTAGE = 0x0000
CW_SHUTDOWN = 0x0006
CW_SWITCH_ON = 0x0007
CW_ENABLE_OPERATION = 0x000F
CW_QUICK_STOP = 0x0002
CW_FAULT_RESET = 0x0080
# Profile Position Mode에서 New Set-point 실행용 예시
CW_PP_START_ABS_IMMEDIATE = 0x003F
# ---------------------------------------------------------------------------
# CiA402 Operation Mode
# ---------------------------------------------------------------------------
MODE_PROFILE_POSITION = 0x01
MODE_PROFILE_VELOCITY = 0x03
MODE_PROFILE_TORQUE = 0x04
MODE_HOMING = 0x06
MODE_CSP = 0x08
MODE_CSV = 0x09
MODE_CST = 0x0A
# ---------------------------------------------------------------------------
# NMT State
# ---------------------------------------------------------------------------
NMT_STATE_NAME = {
0x00: "BOOT-UP / INITIALISING",
0x04: "STOPPED",
0x05: "OPERATIONAL",
0x7F: "PRE-OPERATIONAL",
}
# ---------------------------------------------------------------------------
# SDO Abort Code
# ---------------------------------------------------------------------------
SDO_ABORT_CODE = {
0x00000000: "No abort",
0x05030000: "Toggle bit not alternated",
0x05040000: "SDO protocol timeout",
0x05040001: "Client/server command specifier not valid or unknown",
0x05040004: "CRC error",
0x06010000: "Unsupported access to an object",
0x06010001: "Attempt to read a write only object",
0x06010002: "Attempt to write a read only object",
0x06010003: "Sub-index cannot be written",
0x06010004: "SDO complete access not supported",
0x06020000: "Object does not exist in object dictionary",
0x06040041: "Object cannot be mapped to PDO",
0x06040042: "Number and length of objects exceed PDO length",
0x06040043: "General parameter incompatibility",
0x06040047: "General internal incompatibility",
0x06060000: "Access failed due to hardware error",
0x06070010: "Data type or length does not match",
0x06070013: "Data type does not match, parameter too short",
0x06090011: "Sub-index does not exist",
0x06090030: "Value range exceeded",
0x08000000: "General error",
0x08000020: "Data cannot be transferred or stored",
0x08000022: "Data cannot be transferred or stored because of device state",
0x0F00FFBE: "Password error",
0x0F00FFBF: "Illegal command code",
0x0F00FFC0: "Wrong NMT state",
}
# ---------------------------------------------------------------------------
# Helper Functions
# ---------------------------------------------------------------------------
def abort_message(code: int) -> str:
return SDO_ABORT_CODE.get(code, "Unknown SDO abort code")
def pack_int(value: int, size: int, signed: bool = False) -> bytes:
"""
CANopen SDO Download용 Little-Endian 정수 변환.
size는 1, 2, 4 Byte 중 하나를 사용한다.
"""
if size not in (1, 2, 4):
raise ValueError("SDO expedited transfer size must be 1, 2, or 4 bytes")
return int(value).to_bytes(size, byteorder="little", signed=signed)
def unpack_int(data: bytes, size: Optional[int] = None, signed: bool = False) -> int:
"""
CANopen SDO Upload 또는 PDO Data용 Little-Endian 정수 변환.
"""
if size is None:
size = len(data)
if size not in (1, 2, 4):
raise ValueError("Unsupported integer size")
raw = bytes(data[:size])
return int.from_bytes(raw, byteorder="little", signed=signed)
def pdo_mapping_entry(index: int, sub_index: int, bit_length: int) -> int:
"""
PDO Mapping Entry 생성.
Mapping Entry = (Index << 16) | (Sub-index << 8) | Bit Length
"""
return ((index & 0xFFFF) << 16) | ((sub_index & 0xFF) << 8) | (bit_length & 0xFF)
def decode_pds_state(statusword: int) -> str:
"""
CiA402 Statusword를 PDS FSA 상태로 해석한다.
"""
if (statusword & 0x004F) == 0x0000:
return "Not Ready to Switch On"
if (statusword & 0x004F) == 0x0040:
return "Switch On Disabled"
if (statusword & 0x006F) == 0x0021:
return "Ready to Switch On"
if (statusword & 0x006F) == 0x0023:
return "Switched On"
if (statusword & 0x006F) == 0x0027:
return "Operation Enabled"
if (statusword & 0x006F) == 0x0007:
return "Quick Stop Active"
if (statusword & 0x004F) == 0x000F:
return "Fault Reaction Active"
if (statusword & 0x004F) == 0x0008:
return "Fault"
return "Unknown"
def is_fault(statusword: int) -> bool:
return bool(statusword & 0x0008)
def is_operation_enabled(statusword: int) -> bool:
return (statusword & 0x006F) == 0x0027
# ---------------------------------------------------------------------------
# Configuration
# ---------------------------------------------------------------------------
@dataclass
class SFCanopenConfig:
interface: str
channel: str
bitrate: int
node_id: int
eds: Optional[str]
heartbeat_ms: int
sdo_timeout: float
reset_communication: bool
configure_pdo: bool
run_motion: bool
use_pdo_motion: bool
target_position: int
profile_velocity: int
profile_acceleration: int
profile_deceleration: int
# ---------------------------------------------------------------------------
# SF시리즈 CANopen Master
# ---------------------------------------------------------------------------
class SFCanopenMaster:
def __init__(self, cfg: SFCanopenConfig):
self.cfg = cfg
self.network = canopen.Network()
self.node = None
self.running = True
self.last_tpdo1_timestamp: Optional[float] = None
self.last_statusword: Optional[int] = None
self.last_actual_position: Optional[int] = None
self.last_mode_display: Optional[int] = None
# -----------------------------------------------------------------------
# Network
# -----------------------------------------------------------------------
def connect(self) -> None:
logging.info(
"CANopen connect: interface=%s channel=%s bitrate=%d",
self.cfg.interface,
self.cfg.channel,
self.cfg.bitrate,
)
self.network.connect(
interface=self.cfg.interface,
channel=self.cfg.channel,
bitrate=self.cfg.bitrate,
)
if self.cfg.eds:
logging.info("Add node %d with EDS: %s", self.cfg.node_id, self.cfg.eds)
self.node = self.network.add_node(self.cfg.node_id, self.cfg.eds)
else:
logging.info("Add node %d without EDS", self.cfg.node_id)
self.node = self.network.add_node(self.cfg.node_id)
self.node.nmt.add_heartbeat_callback(self.on_heartbeat)
self.node.emcy.add_callback(self.on_emcy)
self.subscribe_raw_tpdo1()
def disconnect(self) -> None:
logging.info("Disconnect CANopen network")
try:
if self.node is not None:
self.node.rpdo.stop()
self.node.tpdo.stop()
except Exception:
pass
try:
self.network.disconnect()
except Exception:
pass
# -----------------------------------------------------------------------
# Callback
# -----------------------------------------------------------------------
def on_heartbeat(self, state: int) -> None:
name = NMT_STATE_NAME.get(state, f"UNKNOWN(0x{state:02X})")
logging.info("Heartbeat: state=0x%02X %s", state, name)
def on_emcy(self, emcy_error) -> None:
"""
canopen.emcy.EmcyError callback.
"""
code = getattr(emcy_error, "code", None)
register = getattr(emcy_error, "register", None)
data = getattr(emcy_error, "data", b"")
logging.error(
"EMCY received: code=0x%04X register=0x%02X data=%s",
code if code is not None else 0,
register if register is not None else 0,
bytes(data).hex(" ").upper() if data else "",
)
def subscribe_raw_tpdo1(self) -> None:
"""
Default TPDO1 수신 예시.
본 예제에서는 TPDO1 Mapping이 다음과 같다고 가정한다.
- 0x6041:00 Statusword, 16 bit
- 0x6064:00 Position Actual Value, 32 bit
- 0x6061:00 Modes of Operation Display, 8 bit
"""
cob_id = 0x180 + self.cfg.node_id
self.network.subscribe(cob_id, self.on_raw_tpdo1)
logging.info("Subscribe TPDO1: COB-ID=0x%03X", cob_id)
def on_raw_tpdo1(self, can_id: int, data: bytearray, timestamp: float) -> None:
raw = bytes(data)
if len(raw) < 7:
logging.warning("TPDO1 length is too short: %d", len(raw))
return
statusword = struct.unpack_from("<H", raw, 0)[0]
actual_position = struct.unpack_from("<i", raw, 2)[0]
mode_display = struct.unpack_from("<b", raw, 6)[0]
self.last_tpdo1_timestamp = timestamp
self.last_statusword = statusword
self.last_actual_position = actual_position
self.last_mode_display = mode_display
logging.info(
"TPDO1: statusword=0x%04X state=%s position=%d mode=%d",
statusword,
decode_pds_state(statusword),
actual_position,
mode_display,
)
# -----------------------------------------------------------------------
# NMT
# -----------------------------------------------------------------------
def wait_bootup(self, timeout: float = 10.0) -> bool:
try:
self.node.nmt.wait_for_bootup(timeout=timeout)
logging.info("Boot-up message received")
return True
except Exception as exc:
logging.warning("Boot-up wait timeout or failed: %s", exc)
return False
def wait_heartbeat(self, timeout: float = 3.0) -> bool:
try:
self.node.nmt.wait_for_heartbeat(timeout=timeout)
logging.info("Heartbeat received: current NMT state=%s", self.node.nmt.state)
return True
except Exception as exc:
logging.warning("Heartbeat wait timeout or failed: %s", exc)
return False
def reset_communication(self) -> None:
logging.info("NMT Reset Communication")
self.node.nmt.send_command(0x82)
self.wait_bootup(timeout=10.0)
def set_pre_operational(self) -> None:
logging.info("NMT -> PRE-OPERATIONAL")
self.node.nmt.state = "PRE-OPERATIONAL"
self.wait_heartbeat(timeout=2.0)
def set_operational(self) -> None:
logging.info("NMT -> OPERATIONAL")
self.node.nmt.state = "OPERATIONAL"
self.wait_heartbeat(timeout=2.0)
def set_stopped(self) -> None:
logging.info("NMT -> STOPPED")
self.node.nmt.state = "STOPPED"
self.wait_heartbeat(timeout=2.0)
# -----------------------------------------------------------------------
# SDO
# -----------------------------------------------------------------------
def sdo_read_int(self, index: int, sub_index: int, size: int, signed: bool = False) -> int:
try:
data = self.node.sdo.upload(index, sub_index)
value = unpack_int(data, size=size, signed=signed)
logging.debug(
"SDO read 0x%04X:%02X = %d raw=%s",
index,
sub_index,
value,
bytes(data).hex(" ").upper(),
)
return value
except canopen.SdoAbortedError as exc:
logging.error(
"SDO abort on read 0x%04X:%02X code=0x%08X %s",
index,
sub_index,
exc.code,
abort_message(exc.code),
)
raise
except canopen.SdoCommunicationError as exc:
logging.error(
"SDO communication error on read 0x%04X:%02X: %s",
index,
sub_index,
exc,
)
raise
def sdo_write_int(
self,
index: int,
sub_index: int,
value: int,
size: int,
signed: bool = False,
) -> None:
try:
data = pack_int(value, size=size, signed=signed)
logging.debug(
"SDO write 0x%04X:%02X = %d raw=%s",
index,
sub_index,
value,
data.hex(" ").upper(),
)
self.node.sdo.download(index, sub_index, data)
except canopen.SdoAbortedError as exc:
logging.error(
"SDO abort on write 0x%04X:%02X value=%d code=0x%08X %s",
index,
sub_index,
value,
exc.code,
abort_message(exc.code),
)
raise
except canopen.SdoCommunicationError as exc:
logging.error(
"SDO communication error on write 0x%04X:%02X: %s",
index,
sub_index,
exc,
)
raise
def try_sdo_write_int(
self,
index: int,
sub_index: int,
value: int,
size: int,
signed: bool = False,
description: str = "",
) -> bool:
try:
self.sdo_write_int(index, sub_index, value, size, signed)
return True
except Exception as exc:
logging.warning(
"Optional SDO write failed: %s 0x%04X:%02X value=%s error=%s",
description,
index,
sub_index,
value,
exc,
)
return False
# -----------------------------------------------------------------------
# Device Information / Monitoring
# -----------------------------------------------------------------------
def check_sdo_communication(self) -> None:
"""
Object 0x1000 Device Type을 읽어 SDO 통신 가능 여부를 확인한다.
"""
try:
device_type = self.sdo_read_int(0x1000, 0x00, size=4, signed=False)
logging.info("Device Type: 0x%08X", device_type)
except Exception:
logging.warning("Device Type read failed. Check Node ID, Baud Rate, wiring, and power.")
raise
def configure_heartbeat(self, producer_time_ms: int) -> None:
"""
Producer Heartbeat Time 설정.
0이면 Heartbeat 비활성화일 수 있으므로, Master에서는 0보다 큰 값을 권장한다.
"""
if producer_time_ms <= 0:
logging.info("Producer heartbeat time is not changed")
return
logging.info("Set Producer Heartbeat Time: %d ms", producer_time_ms)
self.sdo_write_int(
OBJ_PRODUCER_HEARTBEAT_TIME,
0x00,
producer_time_ms,
size=2,
signed=False,
)
def read_error_status(self) -> None:
try:
error_register = self.sdo_read_int(OBJ_ERROR_REGISTER, 0x00, size=1, signed=False)
error_code = self.sdo_read_int(OBJ_ERROR_CODE, 0x00, size=2, signed=False)
logging.info(
"Error Register=0x%02X, Error Code=0x%04X",
error_register,
error_code,
)
except Exception as exc:
logging.warning("Read error status failed: %s", exc)
# -----------------------------------------------------------------------
# CiA402 State Machine
# -----------------------------------------------------------------------
def read_statusword(self) -> int:
statusword = self.sdo_read_int(OBJ_STATUSWORD, 0x00, size=2, signed=False)
logging.info("Statusword=0x%04X state=%s", statusword, decode_pds_state(statusword))
return statusword
def write_controlword(self, value: int) -> None:
logging.info("Controlword=0x%04X", value)
self.sdo_write_int(OBJ_CONTROLWORD, 0x00, value, size=2, signed=False)
def wait_pds_state(self, expected: str, timeout: float = 5.0) -> bool:
deadline = time.time() + timeout
while time.time() < deadline:
statusword = self.read_statusword()
state = decode_pds_state(statusword)
if state == expected:
logging.info("PDS state reached: %s", expected)
return True
time.sleep(0.05)
logging.warning("PDS state timeout: expected=%s", expected)
return False
def fault_reset_if_needed(self) -> None:
statusword = self.read_statusword()
if not is_fault(statusword):
return
logging.warning("Fault state detected")
self.read_error_status()
logging.info("Fault Reset")
self.write_controlword(CW_FAULT_RESET)
time.sleep(0.2)
statusword = self.read_statusword()
if is_fault(statusword):
raise RuntimeError("Fault Reset failed. Remove the error cause before retrying.")
def set_operation_mode(self, mode: int) -> None:
"""
0x6060 Modes of Operation을 설정하고 0x6061에서 적용 상태를 확인한다.
"""
logging.info("Set Modes of Operation: %d", mode)
self.sdo_write_int(
OBJ_MODES_OF_OPERATION,
0x00,
mode,
size=1,
signed=True,
)
deadline = time.time() + 3.0
while time.time() < deadline:
try:
display = self.sdo_read_int(
OBJ_MODES_OF_OPERATION_DISPLAY,
0x00,
size=1,
signed=True,
)
logging.info("Modes of Operation Display: %d", display)
if display == mode:
return
except Exception:
pass
time.sleep(0.05)
logging.warning("Mode display did not match requested mode within timeout")
def servo_enable(self) -> None:
"""
CiA402 Servo Enable Sequence:
Shutdown -> Switch On -> Enable Operation
"""
self.fault_reset_if_needed()
self.write_controlword(CW_SHUTDOWN)
self.wait_pds_state("Ready to Switch On", timeout=3.0)
self.write_controlword(CW_SWITCH_ON)
self.wait_pds_state("Switched On", timeout=3.0)
self.write_controlword(CW_ENABLE_OPERATION)
if not self.wait_pds_state("Operation Enabled", timeout=3.0):
statusword = self.read_statusword()
raise RuntimeError(
f"Enable Operation failed. Statusword=0x{statusword:04X}, "
f"state={decode_pds_state(statusword)}"
)
def servo_disable(self) -> None:
logging.info("Servo Disable")
self.write_controlword(CW_DISABLE_VOLTAGE)
# -----------------------------------------------------------------------
# Motion
# -----------------------------------------------------------------------
def configure_profile_position_parameters(self) -> None:
logging.info("Configure Profile Position parameters")
if self.cfg.profile_velocity > 0:
self.sdo_write_int(
OBJ_PROFILE_VELOCITY,
0x00,
self.cfg.profile_velocity,
size=4,
signed=False,
)
if self.cfg.profile_acceleration > 0:
self.sdo_write_int(
OBJ_PROFILE_ACCELERATION,
0x00,
self.cfg.profile_acceleration,
size=4,
signed=False,
)
if self.cfg.profile_deceleration > 0:
self.sdo_write_int(
OBJ_PROFILE_DECELERATION,
0x00,
self.cfg.profile_deceleration,
size=4,
signed=False,
)
def move_profile_position_sdo(self, target_position: int) -> None:
"""
SDO 기반 Profile Position Mode 제어 예제.
"""
logging.info("Move Profile Position by SDO: target=%d", target_position)
self.set_operation_mode(MODE_PROFILE_POSITION)
self.configure_profile_position_parameters()
self.servo_enable()
self.sdo_write_int(
OBJ_TARGET_POSITION,
0x00,
target_position,
size=4,
signed=True,
)
self.write_controlword(CW_PP_START_ABS_IMMEDIATE)
self.monitor_motion(timeout=10.0)
def monitor_motion(self, timeout: float = 10.0) -> None:
"""
Statusword와 Actual Position을 SDO로 주기적으로 읽어 모션 상태를 확인한다.
"""
deadline = time.time() + timeout
while time.time() < deadline and self.running:
statusword = self.read_statusword()
state = decode_pds_state(statusword)
try:
position = self.sdo_read_int(
OBJ_POSITION_ACTUAL_VALUE,
0x00,
size=4,
signed=True,
)
except Exception:
position = None
logging.info(
"Motion monitor: state=%s statusword=0x%04X position=%s",
state,
statusword,
position,
)
if statusword & 0x0400:
logging.info("Target reached")
return
if is_fault(statusword):
self.read_error_status()
raise RuntimeError("Fault occurred during motion")
time.sleep(0.1)
logging.warning("Motion monitor timeout")
# -----------------------------------------------------------------------
# PDO Mapping
# -----------------------------------------------------------------------
def configure_default_pdo_mapping_raw(self) -> None:
"""
SDO Raw 방식으로 PDO Mapping을 설정한다.
RPDO1:
- 0x6040:00 Controlword, 16 bit
- 0x607A:00 Target Position, 32 bit
- 0x6060:00 Modes of Operation, 8 bit
TPDO1:
- 0x6041:00 Statusword, 16 bit
- 0x6064:00 Position Actual Value, 32 bit
- 0x6061:00 Modes of Operation Display, 8 bit
주의:
- PDO Mapping 변경은 Pre-operational 상태에서 수행한다.
- 일부 펌웨어 또는 EDS 설정에서는 동적 PDO Mapping이 제한될 수 있다.
"""
logging.info("Configure default PDO Mapping by raw SDO")
self.set_pre_operational()
node_id = self.cfg.node_id
rpdo1_cobid = 0x200 + node_id
tpdo1_cobid = 0x180 + node_id
# ---------------------------
# RPDO1 Communication
# ---------------------------
self.sdo_write_int(0x1400, 0x01, 0x80000000 | rpdo1_cobid, size=4, signed=False)
self.try_sdo_write_int(0x1400, 0x02, 255, size=1, signed=False, description="RPDO1 Transmission Type")
# ---------------------------
# RPDO1 Mapping
# ---------------------------
self.sdo_write_int(0x1600, 0x00, 0, size=1, signed=False)
self.sdo_write_int(
0x1600,
0x01,
pdo_mapping_entry(OBJ_CONTROLWORD, 0x00, 16),
size=4,
signed=False,
)
self.sdo_write_int(
0x1600,
0x02,
pdo_mapping_entry(OBJ_TARGET_POSITION, 0x00, 32),
size=4,
signed=False,
)
self.sdo_write_int(
0x1600,
0x03,
pdo_mapping_entry(OBJ_MODES_OF_OPERATION, 0x00, 8),
size=4,
signed=False,
)
self.sdo_write_int(0x1600, 0x00, 3, size=1, signed=False)
self.sdo_write_int(0x1400, 0x01, rpdo1_cobid, size=4, signed=False)
# ---------------------------
# TPDO1 Communication
# ---------------------------
self.sdo_write_int(0x1800, 0x01, 0x80000000 | tpdo1_cobid, size=4, signed=False)
self.try_sdo_write_int(0x1800, 0x02, 255, size=1, signed=False, description="TPDO1 Transmission Type")
self.try_sdo_write_int(0x1800, 0x05, 20, size=2, signed=False, description="TPDO1 Event Timer")
# ---------------------------
# TPDO1 Mapping
# ---------------------------
self.sdo_write_int(0x1A00, 0x00, 0, size=1, signed=False)
self.sdo_write_int(
0x1A00,
0x01,
pdo_mapping_entry(OBJ_STATUSWORD, 0x00, 16),
size=4,
signed=False,
)
self.sdo_write_int(
0x1A00,
0x02,
pdo_mapping_entry(OBJ_POSITION_ACTUAL_VALUE, 0x00, 32),
size=4,
signed=False,
)
self.sdo_write_int(
0x1A00,
0x03,
pdo_mapping_entry(OBJ_MODES_OF_OPERATION_DISPLAY, 0x00, 8),
size=4,
signed=False,
)
self.sdo_write_int(0x1A00, 0x00, 3, size=1, signed=False)
self.sdo_write_int(0x1800, 0x01, tpdo1_cobid, size=4, signed=False)
logging.info("PDO Mapping configured")
def configure_default_pdo_mapping_with_eds(self) -> None:
"""
EDS가 있는 경우 canopen 모듈의 PDO API를 사용하여 Mapping을 설정하는 예제.
EDS 파일에 Object Dictionary 항목이 정확히 정의되어 있어야 한다.
"""
if not self.cfg.eds:
raise RuntimeError("EDS file is required for high-level PDO Mapping API")
logging.info("Configure default PDO Mapping with EDS API")
self.set_pre_operational()
node_id = self.cfg.node_id
self.node.rpdo.read()
self.node.tpdo.read()
# RPDO1
rpdo1 = self.node.rpdo[1]
rpdo1.clear()
rpdo1.cob_id = 0x200 + node_id
rpdo1.trans_type = 255
rpdo1.add_variable(OBJ_CONTROLWORD, 0x00, 16)
rpdo1.add_variable(OBJ_TARGET_POSITION, 0x00, 32)
rpdo1.add_variable(OBJ_MODES_OF_OPERATION, 0x00, 8)
rpdo1.enabled = True
# TPDO1
tpdo1 = self.node.tpdo[1]
tpdo1.clear()
tpdo1.cob_id = 0x180 + node_id
tpdo1.trans_type = 255
tpdo1.event_timer = 20
tpdo1.add_variable(OBJ_STATUSWORD, 0x00, 16)
tpdo1.add_variable(OBJ_POSITION_ACTUAL_VALUE, 0x00, 32)
tpdo1.add_variable(OBJ_MODES_OF_OPERATION_DISPLAY, 0x00, 8)
tpdo1.enabled = True
self.node.rpdo.save()
self.node.tpdo.save()
logging.info("PDO Mapping configured by EDS API")
# -----------------------------------------------------------------------
# PDO Motion
# -----------------------------------------------------------------------
def send_rpdo1(self, controlword: int, target_position: int, mode: int) -> None:
"""
Default RPDO1 Mapping 기준 송신 예제.
Mapping:
Byte0~1 : Controlword, UINT16
Byte2~5 : Target Position, INT32
Byte6 : Modes of Operation, SINT
Byte7 : Reserved
"""
cob_id = 0x200 + self.cfg.node_id
data = struct.pack(
"<Hib",
controlword & 0xFFFF,
int(target_position),
int(mode),
)
data = data + bytes(8 - len(data))
self.network.send_message(cob_id, data)
logging.info(
"RPDO1 TX: COB-ID=0x%03X CW=0x%04X Target=%d Mode=%d Data=%s",
cob_id,
controlword,
target_position,
mode,
data.hex(" ").upper(),
)
def move_profile_position_pdo(self, target_position: int) -> None:
"""
RPDO1을 사용한 Profile Position Mode 제어 예제.
PDO Mapping이 본 예제와 동일하게 설정되어 있어야 한다.
"""
logging.info("Move Profile Position by RPDO1: target=%d", target_position)
self.set_operation_mode(MODE_PROFILE_POSITION)
self.configure_profile_position_parameters()
self.servo_enable()
# Enable 상태를 PDO로도 유지하면서 목표 위치를 전송
self.send_rpdo1(CW_ENABLE_OPERATION, target_position, MODE_PROFILE_POSITION)
time.sleep(0.05)
# New Set-point 실행
self.send_rpdo1(CW_PP_START_ABS_IMMEDIATE, target_position, MODE_PROFILE_POSITION)
deadline = time.time() + 10.0
while time.time() < deadline and self.running:
if self.last_statusword is not None:
if self.last_statusword & 0x0400:
logging.info("Target reached by TPDO1")
return
if is_fault(self.last_statusword):
self.read_error_status()
raise RuntimeError("Fault occurred during PDO motion")
time.sleep(0.05)
logging.warning("PDO motion timeout")
# -----------------------------------------------------------------------
# Main Sequence
# -----------------------------------------------------------------------
def run(self) -> None:
self.connect()
try:
if self.cfg.reset_communication:
self.reset_communication()
self.check_sdo_communication()
self.set_pre_operational()
self.configure_heartbeat(self.cfg.heartbeat_ms)
if self.cfg.configure_pdo:
if self.cfg.eds:
try:
self.configure_default_pdo_mapping_with_eds()
except Exception as exc:
logging.warning("EDS PDO API failed. Try raw SDO PDO mapping: %s", exc)
self.configure_default_pdo_mapping_raw()
else:
self.configure_default_pdo_mapping_raw()
self.set_operational()
self.fault_reset_if_needed()
if self.cfg.run_motion:
if self.cfg.use_pdo_motion:
self.move_profile_position_pdo(self.cfg.target_position)
else:
self.move_profile_position_sdo(self.cfg.target_position)
else:
logging.info("Motion command is disabled. Use --run-motion to execute motion.")
self.read_error_status()
finally:
try:
self.servo_disable()
except Exception as exc:
logging.warning("Servo disable failed: %s", exc)
self.disconnect()
def stop(self) -> None:
self.running = False
# ---------------------------------------------------------------------------
# Command Line
# ---------------------------------------------------------------------------
def parse_args() -> SFCanopenConfig:
parser = argparse.ArgumentParser(description="SF시리즈 CANopen Master Example")
parser.add_argument("--interface", default="socketcan", help="python-can interface type")
parser.add_argument("--channel", default="can0", help="CAN channel")
parser.add_argument("--bitrate", type=int, default=1000000, help="CAN bitrate")
parser.add_argument("--node-id", type=int, default=1, help="CANopen Node ID")
parser.add_argument("--eds", default=None, help="EDS file path")
parser.add_argument("--heartbeat-ms", type=int, default=1000, help="Producer heartbeat time in ms")
parser.add_argument("--sdo-timeout", type=float, default=1.0, help="SDO timeout in seconds")
parser.add_argument(
"--reset-communication",
action="store_true",
help="Send NMT Reset Communication before configuration",
)
parser.add_argument(
"--configure-pdo",
action="store_true",
help="Configure RPDO1 and TPDO1 mapping",
)
parser.add_argument(
"--run-motion",
action="store_true",
help="Execute profile position motion",
)
parser.add_argument(
"--use-pdo-motion",
action="store_true",
help="Use RPDO1 for target command after servo enable",
)
parser.add_argument("--target-position", type=int, default=5566, help="Target position")
parser.add_argument("--profile-velocity", type=int, default=10000, help="Profile velocity")
parser.add_argument("--profile-acceleration", type=int, default=10000, help="Profile acceleration")
parser.add_argument("--profile-deceleration", type=int, default=10000, help="Profile deceleration")
args = parser.parse_args()
if not (1 <= args.node_id <= 127):
raise ValueError("Node ID must be in range 1..127")
return SFCanopenConfig(
interface=args.interface,
channel=args.channel,
bitrate=args.bitrate,
node_id=args.node_id,
eds=args.eds,
heartbeat_ms=args.heartbeat_ms,
sdo_timeout=args.sdo_timeout,
reset_communication=args.reset_communication,
configure_pdo=args.configure_pdo,
run_motion=args.run_motion,
use_pdo_motion=args.use_pdo_motion,
target_position=args.target_position,
profile_velocity=args.profile_velocity,
profile_acceleration=args.profile_acceleration,
profile_deceleration=args.profile_deceleration,
)
def main() -> int:
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)-8s %(message)s",
)
cfg = parse_args()
master = SFCanopenMaster(cfg)
def signal_handler(signum, frame):
logging.warning("Signal received. Stop requested.")
master.stop()
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
try:
master.run()
return 0
except KeyboardInterrupt:
master.stop()
return 130
except Exception as exc:
logging.exception("CANopen example failed: %s", exc)
return 1
if __name__ == "__main__":
sys.exit(main())
코드 적용 시 확인 사항
항목 |
확인 내용 |
|---|---|
EDS 파일 |
실제 SF시리즈 모델 및 펌웨어 버전에 맞는 EDS 사용 |
Node ID |
코드의 |
Baud Rate |
코드의 |
CAN Interface |
|
PDO Mapping |
장치가 Dynamic PDO Mapping을 지원하는지 확인 |
Operation Mode |
사용할 모드가 장치에서 지원되는지 확인 |
Limit 설정 |
위치, 속도, 전류, 토크 제한값 확인 |
Safety |
무부하 상태에서 먼저 시험 |
실행 시 권장 순서
CAN Interface 활성화
SF시리즈 전원 인가
Boot-up 또는 Heartbeat 수신 확인
SDO Read로 Node 응답 확인
Pre-operational 상태에서 Heartbeat 및 PDO 설정
Operational 상태로 전환
Statusword 확인
Fault 상태이면 Fault Reset
Operation Mode 설정
Servo Enable
Motion Command 실행
TPDO, Statusword, EMCY 모니터링
중요
PDO Mapping을 변경하지 않고 --use-pdo-motion을 사용할 경우,
Master와 SF시리즈의 PDO Mapping이 일치하지 않아 잘못된 제어 데이터가
전달될 수 있습니다. PDO 기반 제어를 사용하기 전에 반드시 실제
Mapping을 확인하십시오.
10. 오류 처리 (Error Handling)
본 장에서는 SF시리즈 CANopen 통신 중 발생할 수 있는 오류의 종류, 오류 응답 형식 및 복구 절차를 설명합니다.
CANopen에서 오류는 크게 다음 세 가지로 구분됩니다.
구분 |
설명 |
|---|---|
SDO Abort Code |
SDO 요청 처리 실패 시 반환되는 통신 오류 |
EMCY Message |
장치 내부 오류 발생 시 비동기적으로 전송되는 긴급 메시지 |
Device Error Code |
SF시리즈 내부 상태 및 드라이브 오류 코드 |
Host Controller는 오류 발생 시 CAN 메시지의 종류와 Error Code를 확인한 후, 원인을 제거하고 복구 절차를 수행해야 합니다.
10.1 오류 처리 개요
SF시리즈에서 오류가 발생하면 다음 방식 중 하나로 Host Controller에 전달됩니다.
오류 전달 방식 |
설명 |
|---|---|
SDO Abort Response |
잘못된 SDO Read/Write 요청에 대한 응답 |
EMCY Message |
장치 내부 오류 발생 시 즉시 전송 |
Statusword |
CiA 402 상태 머신의 Fault 상태 표시 |
Error Code Object |
Object 0x603F를 통한 오류 코드 확인 |
Error Register |
Object 0x1001을 통한 오류 상태 확인 |
일반적으로 통신 오류는 SDO Abort Code로 확인하며, 장치 내부 오류는 EMCY Message 또는 Error Code로 확인합니다.
10.2 SDO Abort Code
SDO Abort Code는 Host Controller가 SDO 요청을 보냈을 때 SF시리즈가 해당 요청을 정상적으로 처리할 수 없는 경우 반환됩니다.
SDO Abort Response의 기본 형식은 다음과 같습니다.
Byte |
내용 |
|---|---|
Byte0 |
0x80 |
Byte1 |
Index Low Byte |
Byte2 |
Index High Byte |
Byte3 |
Sub-index |
Byte4~7 |
Abort Code |
Abort Code는 Little-Endian 형식으로 전송됩니다.
예를 들어 Abort Code가 0x06010002인 경우 데이터 영역은 다음과 같이
표시됩니다.
80 40 60 00 02 00 01 06
10.3 주요 SDO Abort Code
Abort Code |
이름 |
의미 |
|---|---|---|
0x00000000 |
No Abort |
통신 성공 |
0x05030000 |
Toggle Error |
Toggle bit가 변경되지 않음 |
0x05040000 |
SDO Timeout |
SDO 프로토콜 시간 초과 |
0x05040001 |
Command Unknown |
알 수 없는 Command Specifier |
0x05040004 |
CRC Error |
CRC 검증 실패 |
0x06010000 |
Access Error |
해당 Object 접근 불가 |
0x06010001 |
Write Only Error |
Write Only Object를 읽으려고 함 |
0x06010002 |
Read Only Error |
Read Only Object에 쓰려고 함 |
0x06010003 |
Sub-index Write Error |
Sub-index에 쓰기 불가 |
0x06010004 |
Complete Access Not Supported |
Complete Access 미지원 |
0x06020000 |
Object Does Not Exist |
Object Dictionary에 해당 Object 없음 |
0x06090011 |
Sub-index Does Not Exist |
해당 Sub-index 없음 |
0x06090030 |
Value Range Exceeded |
입력 값이 허용 범위를 초과 |
0x06090031 |
Value Too High |
입력 값이 너무 큼 |
0x06090032 |
Value Too Low |
입력 값이 너무 작음 |
0x08000000 |
General Error |
일반 오류 |
0x08000020 |
Data Cannot Be Transferred |
현재 상태에서 데이터 전송 불가 |
0x08000021 |
Local Control Error |
로컬 제어 상태로 인해 접근 불가 |
0x08000022 |
Device State Error |
현재 장치 상태에서 명령 수행 불가 |
10.4 EMCY 메시지
EMCY(Emergency Message)는 SF시리즈 내부에서 오류가 발생했을 때 즉시 전송되는 긴급 메시지입니다.
EMCY 메시지는 비동기적으로 발생하며, Host Controller의 요청과 관계없이 전송될 수 있습니다.
EMCY 메시지 형식은 다음과 같습니다.
COB-ID |
Byte0~1 |
Byte2 |
Byte3 |
Byte4~7 |
|---|---|---|---|---|
0x80 + Node ID |
Emergency Error Code |
Error Register |
Reserved |
0x00 |
예를 들어 Node ID가 1인 경우 EMCY COB-ID는 0x081입니다.
10.5 Error Register
Error Register(Object 0x1001)는 장치의 오류 상태를 나타냅니다.
Bit |
설명 |
|---|---|
Bit 0 |
Generic Error |
Bit 1 |
Current Error |
Bit 2 |
Voltage Error |
Bit 3 |
Temperature Error |
Bit 4 |
Communication Error |
Bit 5 |
Device Profile Specific Error |
Bit 6 |
Reserved |
Bit 7 |
Manufacturer Specific Error |
Host Controller는 EMCY 메시지를 수신한 후 Error Register를 확인하여 오류 유형을 판단할 수 있습니다.
10.6 Device Error Code
Device Error Code는 장치 내부 오류를 나타내며, Object 0x603F를
통해 확인할 수 있습니다.
대표적인 오류 유형은 다음과 같습니다.
오류 유형 |
설명 |
|---|---|
Over Voltage |
입력 전압이 허용 범위를 초과 |
Under Voltage |
입력 전압이 허용 범위보다 낮음 |
Over Current |
과전류 발생 |
Over Temperature |
내부 온도 초과 |
Encoder Error |
Encoder 신호 이상 |
Motor Stall |
모터 정지 또는 부하 과다 |
Communication Error |
CANopen 통신 이상 |
Position Error |
위치 오차 초과 |
Velocity Error |
속도 오차 초과 |
Internal Error |
내부 시스템 오류 |
정확한 Error Code 값은 제품 버전 및 펌웨어에 따라 다를 수 있으므로, Object Dictionary 또는 제품별 오류 코드 표를 참조하십시오.
10.7 Fault Reset 절차
장치가 Fault 상태에 진입하면 일반적인 제어 명령은 실행되지 않습니다.
Fault Reset은 다음 절차에 따라 수행하십시오.
EMCY 또는 Error Code 확인
오류 원인 제거
Statusword에서 Fault 상태 확인
Controlword에
0x0080전송Shutdown 명령 전송
Switch On 명령 전송
Enable Operation 명령 전송
정상 운전 재개
Controlword 예시는 다음과 같습니다.
단계 |
Controlword |
설명 |
|---|---|---|
Fault Reset |
0x0080 |
오류 해제 |
Shutdown |
0x0006 |
Ready to Switch On |
Switch On |
0x0007 |
Switched On |
Enable Operation |
0x000F |
Operation Enabled |
10.8 통신 오류 처리 절차
CANopen 통신 오류가 발생한 경우 다음 순서로 점검하십시오.
단계 |
점검 항목 |
|---|---|
1 |
CAN_H, CAN_L 배선 확인 |
2 |
CAN_GND 연결 상태 확인 |
3 |
Baud Rate 일치 여부 확인 |
4 |
Node ID 중복 여부 확인 |
5 |
120 Ω 종단 저항 확인 |
6 |
Heartbeat 수신 여부 확인 |
7 |
SDO 응답 또는 Abort Code 확인 |
8 |
전원 재인가 후 Boot-up 메시지 확인 |
Heartbeat가 일정 시간 이상 수신되지 않으면 Host Controller는 해당 Node를 통신 장애 상태로 판단해야 합니다.
10.9 오류 복구 시 주의사항
오류를 복구할 때에는 다음 사항을 준수하십시오.
오류 원인을 제거하지 않은 상태에서 Fault Reset을 반복하지 마십시오.
과전압, 과전류, 과온도 오류는 하드웨어 상태를 먼저 확인하십시오.
Encoder 오류가 발생한 경우 원점, 배터리, 배선 및 Encoder 상태를 확인하십시오.
Motor Stall 오류가 발생한 경우 부하, 간섭, 기구 조립 상태를 확인하십시오.
통신 오류가 반복되면 배선, 접지 및 종단 저항을 점검하십시오.
Fault Reset 후에는 반드시 Statusword를 확인한 뒤 제어를 재개하십시오.
경고
오류 상태에서 강제로 운전을 재개하면 장치 손상 또는 예기치 않은 움직임이 발생할 수 있습니다. 반드시 오류 원인을 확인하고 제거한 후 Fault Reset을 수행하십시오.
10.10 오류 처리 권장 로직
Host Controller는 다음과 같은 오류 처리 로직을 구현하는 것을 권장합니다.
Normal Operation
│
▼
Monitor Statusword / Heartbeat / EMCY
│
├── No Error
│ └── Continue Operation
│
└── Error Detected
│
▼
Stop Motion Command
│
▼
Read Error Code
│
▼
Remove Error Cause
│
▼
Fault Reset
│
▼
Enable Operation
│
▼
Resume Operation
중요
Host Controller는 SDO Abort Code, EMCY Message, Statusword 및 Heartbeat를 함께 모니터링해야 합니다. 하나의 피드백만으로 오류 상태를 판단하지 말고, 여러 상태 정보를 조합하여 안전한 오류 처리 로직을 구성하십시오.
11. 부록 (Appendix)
11.1 Object Dictionary Directory
Object Dictionary는 CANopen 장치의 모든 데이터 객체(Object)를 정의하는 데이터베이스입니다. 각 Object는 16-bit Index와 Sub-index로 식별되며, SDO(Service Data Object)를 통해 접근합니다. 일부 Object는 PDO(Process Data Object)에 매핑하여 실시간 데이터 교환에도 사용할 수 있습니다.
SF시리즈 Object Dictionary는 CiA 301 Communication Profile, CiA 402 Device Profile, 그리고 SF시리즈 Manufacturer-Specific Profile로 구성됩니다.
11.1.1 Object Dictionary Memory Map
Object Dictionary
┌─────────────────────────────────────────────────────┐
│ 0000h Reserved │
├─────────────────────────────────────────────────────┤
│ 0001h ~ 001Fh Static Data Types │
├─────────────────────────────────────────────────────┤
│ 0020h ~ 003Fh Complex Data Types │
├─────────────────────────────────────────────────────┤
│ 0040h ~ 005Fh Manufacturer Data Types │
├─────────────────────────────────────────────────────┤
│ 0060h ~ 0FFFh Reserved │
├─────────────────────────────────────────────────────┤
│ 1000h ~ 1FFFh Communication Profile Area │
├─────────────────────────────────────────────────────┤
│ 2000h ~ 5FFFh Manufacturer Specific Area │
├─────────────────────────────────────────────────────┤
│ 6000h ~ 6FFFh CiA402 Device Profile │
├─────────────────────────────────────────────────────┤
│ A000h ~ FFFFh Reserved │
└─────────────────────────────────────────────────────┘
Communication Profile Area (0x1000 ~ 0x1FFF)
Communication Profile Area는 CANopen 네트워크를 구성하기 위한 표준 통신 Object 영역입니다.
Index |
Object |
Description |
|---|---|---|
1000h |
Device Type |
장치 유형 |
1001h |
Error Register |
오류 레지스터 |
1003h |
Pre-defined Error Field |
오류 이력 |
1005h |
COB-ID SYNC |
SYNC Identifier |
1006h |
Communication Cycle Period |
SYNC 주기 |
1007h |
Synchronous Window Length |
동기 윈도우 |
1008h |
Manufacturer Device Name |
제품명 |
1009h |
Hardware Version |
하드웨어 버전 |
100Ah |
Software Version |
펌웨어 버전 |
100Bh |
Node-ID |
노드 ID |
100Ch |
Guard Time |
Node Guard 시간 |
100Dh |
Life Time Factor |
Life Time Factor |
1010h |
Store Parameters |
파라미터 저장 |
1011h |
Restore Default Parameters |
기본값 복원 |
1014h |
COB-ID EMCY |
Emergency Identifier |
1016h |
Consumer Heartbeat Time |
Heartbeat Consumer |
1017h |
Producer Heartbeat Time |
Heartbeat Producer |
1018h |
Identity Object |
Vendor/Product 정보 |
1200h |
SDO Server Parameter |
SDO Server 설정 |
1400h~1403h |
RPDO Communication Parameter |
RPDO1~4 |
1600h~1603h |
RPDO Mapping |
RPDO1~4 Mapping |
1800h~1803h |
TPDO Communication Parameter |
TPDO1~4 |
1A00h~1A03h |
TPDO Mapping |
TPDO1~4 Mapping |
Manufacturer Specific Profile Area (0x2000 ~ 0x5FFF)
Manufacturer Specific Profile Area는 SF시리즈에서 제공하는 제조사 전용 Object를 정의합니다.
이 영역은 CiA 표준에는 포함되지 않으며, SF시리즈의 구동 기능, 진단 기능, Virtual Torque Sensor 및 확장 제어 기능을 제공합니다.
Directory
Index Range |
Category |
Description |
|---|---|---|
2000h~21FFh |
Device Configuration |
제품 설정 및 내부 파라미터 |
2200h~22FFh |
Encoder Information |
엔코더 및 위치 정보 |
2300h~2FFFh |
Reserved |
예약 영역 |
3000h~39FFh |
Motion Extension |
확장 Motion 기능 |
3A00h~3BFFh |
Diagnostics |
진단 및 토크 센서 |
3C00h~5FFFh |
Reserved |
향후 확장 영역 |
주요 Manufacturer Object
Index |
Object Name |
Description |
|---|---|---|
2241h |
Dual Encoder Difference (Δθ) |
모터축과 출력축 엔코더 차이 |
3B68h |
Warning Code |
현재 Warning Code |
3B69h |
Calculated Torque Value / Torque Sensor |
계산 토크 또는 토크 센서 출력 |
3B6Ah |
Torque Sensor Ratio |
정격 토크 대비 출력 비율 |
3B6Bh |
Torque Mode Maximum Velocity Limit |
토크 모드 최대 속도 제한 |
Manufacturer Object 기능 분류
0x2000
│
├─ Device Configuration
│
├─ Calibration Parameter
│
├─ Protection Parameter
│
├─ Encoder Information
│ └─ 0x2241 Dual Encoder Difference
│
├─ Motion Extension
│
├─ Diagnostics
│ ├─ 0x3B68 Warning Code
│ ├─ 0x3B69 Torque Sensor
│ ├─ 0x3B6A Torque Ratio
│ └─ 0x3B6B Torque Mode Velocity Limit
│
└─ Reserved
0x5FFF
참고
Communication Profile Area는 CiA 301 표준을 따르며, Manufacturer Specific Profile Area는 SF시리즈 전용 확장 Object를 제공합니다. 제조사 전용 Object의 상세 정의(Index, Sub-index, Data Type, Access, Default Value, PDO Mapping)는 다음 절 11.2 Object Dictionary에서 각각 설명합니다.
## 11.2 Communication Profile Area (0x1000 ~ 0x1FFF)
Communication Profile Area는 CiA 301 CANopen Application Layer and Communication Profile에서 정의하는 표준 통신 객체(Object) 영역입니다. 이 영역은 장치의 통신 설정, 네트워크 관리, SDO, PDO, SYNC, EMCY 및 Heartbeat 기능을 구성하는 Object들로 이루어져 있습니다. SF시리즈 CANopen은 CiA 301 표준을 기반으로 Communication Profile Area를 구현하며, 대부분의 객체는 CANopen Master와의 호환성을 위해 표준 규격을 따릅니다.
11.2.1 Communication Profile 구성
Communication Profile Area는 다음과 같이 구성됩니다.
Index Range |
Category |
Description |
|---|---|---|
0x1000 ~ 0x1019 |
Device Information |
장치 정보 및 통신 기본 설정 |
0x1020 ~ 0x11FF |
Reserved |
예약 영역 |
0x1200 ~ 0x127F |
SDO Server Parameters |
SDO 서버 설정 |
0x1280 ~ 0x12FF |
SDO Client Parameters |
SDO 클라이언트 설정(미사용) |
0x1400 ~ 0x15FF |
RPDO Communication Parameters |
Receive PDO 통신 설정 |
0x1600 ~ 0x17FF |
RPDO Mapping Parameters |
Receive PDO 매핑 |
0x1800 ~ 0x19FF |
TPDO Communication Parameters |
Transmit PDO 통신 설정 |
0x1A00 ~ 0x1BFF |
TPDO Mapping Parameters |
Transmit PDO 매핑 |
0x1C00 ~ 0x1FFF |
Synchronization Parameters |
SYNC 및 기타 통신 설정 |
11.2.2 Communication Profile 구조
Communication Profile Area (0x1000 ~ 0x1FFF)
0x1000
│
├── Device Information
│ ├─ Device Type
│ ├─ Error Register
│ ├─ Identity Object
│ └─ Heartbeat
│
├── SDO Server
│
├── RPDO Communication
│
├── RPDO Mapping
│
├── TPDO Communication
│
├── TPDO Mapping
│
└── Synchronization
0x1FFF
11.2.3 Device Information Objects
이 영역은 장치의 기본 정보와 네트워크 동작에 필요한 정보를 제공합니다.
Index |
Object |
Description |
|---|---|---|
1000h |
Device Type |
장치 유형 |
1001h |
Error Register |
현재 오류 상태 |
1003h |
Pre-defined Error Field |
오류 이력 |
1005h |
COB-ID SYNC Message |
SYNC COB-ID |
1006h |
Communication Cycle Period |
SYNC 주기 |
1007h |
Synchronous Window Length |
동기 윈도우 |
1008h |
Manufacturer Device Name |
장치 이름 |
1009h |
Manufacturer Hardware Version |
하드웨어 버전 |
100Ah |
Manufacturer Software Version |
소프트웨어 버전 |
100Bh |
Node-ID |
Node ID |
100Ch |
Guard Time |
Node Guard 시간 |
100Dh |
Life Time Factor |
Life Time Factor |
1010h |
Store Parameters |
파라미터 저장 |
1011h |
Restore Default Parameters |
기본값 복원 |
1014h |
COB-ID EMCY |
Emergency COB-ID |
1016h |
Consumer Heartbeat Time |
Heartbeat Consumer |
1017h |
Producer Heartbeat Time |
Heartbeat Producer |
1018h |
Identity Object |
Vendor, Product, Revision 정보 |
11.2.4 SDO Communication Objects
SDO(Service Data Object)는 Object Dictionary의 데이터를 읽거나 쓰기 위한 통신 객체입니다.
Index |
Object |
Description |
|---|---|---|
1200h |
SDO Server Parameter |
기본 SDO Server 설정 |
SDO Server Object에는 다음 정보가 포함됩니다.
Sub-index |
Description |
|---|---|
0 |
Sub-index 개수 |
1 |
Client → Server COB-ID |
2 |
Server → Client COB-ID |
11.2.5 PDO Communication Objects
PDO는 실시간 데이터를 송수신하기 위한 통신 객체입니다.
Receive PDO (RPDO)
Index |
Description |
|---|---|
1400h |
RPDO1 Communication Parameter |
1401h |
RPDO2 Communication Parameter |
1402h |
RPDO3 Communication Parameter |
1403h |
RPDO4 Communication Parameter |
각 RPDO Communication Object에는 다음 항목이 포함됩니다.
Sub-index |
Description |
|---|---|
0 |
Sub-index 개수 |
1 |
COB-ID |
2 |
Transmission Type |
3 |
Inhibit Time |
5 |
Event Timer |
Receive PDO Mapping
Index |
Description |
|---|---|
1600h |
RPDO1 Mapping |
1601h |
RPDO2 Mapping |
1602h |
RPDO3 Mapping |
1603h |
RPDO4 Mapping |
각 Mapping Object는 PDO에 포함될 Object Dictionary 항목을 정의합니다.
Transmit PDO (TPDO)
Index |
Description |
|---|---|
1800h |
TPDO1 Communication Parameter |
1801h |
TPDO2 Communication Parameter |
1802h |
TPDO3 Communication Parameter |
1803h |
TPDO4 Communication Parameter |
TPDO Communication Parameter는 RPDO와 동일한 구조를 사용하며, COB-ID, Transmission Type 및 Event Timer를 정의합니다. PDO의 전송 방식은 Transmission Type 설정에 의해 결정됩니다.
Transmit PDO Mapping
Index |
Description |
|---|---|
1A00h |
TPDO1 Mapping |
1A01h |
TPDO2 Mapping |
1A02h |
TPDO3 Mapping |
1A03h |
TPDO4 Mapping |
TPDO Mapping은 Slave(SF시리즈)에서 Master로 전송되는 실시간 데이터를 정의합니다. 매핑 가능한 객체는 Object Dictionary의 PDO Mapping 속성에 따라 결정됩니다.
11.2.6 주요 Communication Object 요약
Object Group |
Index Range |
Purpose |
|---|---|---|
Device Information |
1000h~1018h |
장치 정보 및 통신 설정 |
SDO Server |
1200h |
SDO 통신 |
RPDO Parameter |
1400h~1403h |
PDO 수신 설정 |
RPDO Mapping |
1600h~1603h |
PDO 수신 데이터 구성 |
TPDO Parameter |
1800h~1803h |
PDO 송신 설정 |
TPDO Mapping |
1A00h~1A03h |
PDO 송신 데이터 구성 |
11.2.7 통신 객체 간의 관계
Communication Profile
+-----------------------------+
| Device Information |
+--------------+--------------+
|
+--------------v--------------+
| SDO Server |
+--------------+--------------+
|
Read / Write Object Dictionary
|
+------------------+---------------------+
| |
+--------v-----------+ +--------v-----------+
| RPDO | | TPDO |
| Master → SF시리즈 | | SF시리즈 → Master |
+-------+------------+ +--------+-----------+
| |
+------------------+---------------------+
|
Process Data Exchange
참고
Communication Profile Area는 CANopen 통신을 위한 표준 객체 집합으로 구성되며, 모든 객체는 CiA 301 규격에 따라 정의됩니다. 각 Object의 Index, Sub-index, 데이터 형식(Data Type), 접근 권한(Access), 기본값(Default Value) 및 PDO Mapping 지원 여부는 이후 11.5 Object Dictionary에서 개별적으로 설명합니다.
11.3 Manufacturer Specific Area (0x2000 ~ 0x5FFF)
Manufacturer Specific Area는 SF시리즈에서 정의한 제조사 전용 Object 영역입니다. 이 영역은 CiA 301 및 CiA 402 표준에서 정의되지 않은 기능을 제공하며, SF시리즈 Rotary Actuator의 확장 제어, 진단, 토크 센서 및 장치 설정 기능을 포함합니다.
Manufacturer Specific Object는 Object Dictionary의 일부로 관리되며, Host Controller는 SDO(Service Data Object)를 통해 해당 Object를 읽거나 쓸 수 있습니다. 또한, 일부 Object는 PDO Mapping을 지원하여 실시간 데이터 교환에 사용할 수 있습니다.
참고
Manufacturer Specific Area에 포함된 Object는 제품 모델 및 펌웨어 버전에 따라 지원 여부가 다를 수 있습니다.
11.3.1 Memory Map
Manufacturer Specific Area는 다음과 같이 구성됩니다.
Manufacturer Specific Area (0x2000 ~ 0x5FFF)
0x2000
│
├── Device Configuration
│
├── Calibration Parameters
│
├── Motion Extension
│
├── Encoder Information
│
├── Protection Parameters
│
├── Diagnostics
│
├── Virtual Torque Sensor
│
├── Warning Information
│
└── Reserved
0x5FFF
11.3.2 Object Group
Manufacturer Specific Area는 기능에 따라 다음과 같이 구분됩니다.
Index Range |
Group |
Description |
|---|---|---|
0x2000 ~ 0x21FF |
Device Configuration |
장치 설정 및 제조사 전용 파라미터 |
0x2200 ~ 0x22FF |
Encoder Information |
엔코더 및 위치 정보 |
0x2300 ~ 0x2FFF |
Reserved |
예약 영역 |
0x3000 ~ 0x39FF |
Motion Extension |
확장 모션 제어 기능 |
0x3A00 ~ 0x3BFF |
Diagnostics |
진단 및 상태 정보 |
0x3C00 ~ 0x5FFF |
Reserved |
향후 기능 확장 영역 |
11.3.3 Device Configuration
Device Configuration Group은 제품의 동작 특성을 설정하기 위한 제조사 전용 Object를 제공합니다.
대표적인 기능은 다음과 같습니다.
Category |
Description |
|---|---|
Device Parameters |
제품 설정 |
Motion Parameters |
내부 운전 파라미터 |
Protection Parameters |
보호 기능 설정 |
Internal Configuration |
내부 설정 |
Calibration Data |
공장 보정 데이터 |
일부 Object는 공장 설정값으로 사용되며 일반 사용자의 변경이 제한될 수 있습니다.
11.3.4 Encoder Information
Encoder Information Group은 위치 검출과 관련된 정보를 제공합니다.
Index |
Object |
Access |
Description |
|---|---|---|---|
0x2241 |
Dual Encoder Difference |
RO |
모터축과 출력축 엔코더의 위치 차이(Δθ) |
Dual Encoder Difference는 감속기의 비틀림량을 계산하기 위한 데이터로 사용되며, Virtual Torque Sensor 기능의 입력값으로 활용됩니다.
11.3.5 Motion Extension
Motion Extension Group은 CiA 402 표준 기능을 보완하는 SF시리즈 고유의 제어 기능을 제공합니다.
주요 기능은 다음과 같습니다.
Function |
Description |
|---|---|
Motion Extension |
확장 운전 기능 |
Internal Motion Parameters |
내부 제어 파라미터 |
Torque Control Extension |
토크 제어 확장 기능 |
Velocity Limitation |
속도 제한 |
Motion Diagnostics |
운전 상태 진단 |
이 Object들은 고급 모션 제어 및 제조사 전용 기능을 지원하기 위해 사용됩니다.
11.3.6 Diagnostics
Diagnostics Group은 장치의 운전 상태와 내부 진단 정보를 제공합니다.
Index |
Object |
Access |
Description |
|---|---|---|---|
0x3B68 |
Warning Code |
RO |
현재 경고 코드 |
0x3B69 |
Calculated Torque Value / Torque Sensor |
RO |
계산 토크 또는 토크 센서 출력 |
0x3B6A |
Torque Sensor Ratio |
RO |
정격 토크 대비 토크 비율 |
0x3B6B |
Torque Mode Maximum Velocity Limit |
RW |
토크 모드 최대 속도 제한 |
Diagnostics Object는 예방 유지보수, 시스템 모니터링 및 이상 상태 분석에 사용할 수 있습니다.
11.3.7 Virtual Torque Sensor
SF시리즈는 Dual Encoder 기반의 Virtual Torque Sensor(VTS) 기능을 제공합니다.
VTS는 모터측 엔코더와 출력측 엔코더의 위치 차이를 이용하여 출력 토크를 계산하며, 별도의 물리적 토크 센서 없이 토크 정보를 제공합니다.
VTS에서 제공하는 주요 데이터는 다음과 같습니다.
Object |
Description |
|---|---|
Dual Encoder Difference |
출력축 비틀림량 |
Calculated Torque Value |
계산된 출력 토크 |
Torque Ratio |
정격 토크 대비 출력 비율 |
이 데이터는 TPDO에 매핑하여 실시간으로 모니터링할 수 있습니다.
11.3.8 Access Method
Manufacturer Specific Object는 표준 CANopen Object와 동일한 방식으로 접근합니다.
Access Method |
Description |
|---|---|
SDO Upload |
Object 읽기(Read) |
SDO Download |
Object 쓰기(Write) |
TPDO |
실시간 상태 전송 |
RPDO |
실시간 제어 데이터 수신(지원 Object에 한함) |
Object의 접근 권한은 다음과 같습니다.
Attribute |
Description |
|---|---|
RO |
Read Only |
RW |
Read / Write |
WO |
Write Only |
읽기 전용(RO) Object에 쓰기를 시도하면 SDO Abort Code가 반환됩니다.
11.3.9 사용 시 주의사항
Manufacturer Specific Object를 사용할 때에는 다음 사항을 확인하십시오.
지원되는 Object는 제품 모델 및 펌웨어 버전에 따라 다를 수 있습니다.
일부 Object는 제조사 서비스 또는 유지보수 용도로만 사용됩니다.
Calibration Parameter는 임의로 변경하지 마십시오.
PDO Mapping을 변경할 경우에는 해당 PDO를 비활성화한 후 설정을 변경하십시오.
제조사 전용 Object를 수정하기 전에 현재 설정값을 백업하는 것을 권장합니다.
11.3.10 Manufacturer Specific Area 구성도
Manufacturer Specific Area
+--------------------------------------+
| Device Configuration |
+--------------------------------------+
| Motion Extension |
+--------------------------------------+
| Encoder Information |
| └─ Dual Encoder Difference |
+--------------------------------------+
| Diagnostics |
| ├─ Warning Code |
| ├─ Calculated Torque Value |
| ├─ Torque Sensor Ratio |
| └─ Torque Mode Velocity Limit |
+--------------------------------------+
| Reserved |
+--------------------------------------+
중요
Manufacturer Specific Area는 SF시리즈 제품의 고유 기능을 제공하는 확장 Object 영역입니다. 각 Object의 Index, Sub-index, Data Type, Access Attribute, Default Value, PDO Mapping 지원 여부는 다음 장인 11.5 Object Dictionary에서 개별적으로 설명합니다.
## 11.4 CiA 402 Drive Profile Area (0x6000 ~ 0x67FF)
CiA 402 Drive Profile Area는 CiA 402 Device Profile for Drives and Motion Control에서 정의한 표준 Object 영역입니다. 이 영역은 서보 드라이브 및 모션 제어 장치의 상태(State), 운전 모드(Operation Mode), 위치(Position), 속도(Velocity), 토크(Torque) 및 기타 모션 제어 기능을 제공합니다.
SF시리즈 Rotary Actuator는 CiA 402 표준을 기반으로 Drive Profile을 구현하며, Host Controller는 이 영역의 Object를 이용하여 장치의 상태를 제어하고 모션을 수행할 수 있습니다.
11.4.1 CiA 402 Profile 구성
Drive Profile Area는 다음과 같이 구성됩니다.
Index Range |
Category |
Description |
|---|---|---|
0x6000 ~ 0x603F |
Status Information |
장치 상태 및 진단 |
0x6040 ~ 0x605F |
State Control |
Controlword 및 Statusword |
0x6060 ~ 0x607F |
Operation Mode |
운전 모드 및 목표값 |
0x6080 ~ 0x609F |
Motion Profile |
속도, 가속도 및 감속도 |
0x60A0 ~ 0x60FF |
Position & Velocity |
위치 및 속도 제어 |
0x6100 ~ 0x67FF |
Manufacturer Extension |
확장 모션 제어 기능 |
11.4.2 Drive Profile 구조
CiA 402 Drive Profile Area (0x6000 ~ 0x67FF)
0x6000
│
├── Status Information
│
├── State Control
│
├── Operation Mode
│
├── Position Control
│
├── Velocity Control
│
├── Torque Control
│
├── Motion Profile
│
└── Drive Parameters
0x67FF
11.4.3 주요 Drive Profile Objects
다음 표는 SF시리즈에서 사용하는 주요 CiA 402 Object를 나타냅니다.
Index |
Object Name |
Access |
Description |
|---|---|---|---|
0x603F |
Error Code |
RO |
최근 오류 코드 |
0x6040 |
Controlword |
RW |
장치 상태 제어 |
0x6041 |
Statusword |
RO |
현재 상태 |
0x6060 |
Modes of Operation |
RW |
운전 모드 선택 |
0x6061 |
Modes of Operation Display |
RO |
현재 운전 모드 |
0x6064 |
Position Actual Value |
RO |
현재 위치 |
0x606C |
Velocity Actual Value |
RO |
현재 속도 |
0x6071 |
Target Torque |
RW |
목표 토크 |
0x6077 |
Torque Actual Value |
RO |
실제 토크 |
0x607A |
Target Position |
RW |
목표 위치 |
0x6081 |
Profile Velocity |
RW |
프로파일 속도 |
0x6083 |
Profile Acceleration |
RW |
프로파일 가속도 |
0x6084 |
Profile Deceleration |
RW |
프로파일 감속도 |
0x60FF |
Target Velocity |
RW |
목표 속도 |
11.4.4 CiA 402 State Machine
CiA 402는 장치의 운전 상태를 Power Drive System Finite State Automaton(PDS FSA) 으로 정의합니다.
Fault
▲
│
Fault Reaction Active
▲
│
Switch On Disabled
│
▼
Ready to Switch On
│
▼
Switched On
│
▼
Operation Enabled
│
▼
Quick Stop Active
Host Controller는 Controlword(0x6040) 를 이용하여 상태를 전환하고, Statusword(0x6041) 를 통해 현재 상태를 확인합니다.
11.4.5 Controlword
Controlword는 CiA 402 상태 머신을 제어하는 핵심 Object입니다.
Value |
Description |
|---|---|
0x0006 |
Shutdown |
0x0007 |
Switch On |
0x000F |
Enable Operation |
0x0002 |
Quick Stop |
0x0000 |
Disable Voltage |
0x0080 |
Fault Reset |
Controlword는 장치의 상태 전이를 제어하며, 각 명령은 현재 상태에 따라 유효성이 결정됩니다.
11.4.6 Statusword
Statusword는 현재 장치의 운전 상태를 나타냅니다.
State |
Description |
|---|---|
Not Ready to Switch On |
초기화 중 |
Switch On Disabled |
Servo 비활성 |
Ready to Switch On |
Servo 준비 |
Switched On |
Servo ON |
Operation Enabled |
정상 운전 |
Quick Stop Active |
Quick Stop 상태 |
Fault Reaction Active |
Fault 처리 중 |
Fault |
Fault 상태 |
Host Controller는 제어 명령을 실행하기 전에 Statusword를 확인하여 장치가 정상 운전 상태인지 확인해야 합니다.
11.4.7 Modes of Operation
CiA 402는 다양한 운전 모드를 지원합니다.
Value |
Mode |
Description |
|---|---|---|
1 |
Profile Position (PP) |
위치 제어 |
3 |
Profile Velocity (PV) |
속도 제어 |
4 |
Profile Torque (PT) |
토크 제어 |
6 |
Homing (HM) |
원점 복귀 |
8 |
Cyclic Synchronous Position (CSP) |
주기 동기 위치 제어 |
9 |
Cyclic Synchronous Velocity (CSV) |
주기 동기 속도 제어 |
10 |
Cyclic Synchronous Torque (CST) |
주기 동기 토크 제어 |
운전 모드는 Object 0x6060에 설정하며, 현재 모드는 Object 0x6061에서 확인할 수 있습니다.
11.4.8 Motion Profile Objects
모션 제어에 사용되는 주요 Object는 다음과 같습니다.
Object |
Description |
|---|---|
Target Position |
목표 위치 |
Position Actual Value |
현재 위치 |
Target Velocity |
목표 속도 |
Velocity Actual Value |
현재 속도 |
Target Torque |
목표 토크 |
Torque Actual Value |
현재 토크 |
Profile Velocity |
이동 속도 |
Profile Acceleration |
가속도 |
Profile Deceleration |
감속도 |
이 Object들은 선택한 Operation Mode에 따라 사용됩니다.
11.4.9 Drive Profile 동작 흐름
Host Controller
│
│ Controlword
▼
CiA402 State Machine
│
▼
Operation Mode
│
▼
Target Position
Target Velocity
Target Torque
│
▼
Motion Controller
│
▼
Statusword
Actual Position
Actual Velocity
Actual Torque
11.4.10 사용 시 주의사항
Drive Profile Object를 사용할 때에는 다음 사항을 확인하십시오.
Controlword를 사용하기 전에 Statusword를 확인하십시오.
Operation Mode를 먼저 설정한 후 목표값을 전송하십시오.
Position, Velocity 및 Torque 명령은 선택한 Operation Mode에 따라 동작합니다.
Fault 상태에서는 모든 모션 명령이 무시됩니다.
Fault Reset 후에는 Shutdown → Switch On → Enable Operation 순으로 상태를 복구해야 합니다.
PDO Mapping을 사용하는 경우 실시간 데이터와 Object Dictionary의 설정이 일치하는지 확인하십시오.
중요
CiA 402 Drive Profile Area는 SF시리즈 Rotary Actuator의 모든 모션 제어 기능을 제공하는 핵심 Object 영역입니다. 각 Object의 Index, Sub-index, Data Type, Access Attribute, Default Value, PDO Mapping 지원 여부 및 비트 정의는 다음 절인 11.5 Object Dictionary에서 상세히 설명합니다.
11.5 Object Dictionary
본 절에서는 SF시리즈 CANopen 및 EtherCAT에서 사용하는 Object Dictionary 전체 목록을 제공합니다.
각 Object는 Index, Object Name, Object Code, 적용 영역, CANopen 지원 여부 및 EtherCAT 지원 여부로 구분됩니다.
Index |
Object Name |
Object Code |
Area |
CANopen |
EtherCAT |
Description |
|---|---|---|---|---|---|---|
0x1000 |
Device Type |
VAR |
Communication Profile |
✓ |
✓ |
장치 유형 |
0x1001 |
Error Register |
VAR |
Communication Profile |
✓ |
✓ |
오류 레지스터 |
0x1003 |
Pre-defined Error Field |
ARRAY |
Communication Profile |
✓ |
✓ |
사전 정의 오류 이력 |
0x1005 |
COB-ID SYNC Message |
VAR |
Communication Profile |
✓ |
SYNC 메시지 COB-ID |
|
0x1006 |
Communication Cycle Period |
VAR |
Communication Profile |
✓ |
통신 주기 |
|
0x1007 |
Synchronous Window Length |
VAR |
Communication Profile |
✓ |
동기 윈도우 길이 |
|
0x1008 |
Manufacturer Device Name |
VAR |
Communication Profile |
✓ |
✓ |
제조사 장치명 |
0x1009 |
Manufacturer Hardware Version |
VAR |
Communication Profile |
✓ |
✓ |
하드웨어 버전 |
0x100A |
Manufacturer Software Version |
VAR |
Communication Profile |
✓ |
✓ |
소프트웨어 버전 |
0x100B |
Node-ID |
VAR |
Communication Profile |
✓ |
✓ |
Node ID |
0x100C |
Guard Time |
VAR |
Communication Profile |
✓ |
Node Guard 시간 |
|
0x100D |
Life Time Factor |
VAR |
Communication Profile |
✓ |
Life Time Factor |
|
0x1010 |
Save Parameters |
ARRAY |
Communication Profile |
✓ |
✓ |
파라미터 저장 |
0x1014 |
COB-ID EMCY |
VAR |
Communication Profile |
✓ |
Emergency 메시지 COB-ID |
|
0x1016 |
Consumer Heartbeat Time |
ARRAY |
Communication Profile |
✓ |
Consumer Heartbeat 시간 |
|
0x1017 |
Producer Heartbeat Time |
VAR |
Communication Profile |
✓ |
Producer Heartbeat 시간 |
|
0x1018 |
Identity Object |
RECORD |
Communication Profile |
✓ |
✓ |
장치 식별 정보 |
0x1200 |
SDO Server Parameter |
RECORD |
Communication Profile |
✓ |
SDO Server 설정 |
|
0x1400 |
Receive PDO 1 Parameter |
RECORD |
Communication Profile |
✓ |
RPDO1 통신 파라미터 |
|
0x1401 |
Receive PDO 2 Parameter |
RECORD |
Communication Profile |
✓ |
RPDO2 통신 파라미터 |
|
0x1402 |
Receive PDO 3 Parameter |
RECORD |
Communication Profile |
✓ |
RPDO3 통신 파라미터 |
|
0x1403 |
Receive PDO 4 Parameter |
RECORD |
Communication Profile |
✓ |
RPDO4 통신 파라미터 |
|
0x1600 |
Receive PDO 1 Mapping |
RECORD |
Communication Profile |
✓ |
✓ |
RPDO1 매핑 |
0x1601 |
Receive PDO 2 Mapping |
RECORD |
Communication Profile |
✓ |
✓ |
RPDO2 매핑 |
0x1602 |
Receive PDO 3 Mapping |
RECORD |
Communication Profile |
✓ |
✓ |
RPDO3 매핑 |
0x1603 |
Receive PDO 4 Mapping |
RECORD |
Communication Profile |
✓ |
✓ |
RPDO4 매핑 |
0x1800 |
Transmit PDO 1 Parameter |
RECORD |
Communication Profile |
✓ |
TPDO1 통신 파라미터 |
|
0x1801 |
Transmit PDO 2 Parameter |
RECORD |
Communication Profile |
✓ |
TPDO2 통신 파라미터 |
|
0x1802 |
Transmit PDO 3 Parameter |
RECORD |
Communication Profile |
✓ |
TPDO3 통신 파라미터 |
|
0x1803 |
Transmit PDO 4 Parameter |
RECORD |
Communication Profile |
✓ |
TPDO4 통신 파라미터 |
|
0x1A00 |
Transmit PDO 1 Mapping |
RECORD |
Communication Profile |
✓ |
✓ |
TPDO1 매핑 |
0x1A01 |
Transmit PDO 2 Mapping |
RECORD |
Communication Profile |
✓ |
✓ |
TPDO2 매핑 |
0x1A02 |
Transmit PDO 3 Mapping |
RECORD |
Communication Profile |
✓ |
✓ |
TPDO3 매핑 |
0x1A03 |
Transmit PDO 4 Mapping |
RECORD |
Communication Profile |
✓ |
✓ |
TPDO4 매핑 |
0x1C00 |
SYNC Manager Communication Type |
ARRAY |
EtherCAT Profile |
✓ |
Sync Manager 통신 타입 |
|
0x1C12 |
SYNC Manager 2 PDO Assignment |
ARRAY |
EtherCAT Profile |
✓ |
SM2 PDO 할당 |
|
0x1C13 |
SYNC Manager 3 PDO Assignment |
ARRAY |
EtherCAT Profile |
✓ |
SM3 PDO 할당 |
|
0x1C32 |
SYNC Manager 2 Parameter |
RECORD |
EtherCAT Profile |
✓ |
SM2 파라미터 |
|
0x1C33 |
SYNC Manager 3 Parameter |
RECORD |
EtherCAT Profile |
✓ |
SM3 파라미터 |
|
0x200A |
Locked-Rotor Parameter Set |
ARRAY |
Manufacturer Specific |
✓ |
✓ |
로터 잠김 보호 파라미터 |
0x20A0 |
Load-Side Encoder Position |
VAR |
Manufacturer Specific |
✓ |
✓ |
부하측 엔코더 위치 |
0x2205 |
Analog Input |
VAR |
Manufacturer Specific |
✓ |
✓ |
아날로그 입력 |
0x2240 |
Motor Encoder Position |
VAR |
Manufacturer Specific |
✓ |
✓ |
모터 엔코더 위치 |
0x2241 |
Dual Encoder Difference Value |
VAR |
Manufacturer Specific |
✓ |
✓ |
듀얼 엔코더 차이값 |
0x2242 |
Reset Load Side Encoder |
VAR |
Manufacturer Specific |
✓ |
✓ |
부하측 엔코더 리셋 |
0x22A2 |
Drive Temperature |
VAR |
Manufacturer Specific |
✓ |
✓ |
드라이브 온도 |
0x2380 |
Current Loop Parameter |
ARRAY |
Manufacturer Specific |
✓ |
✓ |
전류 루프 파라미터 |
0x2381 |
Velocity Loop Parameter |
ARRAY |
Manufacturer Specific |
✓ |
✓ |
속도 루프 파라미터 |
0x2382 |
Position Loop Gain |
ARRAY |
Manufacturer Specific |
✓ |
✓ |
위치 루프 게인 |
0x2420 |
Prepare Download |
VAR |
Manufacturer Specific |
✓ |
펌웨어 다운로드 준비 |
|
0x2421 |
Hardware Version Number |
VAR |
Manufacturer Specific |
✓ |
하드웨어 버전 번호 |
|
0x2422 |
Firmware Version Number |
VAR |
Manufacturer Specific |
✓ |
펌웨어 버전 번호 |
|
0x2423 |
Firmware Length |
VAR |
Manufacturer Specific |
✓ |
펌웨어 길이 |
|
0x3000 |
Max Integral |
VAR |
Manufacturer Specific |
✓ |
최대 적분값 |
|
0x3B59 |
Velocity Offset Switch |
VAR |
Manufacturer Specific |
✓ |
속도 오프셋 스위치 |
|
0x3B60 |
Velocity Following Error Window |
VAR |
Manufacturer Specific |
✓ |
속도 추종 오차 윈도우 |
|
0x3B61 |
Soft Velocity Following Error Window |
VAR |
Manufacturer Specific |
✓ |
소프트 속도 추종 오차 윈도우 |
|
0x3B62 |
Soft Position Following Error Window |
VAR |
Manufacturer Specific |
✓ |
소프트 위치 추종 오차 윈도우 |
|
0x3B64 |
Filter 1: Filter Window Value |
VAR |
Manufacturer Specific |
✓ |
필터 윈도우 값 |
|
0x3B67 |
Soft Locked-Rotor Parameter Set |
VAR |
Manufacturer Specific |
✓ |
소프트 로터 잠김 보호 파라미터 |
|
0x3B68 |
Warning Code |
VAR |
Manufacturer Specific |
✓ |
경고 코드 |
|
0x3B69 |
Torque Sensor |
VAR |
Manufacturer Specific |
✓ |
✓ |
토크 센서 값 |
0x3B6A |
Torque Sensor Ratio |
VAR |
Manufacturer Specific |
✓ |
✓ |
토크 센서 비율 |
0x3B6B |
Torque Mode Maximum Velocity Limit |
VAR |
Manufacturer Specific |
✓ |
✓ |
토크 모드 최대 속도 제한 |
0x3B6C |
Feedforward Filter Coefficient of Velocity |
VAR |
Manufacturer Specific |
✓ |
✓ |
속도 피드포워드 필터 계수 |
0x4602 |
Release Brake |
VAR |
Manufacturer Specific |
✓ |
✓ |
브레이크 해제 |
0x603F |
Error Code |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
오류 코드 |
0x6040 |
Controlword |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
제어 워드 |
0x6041 |
Statusword |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
상태 워드 |
0x605A |
Quick Stop Option Code |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
Quick Stop 동작 옵션 |
0x605B |
Shutdown Option Code |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
Shutdown 동작 옵션 |
0x605C |
Disable Operation Option Code |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
Disable Operation 동작 옵션 |
0x605D |
Halt Option Code |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
Halt 동작 옵션 |
0x605E |
Fault Reaction Option Code |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
Fault 발생 시 반응 옵션 |
0x6060 |
Modes of Operation |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
운전 모드 설정 |
0x6061 |
Modes of Operation Display |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
현재 운전 모드 표시 |
0x6062 |
Position Demand Value |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
위치 지령값 |
0x6064 |
Position Actual Value |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
현재 위치 |
0x6065 |
Following Error Window |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
위치 추종 오차 윈도우 |
0x6066 |
Following Error Time Out |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
위치 추종 오차 시간 |
0x6067 |
Position Window |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
위치 도달 윈도우 |
0x6068 |
Position Window Time |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
위치 도달 시간 |
0x6069 |
Velocity Sensor Actual Value |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
속도 센서 현재값 |
0x606B |
Velocity Demand Value |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
속도 지령값 |
0x606C |
Velocity Actual Value |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
현재 속도 |
0x606D |
Velocity Window |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
속도 도달 윈도우 |
0x606E |
Velocity Window Time |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
속도 도달 시간 |
0x606F |
Velocity Threshold |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
속도 임계값 |
0x6070 |
Velocity Threshold Time |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
속도 임계 시간 |
0x6071 |
Target Torque |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
목표 토크 |
0x6072 |
Max Torque |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
최대 토크 |
0x6073 |
Max Current |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
최대 전류 |
0x6074 |
Torque Demand Value |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
토크 지령값 |
0x6075 |
Motor Rated Current |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
모터 정격 전류 |
0x6076 |
Motor Rated Torque |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
모터 정격 토크 |
0x6077 |
Torque Actual Value |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
현재 토크 |
0x6078 |
Motor Actual Current |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
모터 현재 전류 |
0x6079 |
DC Link Circuit Voltage |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
DC Link 전압 |
0x607A |
Target Position |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
목표 위치 |
0x607B |
Position Range Limit |
ARRAY |
CiA402 Drive Profile |
✓ |
✓ |
위치 범위 제한 |
0x607C |
Home Offset |
ARRAY |
CiA402 Drive Profile |
✓ |
✓ |
원점 오프셋 |
0x607D |
Software Position Limit |
ARRAY |
CiA402 Drive Profile |
✓ |
✓ |
소프트웨어 위치 제한 |
0x607E |
Polarity (Velocity & Position) |
ARRAY |
CiA402 Drive Profile |
극성 설정 |
||
0x607F |
Max Profile Velocity |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
최대 프로파일 속도 |
0x6080 |
Max Motor Speed |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
최대 모터 속도 |
0x6081 |
Profile Velocity |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
프로파일 속도 |
0x6082 |
End Velocity |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
종료 속도 |
0x6083 |
Profile Acceleration |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
프로파일 가속도 |
0x6084 |
Profile Deceleration |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
프로파일 감속도 |
0x6085 |
Quick Stop Deceleration |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
Quick Stop 감속도 |
0x6086 |
Motion Profile Type |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
모션 프로파일 타입 |
0x6087 |
Torque Slope |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
토크 기울기 |
0x6093 |
Position Factor |
VAR |
CiA402 Drive Profile |
위치 계수 |
||
0x6094 |
Velocity Encoder Factor |
VAR |
CiA402 Drive Profile |
속도 엔코더 계수 |
||
0x6095 |
Velocity Factor 1 |
VAR |
CiA402 Drive Profile |
속도 계수 1 |
||
0x6097 |
Acceleration Factor |
VAR |
CiA402 Drive Profile |
가속도 계수 |
||
0x6098 |
Homing Method |
VAR |
CiA402 Drive Profile |
원점 복귀 방식 |
||
0x6099 |
Home Velocity |
VAR |
CiA402 Drive Profile |
원점 복귀 속도 |
||
0x609A |
Homing Acceleration |
VAR |
CiA402 Drive Profile |
원점 복귀 가속도 |
||
0x60B0 |
Position Offset |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
위치 오프셋 |
0x60B1 |
Velocity Offset |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
속도 오프셋 |
0x60B2 |
Torque Offset |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
토크 오프셋 |
0x60C0 |
Interpolated Position Mode |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
보간 위치 모드 |
0x60C1 |
Interpolated Data Record |
VAR |
CiA402 Drive Profile |
보간 데이터 레코드 |
||
0x60C2 |
Interpolated Time Period |
VAR |
CiA402 Drive Profile |
보간 시간 주기 |
||
0x60C5 |
Max Acceleration |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
최대 가속도 |
0x60C6 |
Max Deceleration |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
최대 감속도 |
0x60E0 |
Positive Torque Limit Value |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
정방향 토크 제한 |
0x60E1 |
Negative Torque Limit Value |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
역방향 토크 제한 |
0x60F2 |
Position Option Code |
VAR |
CiA402 Drive Profile |
위치 옵션 코드 |
||
0x60F4 |
Following Error Actual Value |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
실제 추종 오차 |
0x60FC |
Position Demand Value |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
위치 지령값 |
0x60FD |
Digital Inputs |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
디지털 입력 |
0x60FE |
Digital Outputs |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
디지털 출력 |
0x60FF |
Target Velocity |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
목표 속도 |
0x6502 |
Supported Drive Modes |
VAR |
CiA402 Drive Profile |
✓ |
✓ |
지원 운전 모드 |
참고
본 표는 SF시리즈 CANopen 및 EtherCAT에서 제공하는 Object Dictionary의 전체 Index 목록입니다. 각 Object의 Sub-index, Data Type, Default Value, Min/Max Value, Access Attribute, Backup 여부, Update 방식 및 PDO Mapping 가능 여부는 다음 절에서 개별 Object별 상세 표로 설명합니다.
## 11.6 PDO Mapping Objects
PDO(Process Data Object)는 CANopen에서 실시간 제어 데이터와 피드백 데이터를 송수신하기 위한 통신 객체입니다.
SF시리즈 CANopen은 다음 PDO를 지원합니다.
Receive PDO(RPDO) 4개
Transmit PDO(TPDO) 4개
각 PDO는 최대 8 Byte의 데이터를 포함할 수 있으며, Mapping Object를 통해 PDO에 포함할 Object Dictionary 항목을 지정합니다.
11.6.1 PDO 개요
PDO는 방향에 따라 다음과 같이 구분됩니다.
PDO Type |
Direction |
Description |
|---|---|---|
RPDO |
Master → SF시리즈 |
Host Controller가 SF시리즈로 제어 명령을 전송 |
TPDO |
SF시리즈 → Master |
SF시리즈가 Host Controller로 상태 정보를 전송 |
일반적으로 RPDO에는 Controlword, Target Position, Target Velocity, Target Torque 등의 제어 데이터가 매핑되며, TPDO에는 Statusword, Actual Position, Actual Velocity, Actual Torque 등의 피드백 데이터가 매핑됩니다.
11.6.2 PDO Communication Object 및 Mapping Object
SF시리즈 CANopen에서 사용하는 PDO Communication Object와 Mapping Object는 다음과 같습니다.
PDO |
Communication Object |
Mapping Object |
Default COB-ID |
|---|---|---|---|
RPDO1 |
0x1400 |
0x1600 |
0x200 + Node ID |
RPDO2 |
0x1401 |
0x1601 |
0x300 + Node ID |
RPDO3 |
0x1402 |
0x1602 |
0x400 + Node ID |
RPDO4 |
0x1403 |
0x1603 |
0x500 + Node ID |
TPDO1 |
0x1800 |
0x1A00 |
0x180 + Node ID |
TPDO2 |
0x1801 |
0x1A01 |
0x280 + Node ID |
TPDO3 |
0x1802 |
0x1A02 |
0x380 + Node ID |
TPDO4 |
0x1803 |
0x1A03 |
0x480 + Node ID |
예를 들어 Node ID가 1인 경우 다음 COB-ID를 사용합니다.
PDO |
COB-ID |
|---|---|
RPDO1 |
0x201 |
RPDO2 |
0x301 |
RPDO3 |
0x401 |
RPDO4 |
0x501 |
TPDO1 |
0x181 |
TPDO2 |
0x281 |
TPDO3 |
0x381 |
TPDO4 |
0x481 |
11.6.3 PDO Communication Parameter
PDO Communication Parameter는 PDO의 COB-ID, 전송 방식 및 이벤트 조건을 정의합니다.
RPDO Communication Parameter
Index |
Object Name |
|---|---|
0x1400 |
Receive PDO 1 Communication Parameter |
0x1401 |
Receive PDO 2 Communication Parameter |
0x1402 |
Receive PDO 3 Communication Parameter |
0x1403 |
Receive PDO 4 Communication Parameter |
일반적인 RPDO Communication Parameter 구조는 다음과 같습니다.
Sub-index |
Name |
Description |
|---|---|---|
0x00 |
Number of Entries |
Sub-index 개수 |
0x01 |
COB-ID |
RPDO Identifier |
0x02 |
Transmission Type |
전송 방식 |
0x03 |
Inhibit Time |
최소 전송 간격 |
0x05 |
Event Timer |
이벤트 타이머 |
TPDO Communication Parameter
Index |
Object Name |
|---|---|
0x1800 |
Transmit PDO 1 Communication Parameter |
0x1801 |
Transmit PDO 2 Communication Parameter |
0x1802 |
Transmit PDO 3 Communication Parameter |
0x1803 |
Transmit PDO 4 Communication Parameter |
일반적인 TPDO Communication Parameter 구조는 다음과 같습니다.
Sub-index |
Name |
Description |
|---|---|---|
0x00 |
Number of Entries |
Sub-index 개수 |
0x01 |
COB-ID |
TPDO Identifier |
0x02 |
Transmission Type |
전송 방식 |
0x03 |
Inhibit Time |
최소 전송 간격 |
0x05 |
Event Timer |
이벤트 타이머 |
11.6.4 Transmission Type
Transmission Type은 PDO 데이터가 언제 갱신되거나 전송되는지를 정의합니다.
Value |
Type |
RPDO 동작 |
TPDO 동작 |
|---|---|---|---|
0 |
Synchronous Acyclic |
SYNC 수신 시 RPDO 데이터를 적용 |
데이터 변경 후 SYNC 수신 시 TPDO 전송 |
1~240 |
Synchronous Cyclic |
지정된 SYNC 주기마다 데이터 적용 |
지정된 SYNC 주기마다 TPDO 전송 |
254 |
Manufacturer Specific Event |
제조사 정의 이벤트 기반 |
제조사 정의 이벤트 기반 |
255 |
Asynchronous Event |
수신 즉시 적용 |
이벤트 또는 Event Timer에 따라 전송 |
실시간 동기 제어가 필요한 경우에는 Synchronous Type을 사용하고, 이벤트 기반 상태 모니터링에는 Asynchronous Type을 사용할 수 있습니다.
11.6.5 PDO Mapping Object
PDO Mapping Object는 하나의 PDO에 포함될 Object Dictionary 항목을 정의합니다.
RPDO Mapping Object
Index |
Object Name |
|---|---|
0x1600 |
Receive PDO 1 Mapping |
0x1601 |
Receive PDO 2 Mapping |
0x1602 |
Receive PDO 3 Mapping |
0x1603 |
Receive PDO 4 Mapping |
TPDO Mapping Object
Index |
Object Name |
|---|---|
0x1A00 |
Transmit PDO 1 Mapping |
0x1A01 |
Transmit PDO 2 Mapping |
0x1A02 |
Transmit PDO 3 Mapping |
0x1A03 |
Transmit PDO 4 Mapping |
각 Mapping Object는 다음과 같은 구조를 사용합니다.
Sub-index |
Description |
|---|---|
0x00 |
매핑된 Object 개수 |
0x01 |
첫 번째 Mapping Entry |
0x02 |
두 번째 Mapping Entry |
… |
… |
0x08 |
여덟 번째 Mapping Entry |
CANopen PDO의 전체 데이터 길이는 최대 8 Byte이므로, Mapping Entry들의 총 Bit Length 합계는 64 bit를 초과할 수 없습니다.
11.6.6 Mapping Entry Format
PDO Mapping Entry는 32-bit 값으로 구성되며, 다음 형식을 사용합니다.
31 16 15 8 7 0
+----------------+------------+-----------+
| Object Index | Sub-index | Bit Length|
+----------------+------------+-----------+
Bit Range |
Description |
|---|---|
Bit 31~16 |
Object Index |
Bit 15~8 |
Sub-index |
Bit 7~0 |
Object Length(bit) |
Mapping Entry 계산식은 다음과 같습니다.
Mapping Entry = (Index << 16) | (Sub-index << 8) | Bit Length
예를 들어 Controlword(0x6040:00)를 16 bit로 매핑하는 경우:
Index = 0x6040
Sub-index = 0x00
Bit Length = 0x10
Mapping Entry = 0x60400010
11.6.7 주요 Mapping Entry 예시
Object |
Index |
Sub-index |
Length |
Mapping Entry |
|---|---|---|---|---|
Controlword |
0x6040 |
0x00 |
16 bit |
0x60400010 |
Statusword |
0x6041 |
0x00 |
16 bit |
0x60410010 |
Modes of Operation |
0x6060 |
0x00 |
8 bit |
0x60600008 |
Modes of Operation Display |
0x6061 |
0x00 |
8 bit |
0x60610008 |
Position Actual Value |
0x6064 |
0x00 |
32 bit |
0x60640020 |
Velocity Actual Value |
0x606C |
0x00 |
32 bit |
0x606C0020 |
Target Position |
0x607A |
0x00 |
32 bit |
0x607A0020 |
Target Velocity |
0x60FF |
0x00 |
32 bit |
0x60FF0020 |
Target Torque |
0x6071 |
0x00 |
16 bit |
0x60710010 |
Torque Actual Value |
0x6077 |
0x00 |
16 bit |
0x60770010 |
11.6.8 RPDO Mapping 예시
다음은 RPDO1에 Controlword, Target Position, Modes of Operation을 매핑하는 예입니다.
Sub-index |
Object |
Mapping Entry |
Size |
|---|---|---|---|
0x00 |
Number of Objects |
0x03 |
|
0x01 |
Controlword |
0x60400010 |
16 bit |
0x02 |
Target Position |
0x607A0020 |
32 bit |
0x03 |
Modes of Operation |
0x60600008 |
8 bit |
총 데이터 길이는 다음과 같습니다.
16 bit + 32 bit + 8 bit = 56 bit = 7 Byte
RPDO1 데이터 배열 예시는 다음과 같습니다.
Byte0~1 : Controlword
Byte2~5 : Target Position
Byte6 : Modes of Operation
11.6.9 TPDO Mapping 예시
다음은 TPDO1에 Statusword, Position Actual Value, Modes of Operation Display를 매핑하는 예입니다.
Sub-index |
Object |
Mapping Entry |
Size |
|---|---|---|---|
0x00 |
Number of Objects |
0x03 |
|
0x01 |
Statusword |
0x60410010 |
16 bit |
0x02 |
Position Actual Value |
0x60640020 |
32 bit |
0x03 |
Modes of Operation Display |
0x60610008 |
8 bit |
총 데이터 길이는 다음과 같습니다.
16 bit + 32 bit + 8 bit = 56 bit = 7 Byte
TPDO1 데이터 배열 예시는 다음과 같습니다.
Byte0~1 : Statusword
Byte2~5 : Position Actual Value
Byte6 : Modes of Operation Display
11.6.10 PDO Mapping 변경 절차
PDO Mapping을 변경할 때에는 반드시 안전한 상태에서 다음 절차에 따라 수행하십시오.
NMT 상태를 Pre-operational로 전환합니다.
해당 PDO를 비활성화합니다.
Mapping Object의 Sub-index
0x00에0을 기록합니다.필요한 Mapping Entry를 Sub-index
0x01부터 순서대로 기록합니다.Mapping Object의 Sub-index
0x00에 Mapping Entry 개수를 기록합니다.해당 PDO를 다시 활성화합니다.
NMT 상태를 Operational로 전환합니다.
PDO 데이터 송수신이 정상적으로 동작하는지 확인합니다.
11.6.11 PDO 비활성화 및 활성화
PDO를 비활성화하려면 Communication Parameter의 COB-ID에서 Bit 31을
1로 설정합니다.
PDO Disable = COB-ID | 0x80000000
PDO를 활성화하려면 COB-ID의 Bit 31을 0으로 설정합니다.
PDO Enable = COB-ID & 0x7FFFFFFF
예를 들어 Node ID가 1인 RPDO1의 기본 COB-ID는 0x201입니다.
Disable RPDO1: 0x80000201
Enable RPDO1: 0x00000201
11.6.12 PDO Mapping 설정 예시
RPDO1에 Controlword와 Target Position을 매핑하는 SDO 설정 순서는 다음과 같습니다.
Step |
Object |
Value |
Description |
|---|---|---|---|
1 |
0x1400:01 |
0x80000201 |
RPDO1 비활성화 |
2 |
0x1600:00 |
0x00 |
Mapping 개수 초기화 |
3 |
0x1600:01 |
0x60400010 |
Controlword 매핑 |
4 |
0x1600:02 |
0x607A0020 |
Target Position 매핑 |
5 |
0x1600:00 |
0x02 |
Mapping Object 개수 설정 |
6 |
0x1400:01 |
0x00000201 |
RPDO1 활성화 |
TPDO1에 Statusword와 Position Actual Value를 매핑하는 SDO 설정 순서는 다음과 같습니다.
Step |
Object |
Value |
Description |
|---|---|---|---|
1 |
0x1800:01 |
0x80000181 |
TPDO1 비활성화 |
2 |
0x1A00:00 |
0x00 |
Mapping 개수 초기화 |
3 |
0x1A00:01 |
0x60410010 |
Statusword 매핑 |
4 |
0x1A00:02 |
0x60640020 |
Position Actual Value 매핑 |
5 |
0x1A00:00 |
0x02 |
Mapping Object 개수 설정 |
6 |
0x1800:01 |
0x00000181 |
TPDO1 활성화 |
11.6.13 PDO Mapping 사용 시 주의사항
PDO Mapping 설정 시 다음 사항을 준수하십시오.
PDO Mapping 변경은 Pre-operational 상태에서 수행하십시오.
Mapping Entry의 총 데이터 길이는 64 bit를 초과하지 않아야 합니다.
Object의 PDO Mapping 속성이 지원되는지 확인하십시오.
Read Only Object는 RPDO에 매핑하지 마십시오.
Write 가능한 제어 Object는 TPDO에 매핑하지 마십시오.
PDO를 비활성화한 후 Mapping 설정을 변경하고 다시 활성화하십시오.
Mapping 변경 후 실제 수신 및 송신 데이터 길이가 Master 설정과 일치하는지 확인하십시오.
Node ID 변경 시 COB-ID도 함께 확인하십시오.
중요
PDO Mapping은 실시간 제어 데이터의 구조를 결정하는 핵심 설정입니다. Mapping 설정이 Host Controller의 데이터 구조와 일치하지 않으면 잘못된 제어 명령이 전달되거나 피드백 데이터가 잘못 해석될 수 있습니다. 설정 변경 후에는 반드시 무부하 상태에서 PDO 송수신을 검증하십시오.
11.7 Default COB-ID
COB-ID(Communication Object Identifier)는 CANopen 메시지의 종류와 대상 Node를 식별하기 위한 CAN Identifier입니다.
SF시리즈 CANopen은 Standard CAN 2.0A의 11-bit Identifier를 사용하며, 대부분의 CANopen Object는 다음과 같은 기본 COB-ID 규칙을 따릅니다.
COB-ID = Function Code + Node ID
단, NMT와 SYNC와 같이 네트워크 전체에 적용되는 메시지는 Node ID를 포함하지 않는 고정 COB-ID를 사용합니다.
11.7.1 COB-ID 기본 구조
CANopen의 11-bit COB-ID는 일반적으로 다음과 같이 구성됩니다.
Bit10 Bit7 Bit6 Bit0
+------------------------+------------------------+
| Function Code | Node ID |
+------------------------+------------------------+
Field |
Bit |
Description |
|---|---|---|
Function Code |
Bit10~Bit7 |
메시지 종류 |
Node ID |
Bit6~Bit0 |
대상 Node 번호 |
Node ID는 일반적으로 1 ~ 127 범위를 사용합니다.
11.7.2 Default COB-ID Table
다음 표는 SF시리즈 CANopen에서 사용하는 기본 COB-ID입니다.
Communication Object |
Direction |
Default COB-ID |
Description |
|---|---|---|---|
NMT |
Master → Slave |
0x000 |
네트워크 상태 제어 |
SYNC |
Master → Slave |
0x080 |
동기화 메시지 |
EMCY |
Slave → Master |
0x080 + Node ID |
Emergency 메시지 |
TPDO1 |
Slave → Master |
0x180 + Node ID |
Transmit PDO 1 |
RPDO1 |
Master → Slave |
0x200 + Node ID |
Receive PDO 1 |
TPDO2 |
Slave → Master |
0x280 + Node ID |
Transmit PDO 2 |
RPDO2 |
Master → Slave |
0x300 + Node ID |
Receive PDO 2 |
TPDO3 |
Slave → Master |
0x380 + Node ID |
Transmit PDO 3 |
RPDO3 |
Master → Slave |
0x400 + Node ID |
Receive PDO 3 |
TPDO4 |
Slave → Master |
0x480 + Node ID |
Transmit PDO 4 |
RPDO4 |
Master → Slave |
0x500 + Node ID |
Receive PDO 4 |
SDO Response |
Slave → Master |
0x580 + Node ID |
SDO Upload/Download 응답 |
SDO Request |
Master → Slave |
0x600 + Node ID |
SDO Upload/Download 요청 |
Heartbeat / Boot-up |
Slave → Master |
0x700 + Node ID |
Node 상태 메시지 |
11.7.3 Node ID별 COB-ID 예시
Node ID = 1
Communication Object |
COB-ID |
|---|---|
NMT |
0x000 |
SYNC |
0x080 |
EMCY |
0x081 |
TPDO1 |
0x181 |
RPDO1 |
0x201 |
TPDO2 |
0x281 |
RPDO2 |
0x301 |
TPDO3 |
0x381 |
RPDO3 |
0x401 |
TPDO4 |
0x481 |
RPDO4 |
0x501 |
SDO Response |
0x581 |
SDO Request |
0x601 |
Heartbeat / Boot-up |
0x701 |
Node ID = 5
Communication Object |
COB-ID |
|---|---|
NMT |
0x000 |
SYNC |
0x080 |
EMCY |
0x085 |
TPDO1 |
0x185 |
RPDO1 |
0x205 |
TPDO2 |
0x285 |
RPDO2 |
0x305 |
TPDO3 |
0x385 |
RPDO3 |
0x405 |
TPDO4 |
0x485 |
RPDO4 |
0x505 |
SDO Response |
0x585 |
SDO Request |
0x605 |
Heartbeat / Boot-up |
0x705 |
11.7.4 Communication Object별 COB-ID 설정 Object
일부 COB-ID는 Object Dictionary에서 확인하거나 설정할 수 있습니다.
Object |
Index |
Sub-index |
Description |
|---|---|---|---|
SYNC COB-ID |
0x1005 |
0x00 |
SYNC 메시지 COB-ID |
EMCY COB-ID |
0x1014 |
0x00 |
Emergency 메시지 COB-ID |
SDO Server Parameter |
0x1200 |
0x01~0x02 |
SDO Request / Response COB-ID |
RPDO1 Communication Parameter |
0x1400 |
0x01 |
RPDO1 COB-ID |
RPDO2 Communication Parameter |
0x1401 |
0x01 |
RPDO2 COB-ID |
RPDO3 Communication Parameter |
0x1402 |
0x01 |
RPDO3 COB-ID |
RPDO4 Communication Parameter |
0x1403 |
0x01 |
RPDO4 COB-ID |
TPDO1 Communication Parameter |
0x1800 |
0x01 |
TPDO1 COB-ID |
TPDO2 Communication Parameter |
0x1801 |
0x01 |
TPDO2 COB-ID |
TPDO3 Communication Parameter |
0x1802 |
0x01 |
TPDO3 COB-ID |
TPDO4 Communication Parameter |
0x1803 |
0x01 |
TPDO4 COB-ID |
11.7.5 PDO COB-ID Enable / Disable Bit
PDO Communication Parameter의 COB-ID는 32-bit 값으로 관리됩니다.
이때 Bit31은 해당 PDO의 유효 여부를 나타냅니다.
Bit |
Value |
Description |
|---|---|---|
Bit31 |
0 |
PDO Enable |
Bit31 |
1 |
PDO Disable |
예를 들어 Node ID가 1인 RPDO1의 기본 COB-ID는 0x201입니다.
RPDO1 Enable = 0x00000201
RPDO1 Disable = 0x80000201
Node ID가 1인 TPDO1의 기본 COB-ID는 0x181입니다.
TPDO1 Enable = 0x00000181
TPDO1 Disable = 0x80000181
참고
PDO COB-ID의 CAN-ID 부분은 Node ID에 따라 결정됩니다. PDO 설정 시 일반적으로 사용자는 COB-ID의 유효 비트(Bit31)를 이용하여 PDO를 활성화하거나 비활성화합니다.
11.7.6 NMT COB-ID
NMT(Network Management)는 CANopen 네트워크 상태를 제어하기 위한 메시지입니다.
NMT는 항상 고정 COB-ID 0x000을 사용합니다.
COB-ID |
DLC |
Byte0 |
Byte1 |
|---|---|---|---|
0x000 |
2 |
Command |
Node ID |
Byte1의 Node ID가 0이면 네트워크에 연결된 모든 Node에 명령을
적용합니다.
Byte1 |
Target |
|---|---|
0x00 |
All Nodes |
0x01~0x7F |
지정 Node |
11.7.7 SYNC COB-ID
SYNC 메시지는 동기 PDO 통신을 위해 사용됩니다.
기본 COB-ID는 0x080입니다.
Object |
Index |
Default |
|---|---|---|
COB-ID SYNC Message |
0x1005 |
0x00000080 |
SYNC 메시지는 일반적으로 Data Field를 사용하지 않습니다.
COB-ID : 0x080
DLC : 0
Data : 없음
11.7.8 EMCY COB-ID
EMCY(Emergency) 메시지는 장치 내부 오류 발생 시 SF시리즈가 Master로 전송하는 비동기 메시지입니다.
기본 COB-ID는 다음과 같습니다.
EMCY COB-ID = 0x080 + Node ID
예를 들어 Node ID가 1인 경우 EMCY COB-ID는 0x081입니다.
Node ID |
EMCY COB-ID |
|---|---|
1 |
0x081 |
2 |
0x082 |
5 |
0x085 |
10 |
0x08A |
11.7.9 SDO COB-ID
SDO(Service Data Object)는 Object Dictionary를 읽거나 쓰기 위해 사용합니다.
Direction |
COB-ID |
|---|---|
Master → SF시리즈 |
0x600 + Node ID |
SF시리즈 → Master |
0x580 + Node ID |
Node ID가 1인 경우 SDO COB-ID는 다음과 같습니다.
Direction |
COB-ID |
|---|---|
Master → SF시리즈 |
0x601 |
SF시리즈 → Master |
0x581 |
11.7.10 Heartbeat / Boot-up COB-ID
Heartbeat와 Boot-up 메시지는 동일한 COB-ID를 사용합니다.
Heartbeat / Boot-up COB-ID = 0x700 + Node ID
Boot-up 메시지는 장치가 초기화 후 Pre-operational 상태에 진입했음을 나타냅니다.
COB-ID |
DLC |
Data |
|---|---|---|
0x700 + Node ID |
1 |
0x00 |
Heartbeat 메시지는 현재 NMT 상태를 주기적으로 전송합니다.
Data |
NMT State |
|---|---|
0x00 |
Boot-up |
0x04 |
Stopped |
0x05 |
Operational |
0x7F |
Pre-operational |
11.7.11 COB-ID 우선순위
CAN Bus에서는 COB-ID 값이 낮을수록 높은 우선순위를 가집니다.
따라서 일반적으로 다음 순서로 우선순위가 높습니다.
NMT < SYNC < EMCY < PDO < SDO < Heartbeat
Object |
COB-ID Range |
Priority |
|---|---|---|
NMT |
0x000 |
Highest |
SYNC |
0x080 |
High |
EMCY |
0x080 + Node ID |
High |
PDO |
0x180 ~ 0x57F |
Medium |
SDO |
0x580 ~ 0x67F |
Low |
Heartbeat |
0x700 ~ 0x77F |
Lowest |
참고
CAN Identifier 값이 낮을수록 Bus Arbitration에서 우선순위가 높습니다. 따라서 긴급 메시지인 EMCY는 SDO 및 Heartbeat보다 우선적으로 전송됩니다.
11.7.12 COB-ID 사용 시 주의사항
COB-ID를 사용할 때에는 다음 사항을 확인하십시오.
동일 CAN Bus에서 Node ID가 중복되지 않아야 합니다.
Node ID가 변경되면 Node ID 기반 COB-ID도 함께 변경됩니다.
NMT와 SYNC는 고정 COB-ID를 사용합니다.
SDO Request와 SDO Response의 COB-ID 방향을 혼동하지 마십시오.
PDO COB-ID 변경 또는 PDO Enable/Disable 설정 후에는 통신 재시작이 필요할 수 있습니다.
PDO Mapping 설정과 Master의 PDO 설정이 일치해야 합니다.
Heartbeat COB-ID는 Boot-up 메시지와 동일합니다.
중요
COB-ID는 CANopen 네트워크에서 메시지의 종류, 대상 Node 및 우선순위를 결정하는 핵심 값입니다. Host Controller는 각 Node의 COB-ID를 정확히 계산하고, PDO Mapping 및 SDO 통신 설정과 일치하도록 관리해야 합니다.
## 11.8 NMT Command
NMT(Network Management)는 CANopen 네트워크의 Node 상태를 제어하기 위한 관리 명령입니다.
Host Controller는 NMT Command를 이용하여 SF시리즈 Node를 Operational, Pre-operational, Stopped 상태로 전환하거나 Node를 재시작할 수 있습니다.
NMT 메시지는 CANopen Master에서 Slave로 전송되며, 항상 고정 COB-ID
0x000을 사용합니다.
11.8.1 NMT Message Format
NMT Command는 항상 2 Byte 데이터로 구성됩니다.
Field |
Value |
|---|---|
COB-ID |
0x000 |
DLC |
2 Byte |
Byte0 |
Command Specifier |
Byte1 |
Node ID |
COB-ID : 0x000
DLC : 2
Byte0 : NMT Command
Byte1 : Node ID
Byte |
Name |
Description |
|---|---|---|
Byte0 |
CMD |
NMT 명령 코드 |
Byte1 |
Node ID |
대상 Node ID |
Node ID가 0x00이면 네트워크에 연결된 모든 Node에 명령이
적용됩니다.
Node ID |
Target |
|---|---|
0x00 |
All Nodes |
0x01 ~ 0x7F |
지정 Node |
11.8.2 NMT Command Code
Command |
Value |
Description |
|---|---|---|
Start Remote Node |
0x01 |
Node를 Operational 상태로 전환 |
Stop Remote Node |
0x02 |
Node를 Stopped 상태로 전환 |
Enter Pre-operational |
0x80 |
Node를 Pre-operational 상태로 전환 |
Reset Node |
0x81 |
Node 전체 재시작 |
Reset Communication |
0x82 |
통신 기능 재시작 |
11.8.3 NMT State
SF시리즈 CANopen Node는 다음 NMT 상태를 가집니다.
State |
Description |
|---|---|
Initialization |
전원 인가 후 초기화 상태 |
Pre-operational |
SDO 설정 가능, PDO 통신 불가 |
Operational |
SDO 및 PDO 통신 가능 |
Stopped |
NMT 및 Heartbeat만 가능 |
전원 인가 후 장치가 초기화를 완료하면 일반적으로 Pre-operational 상태로 진입합니다.
11.8.4 NMT State Transition
Power ON
│
▼
Initialization
│
│ Boot-up Message
▼
Pre-operational
│
│ NMT Start Remote Node
▼
Operational
│
│ NMT Stop Remote Node
▼
Stopped
Pre-operational 상태에서는 SDO를 이용하여 파라미터 설정, PDO Mapping 설정 및 통신 설정을 수행할 수 있습니다.
Operational 상태에서는 PDO를 이용한 실시간 제어 및 피드백 통신이 가능합니다.
11.8.5 상태별 사용 가능한 Communication Object
Communication Object |
Initialization |
Pre-operational |
Operational |
Stopped |
|---|---|---|---|---|
NMT |
✓ |
✓ |
✓ |
|
Boot-up |
✓ |
|||
SDO |
✓ |
✓ |
||
PDO |
✓ |
|||
SYNC |
✓ |
✓ |
||
EMCY |
✓ |
✓ |
||
Heartbeat |
✓ |
✓ |
✓ |
참고
PDO 통신은 반드시 Operational 상태에서만 수행하십시오. Pre-operational 상태에서는 PDO Mapping 및 통신 파라미터 설정을 수행할 수 있지만, 실제 PDO 데이터 교환은 이루어지지 않습니다.
11.8.6 NMT Command Frame 예시
Start Remote Node
Node ID가 1인 SF시리즈를 Operational 상태로 전환합니다.
COB-ID |
DLC |
Data |
|---|---|---|
0x000 |
2 |
01 01 |
00 01 01
Start All Nodes
모든 Node를 Operational 상태로 전환합니다.
COB-ID |
DLC |
Data |
|---|---|---|
0x000 |
2 |
01 00 |
00 01 00
Stop Remote Node
Node ID가 1인 SF시리즈를 Stopped 상태로 전환합니다.
COB-ID |
DLC |
Data |
|---|---|---|
0x000 |
2 |
02 01 |
00 02 01
Enter Pre-operational
Node ID가 1인 SF시리즈를 Pre-operational 상태로 전환합니다.
COB-ID |
DLC |
Data |
|---|---|---|
0x000 |
2 |
80 01 |
00 80 01
Reset Node
Node ID가 1인 SF시리즈를 재시작합니다.
COB-ID |
DLC |
Data |
|---|---|---|
0x000 |
2 |
81 01 |
00 81 01
Reset Communication
Node ID가 1인 SF시리즈의 통신 기능을 재시작합니다.
COB-ID |
DLC |
Data |
|---|---|---|
0x000 |
2 |
82 01 |
00 82 01
11.8.7 Boot-up Message
Node가 초기화를 완료하면 Boot-up 메시지를 전송합니다.
Boot-up 메시지는 Node가 정상적으로 초기화되어 Pre-operational 상태에 진입했음을 나타냅니다.
COB-ID |
DLC |
Data |
|---|---|---|
0x700 + Node ID |
1 |
0x00 |
Node ID가 1인 경우 Boot-up 메시지는 다음과 같습니다.
COB-ID |
DLC |
Data |
|---|---|---|
0x701 |
1 |
00 |
701 00
Host Controller는 전원 인가 또는 Reset 명령 이후 Boot-up 메시지를 수신하여 Node 초기화 완료 여부를 확인할 수 있습니다.
11.8.8 Heartbeat를 이용한 NMT 상태 확인
Heartbeat 메시지는 Node의 현재 NMT 상태를 주기적으로 전송합니다.
COB-ID |
DLC |
Data |
|---|---|---|
0x700 + Node ID |
1 |
NMT State |
Heartbeat Data 값은 다음과 같습니다.
Data |
NMT State |
|---|---|
0x00 |
Boot-up |
0x04 |
Stopped |
0x05 |
Operational |
0x7F |
Pre-operational |
예를 들어 Node ID가 1인 장치가 Operational 상태이면 다음 Heartbeat
메시지를 전송할 수 있습니다.
701 05
11.8.9 NMT Command 처리 특성
NMT Command는 일반적으로 별도의 응답 프레임을 반환하지 않습니다.
따라서 Host Controller는 다음 방법으로 명령 처리 결과를 확인해야 합니다.
확인 방법 |
Description |
|---|---|
Boot-up Message |
Reset 후 초기화 완료 확인 |
Heartbeat |
현재 NMT 상태 확인 |
SDO Read |
상태 관련 Object 확인 |
PDO Feedback |
Operational 상태에서 실시간 상태 확인 |
NMT Start 명령 후에는 Heartbeat가 0x05를 반환하는지 확인하여
Operational 상태 진입 여부를 판단할 수 있습니다.
11.8.10 권장 NMT 제어 순서
SF시리즈 CANopen 시스템의 일반적인 NMT 제어 순서는 다음과 같습니다.
Power ON
│
▼
Wait Boot-up Message
│
▼
Pre-operational
│
├─ SDO Parameter Setting
├─ PDO Communication Setting
└─ Heartbeat Setting
│
▼
NMT Start Remote Node
│
▼
Operational
│
├─ RPDO Control Command
├─ TPDO Feedback
└─ Heartbeat Monitoring
11.8.11 PDO 설정 시 NMT 사용
PDO Mapping 또는 PDO Communication Parameter를 변경할 때에는 장치를 Pre-operational 상태로 전환한 후 설정하는 것을 권장합니다.
권장 절차는 다음과 같습니다.
NMT Enter Pre-operational 전송
PDO 비활성화
PDO Mapping 변경
PDO Communication Parameter 설정
PDO 활성화
NMT Start Remote Node 전송
Operational 상태 확인
11.8.12 Reset Node와 Reset Communication 차이
Command |
Value |
Description |
|---|---|---|
Reset Node |
0x81 |
장치 전체 재시작 |
Reset Communication |
0x82 |
CANopen 통신부 재시작 |
Reset Node는 장치 전체 초기화를 수행하므로 제어 상태와 내부 동작이 모두 재초기화될 수 있습니다.
Reset Communication은 통신 관련 설정을 재초기화할 때 사용하며, Node ID, Baud Rate, PDO 설정 등 통신 설정 변경 후 적용 목적으로 사용할 수 있습니다.
11.8.13 NMT 사용 시 주의사항
NMT Command를 사용할 때에는 다음 사항을 확인하십시오.
Node ID가 올바른지 확인하십시오.
Node ID
0x00은 모든 Node에 명령을 적용하므로 주의하십시오.PDO 통신은 Operational 상태에서만 수행하십시오.
PDO Mapping 변경은 Pre-operational 상태에서 수행하십시오.
Reset Node 명령은 장치 동작을 중단시킬 수 있으므로 운전 중 사용하지 마십시오.
NMT Command는 별도 응답이 없으므로 Heartbeat 또는 Boot-up 메시지로 상태를 확인하십시오.
Fault 상태에서는 NMT 상태와 CiA 402 상태가 서로 다를 수 있으므로 Statusword도 함께 확인하십시오.
중요
NMT는 CANopen 네트워크 전체의 동작 상태를 제어하는 핵심 기능입니다. 잘못된 NMT Command는 모든 Node의 통신 상태를 변경하거나 운전 중인 장치를 정지시킬 수 있으므로, 실제 장비에서는 반드시 대상 Node ID와 현재 운전 상태를 확인한 후 명령을 전송하십시오.
11.9 EMCY Error Code
EMCY(Emergency)는 CANopen Node에서 오류가 발생했을 때 Master로 즉시 전송되는 비동기 오류 메시지입니다.
SDO Abort Code가 요청에 대한 응답으로 반환되는 통신 오류인 반면, EMCY는 장치 내부 오류가 발생했을 때 Host Controller의 요청과 관계없이 전송됩니다.
SF시리즈는 EMCY 메시지를 생성하는 EMCY Producer로 동작하며, 다른 Node에서 발생한 EMCY 메시지는 처리하지 않습니다.
11.9.1 EMCY Message Format
EMCY 메시지는 다음 형식을 사용합니다.
Field |
Value |
|---|---|
COB-ID |
0x080 + Node ID |
DLC |
8 Byte |
Byte0~1 |
Emergency Error Code |
Byte2 |
Error Register |
Byte3~7 |
Reserved |
COB-ID : 0x080 + Node ID
DLC : 8
Byte0 : Emergency Error Code Low Byte
Byte1 : Emergency Error Code High Byte
Byte2 : Error Register
Byte3 : Reserved
Byte4 : Reserved
Byte5 : Reserved
Byte6 : Reserved
Byte7 : Reserved
EMCY Error Code는 Little-Endian 형식으로 전송됩니다.
예를 들어 Error Code가 0x3210인 경우 EMCY Data Field의 Byte0~1은
다음과 같이 전송됩니다.
Error Code : 0x3210
Byte0 = 0x10
Byte1 = 0x32
11.9.2 EMCY COB-ID
EMCY COB-ID는 Node ID를 기준으로 다음과 같이 계산합니다.
EMCY COB-ID = 0x080 + Node ID
Node ID |
EMCY COB-ID |
|---|---|
1 |
0x081 |
2 |
0x082 |
3 |
0x083 |
4 |
0x084 |
5 |
0x085 |
10 |
0x08A |
127 |
0x0FF |
예를 들어 Node ID가 1인 장치에서 오류가 발생하면, Master는 COB-ID
0x081의 EMCY 메시지를 수신합니다.
11.9.3 EMCY 관련 Object
EMCY와 관련된 주요 Object는 다음과 같습니다.
Index |
Object |
Description |
|---|---|---|
0x1001 |
Error Register |
현재 오류 상태 |
0x1003 |
Pre-defined Error Field |
오류 이력 |
0x1014 |
COB-ID EMCY |
EMCY COB-ID |
0x603F |
Error Code |
현재 장치 오류 코드 |
0x6041 |
Statusword |
CiA 402 Fault 상태 확인 |
Host Controller는 EMCY 메시지를 수신한 후 0x603F를 읽어 장치 오류
코드를 확인할 수 있습니다.
11.9.4 Error Register
Error Register(Object 0x1001)는 장치의 오류 유형을 비트 단위로 표시합니다.
Bit |
Value |
Description |
|---|---|---|
Bit0 |
0x01 |
Generic Error |
Bit1 |
0x02 |
Current Error |
Bit2 |
0x04 |
Voltage Error |
Bit3 |
0x08 |
Temperature Error |
Bit4 |
0x10 |
Communication Error |
Bit5 |
0x20 |
Device Profile Specific Error |
Bit6 |
0x40 |
Reserved |
Bit7 |
0x80 |
Manufacturer Specific Error |
예를 들어 Error Register 값이 0x04인 경우 전압 관련 오류가 발생한
것으로 판단할 수 있습니다.
11.9.5 EMCY Frame 예시
예시 1: Node ID 1, Bus Overvoltage
장치에서 Bus Overvoltage 오류 0x3210이 발생한 경우 EMCY 메시지는
다음과 같이 표현할 수 있습니다.
Field |
Value |
|---|---|
COB-ID |
0x081 |
DLC |
8 |
Error Code |
0x3210 |
Error Register |
0x04 |
COB-ID : 081
Data : 10 32 04 00 00 00 00 00
예시 2: Node ID 1, CAN Heartbeat Error
CAN Heartbeat 오류 0x8130이 발생한 경우 EMCY 메시지는 다음과 같이
표현할 수 있습니다.
Field |
Value |
|---|---|
COB-ID |
0x081 |
DLC |
8 |
Error Code |
0x8130 |
Error Register |
0x10 |
COB-ID : 081
Data : 30 81 10 00 00 00 00 00
참고
위 EMCY Frame은 데이터 구조를 설명하기 위한 예시입니다. 실제 Error Register 값은 장치 내부 오류 상태에 따라 달라질 수 있습니다.
11.9.6 SF시리즈 EMCY / Device Error Code Table
다음 표는 SF시리즈에서 사용하는 주요 EMCY / Device Error Code입니다.
Error Code |
Category |
Message |
Description |
|---|---|---|---|
0x0000 |
Normal |
Ready to switch on |
정상 상태 |
0x2214 |
Current |
Motor current is over current |
모터 전류 과전류 |
0x2250 |
Current |
Sum of motor three phase current exceed the limit |
모터 3상 전류 합계 초과 |
0x2341 |
Current |
U phase over current |
U상 과전류 |
0x2342 |
Current |
V phase over current |
V상 과전류 |
0x2343 |
Current |
W phase over current |
W상 과전류 |
0x3210 |
Voltage |
Bus voltage is overvoltage |
DC Bus 과전압 |
0x3220 |
Voltage |
Bus voltage is undervoltage |
DC Bus 저전압 |
0x4110 |
Temperature |
Temperature of power component is too high |
파워부 온도 과열 |
0x7121 |
Motor / Mechanism |
Blocked motor rotation |
모터 스톨 또는 회전 막힘 |
0x7305 |
Encoder |
Load-side single-turn encoder data error |
부하측 단일 회전 엔코더 데이터 오류 |
0x7306 |
Encoder |
Motor-side single-turn encoder data error |
모터측 단일 회전 엔코더 데이터 오류 |
0x730D |
Battery |
Battery warning error |
배터리 경고 오류 |
0x730F |
Battery |
Battery low voltage |
배터리 저전압 |
0x7311 |
Encoder / Position |
Motor-end sampled position error exceeds limit |
모터측 샘플링 위치 오차 초과 |
0x7314 |
Encoder / Battery |
Multi-turn battery reconnection detected |
다회전 카운트 배터리 재접속 감지 |
0x7315 |
Encoder / Position |
Load-side sampled position error exceeds limit |
부하측 샘플링 위치 오차 초과 |
0x7350 |
Encoder |
Motor-side encoder type is not supported |
모터측 엔코더 타입 미지원 |
0x7374 |
Encoder |
Multi-turn position error |
다회전 위치 오류 |
0x7377 |
Encoder |
Reset pin error detected |
Reset Pin 오류 감지 |
0x737A |
Encoder |
Load-side single-turn encoder startup error |
부하측 단일 회전 엔코더 시작 오류 |
0x737E |
Encoder |
Motor-side single-turn encoder startup error |
모터측 단일 회전 엔코더 시작 오류 |
0x8130 |
Communication |
CAN Heartbeat error |
CAN Heartbeat 오류 |
0x8400 |
Velocity |
Velocity error exceeds limit |
속도 오차 한계 초과 |
0x8401 |
Velocity |
Motor velocity exceeds limit |
모터 속도 한계 초과 |
0x8500 |
Position |
Position error exceeds limit |
위치 오차 한계 초과 |
0xA000 |
Communication |
Master station goes offline |
Master 연결 끊김 |
0xF004 |
EtherCAT |
EtherCAT initialization error |
EtherCAT 초기화 오류 |
0xF005 |
Safety |
STO function is activated |
STO 기능 활성화 |
0xF006 |
Encoder |
Multi-turn circle count error |
다회전 카운트 오류 |
0xF008 |
Voltage |
Bus voltage lower than minimum supply voltage |
Bus 전압이 최소 허용 전압보다 낮음 |
11.9.7 Error Code 분류
SF시리즈 EMCY Error Code는 오류 원인에 따라 다음과 같이 분류할 수 있습니다.
Category |
Error Code |
|---|---|
Current Error |
0x2214, 0x2250, 0x2341, 0x2342, 0x2343 |
Voltage Error |
0x3210, 0x3220, 0xF008 |
Temperature Error |
0x4110 |
Motor / Mechanism Error |
0x7121 |
Encoder Error |
0x7305, 0x7306, 0x7311, 0x7314, 0x7315, 0x7350, 0x7374, 0x7377, 0x737A, 0x737E, 0xF006 |
Battery Error |
0x730D, 0x730F |
Communication Error |
0x8130, 0xA000 |
Motion Error |
0x8400, 0x8401, 0x8500 |
Safety Error |
0xF005 |
EtherCAT Error |
0xF004 |
11.9.8 EMCY 수신 처리 절차
Host Controller는 EMCY 메시지를 수신하면 다음 절차에 따라 처리하는 것을 권장합니다.
EMCY COB-ID에서 Node ID를 확인합니다.
Byte0~1의 Emergency Error Code를 해석합니다.
Byte2의 Error Register를 확인합니다.
Statusword(0x6041)를 읽어 Fault 상태를 확인합니다.
Error Code(0x603F)를 읽어 현재 오류 코드를 확인합니다.
Motion Command를 정지합니다.
오류 원인을 제거합니다.
Fault Reset을 수행합니다.
Enable Operation 절차를 다시 수행합니다.
11.9.9 EMCY 처리 로직
Receive EMCY
│
▼
Check COB-ID
│
▼
Identify Node ID
│
▼
Read Error Code
│
▼
Check Error Register
│
▼
Stop Motion Command
│
▼
Remove Error Cause
│
▼
Fault Reset
│
▼
Enable Operation
11.9.10 Fault Reset
EMCY가 발생하여 장치가 Fault 상태에 진입한 경우, 오류 원인을 제거한 뒤 Fault Reset을 수행해야 합니다.
Fault Reset은 Controlword(Object 0x6040)를 이용하여 수행합니다.
Step |
Controlword |
Description |
|---|---|---|
1 |
0x0080 |
Fault Reset |
2 |
0x0006 |
Shutdown |
3 |
0x0007 |
Switch On |
4 |
0x000F |
Enable Operation |
Fault Reset 후에도 동일 오류가 반복되면, 오류 원인이 제거되지 않은 상태로 판단해야 합니다.
11.9.11 EMCY 사용 시 주의사항
EMCY Error Code를 처리할 때에는 다음 사항을 확인하십시오.
EMCY 메시지는 오류 발생 시 1회 전송될 수 있으므로 수신 즉시 저장하십시오.
동일 오류가 반복될 경우 Error Code와 Error Register를 함께 기록하십시오.
Fault Reset 전에 반드시 오류 원인을 제거하십시오.
과전류, 과전압, 과온도 오류는 하드웨어 상태를 먼저 점검하십시오.
Encoder 또는 Battery 오류는 배선, 배터리 상태, 영점 및 엔코더 설정을 확인하십시오.
통신 오류는 CAN 배선, Node ID, Baud Rate, Heartbeat 설정을 확인하십시오.
EMCY 메시지와 함께 Heartbeat 및 Statusword를 모니터링하십시오.
중요
EMCY는 장치 보호를 위한 긴급 오류 메시지입니다. EMCY를 수신한 상태에서 원인을 제거하지 않고 Fault Reset만 반복하면 장치 손상 또는 예기치 않은 움직임이 발생할 수 있습니다. Host Controller는 EMCY Error Code, Error Register, Statusword 및 0x603F Error Code를 함께 확인하여 안전하게 복구해야 합니다.
11.10 SDO Abort Code
SDO Abort Code는 Host Controller가 SDO(Service Data Object)를 통해 Object Dictionary에 접근할 때, SF시리즈가 해당 요청을 정상적으로 처리할 수 없는 경우 반환하는 오류 코드입니다.
SDO Abort는 다음과 같은 경우에 발생할 수 있습니다.
존재하지 않는 Object Index 접근
존재하지 않는 Sub-index 접근
읽기 전용 Object에 Write 시도
쓰기 전용 Object에 Read 시도
데이터 타입 또는 데이터 길이 불일치
PDO Mapping 불가능한 Object를 Mapping 시도
허용 범위를 벗어난 값 입력
현재 NMT 상태 또는 장치 상태에서 허용되지 않는 접근
Password 또는 Command Code 오류
SDO Abort Code는 CANopen 통신 오류를 진단하는 핵심 정보이므로, Host
Controller는 SDO Response의 Byte0이 0x80인지 항상 확인해야 합니다.
11.10.1 SDO Abort Response Format
SDO Abort Response는 다음과 같은 8 Byte 형식을 사용합니다.
Byte |
Name |
Description |
|---|---|---|
Byte0 |
Abort Command Specifier |
항상 |
Byte1 |
Index Low Byte |
Object Index Low Byte |
Byte2 |
Index High Byte |
Object Index High Byte |
Byte3 |
Sub-index |
Object Sub-index |
Byte4 |
Abort Code Byte0 |
Abort Code Low Byte |
Byte5 |
Abort Code Byte1 |
Abort Code |
Byte6 |
Abort Code Byte2 |
Abort Code |
Byte7 |
Abort Code Byte3 |
Abort Code High Byte |
Abort Code는 Little-Endian 형식으로 전송됩니다.
COB-ID : 0x580 + Node ID
DLC : 8
Byte0 : 0x80
Byte1 : Index Low Byte
Byte2 : Index High Byte
Byte3 : Sub-index
Byte4 : Abort Code Byte0
Byte5 : Abort Code Byte1
Byte6 : Abort Code Byte2
Byte7 : Abort Code Byte3
11.10.2 SDO Abort Response 예시
예를 들어 Host Controller가 0x6040:00에 잘못된 방식으로 접근하여
Abort Code 0x06010002가 발생한 경우, 응답은 다음과 같이
나타납니다.
COB-ID : 0x581
Data : 80 40 60 00 02 00 01 06
해석은 다음과 같습니다.
항목 |
값 |
설명 |
|---|---|---|
COB-ID |
0x581 |
Node ID 1의 SDO Response |
Byte0 |
0x80 |
SDO Abort Response |
Byte1~2 |
0x6040 |
Object Index |
Byte3 |
0x00 |
Sub-index |
Byte4~7 |
0x06010002 |
Abort Code |
참고
Abort Code는 Little-Endian으로 전송되므로, 02 00 01 06은
0x06010002로 해석해야 합니다.
11.10.3 SDO Abort Code Table
다음 표는 SF시리즈 CANopen에서 사용하는 SDO Abort Code 목록입니다.
Abort Code |
Name |
Meaning |
Description |
|---|---|---|---|
0x00000000 |
No Abort |
Communication Successful |
통신 성공 |
0x05030000 |
Toggle Error |
Toggle Bit Not Alternated |
Toggle Bit가 정상적으로 변경되지 않음 |
0x05040000 |
SDO Timeout |
SDO Protocol Timed Out |
SDO 통신 시간 초과 |
0x05040001 |
Command Unknown |
Command Specifier Unknown |
알 수 없거나 잘못된 Command Specifier |
0x05040004 |
CRC Error |
CRC Check Failed |
CRC 검증 실패 |
0x06010000 |
Access Error |
Unsupported Access to an Object |
해당 Object 접근 불가 |
0x06010001 |
Write Only Error |
Read Command to a Write Only Object |
Write Only Object를 읽으려고 함 |
0x06010002 |
Read Only Error |
Write Command to a Read Only Object |
Read Only Object에 쓰려고 함 |
0x06010003 |
Sub-index Cannot Be Written |
Sub-index Must Be 0 for Write Access |
해당 Sub-index에 쓰기 불가 |
0x06010004 |
SDO Complete Access Not Supported |
Complete Access Not Supported |
Complete Access 방식 미지원 |
0x06020000 |
Object Does Not Exist |
Object Index or Sub-index Error |
Object Dictionary에 해당 Object 없음 |
0x06040041 |
PDO Mapping Error |
Object Is Not Mappable to PDO |
해당 Object는 PDO Mapping 불가 |
0x06040042 |
PDO Length Error |
PDO Length Exceeded |
Mapping Object 수 또는 길이가 PDO 최대 길이 초과 |
0x06040043 |
General Parameter Error |
General Parameter Incompatibility |
일반 파라미터 호환성 오류 |
0x06040047 |
General Internal Incompatibility Error |
Internal Incompatibility in Device |
장치 내부 호환성 오류 |
0x06060000 |
Hardware Error |
Access Failed Due to Hardware Error |
하드웨어 오류로 Object 접근 실패 |
0x06070010 |
Service Parameter Error |
Data Type or Length Does Not Match |
데이터 타입 또는 서비스 파라미터 길이 불일치 |
0x06070013 |
Service Parameter Too Short Error |
Service Parameter Length Too Low |
서비스 파라미터 길이가 너무 짧음 |
0x06090011 |
Sub-index Error |
Sub-index Does Not Exist |
해당 Sub-index 없음 |
0x06090030 |
Value Range Error |
Value Range of Parameter Exceeded |
입력 값이 허용 범위를 초과 |
0x08000000 |
General Error |
General Error |
일반 오류 |
0x08000020 |
Transfer or Store Error |
Data Cannot Be Transferred or Stored |
데이터를 전송하거나 저장할 수 없음 |
0x08000022 |
Wrong Device State Error |
Wrong Present Device State |
현재 장치 상태에서 데이터 전송 또는 저장 불가 |
0x0F00FFBE |
Password Error |
Password Is Incorrect |
Password 오류 |
0x0F00FFBF |
Illegal Command Error |
Command Code Is Illegal |
존재하지 않거나 허용되지 않은 명령 코드 |
0x0F00FFC0 |
Wrong NMT State Error |
Device Is in Wrong NMT State |
장치가 잘못된 NMT 상태에 있음 |
11.10.4 Abort Code 분류
SDO Abort Code는 원인에 따라 다음과 같이 분류할 수 있습니다.
Category |
Abort Code |
Description |
|---|---|---|
Protocol Error |
0x05030000, 0x05040000, 0x05040001, 0x05040004 |
SDO 프로토콜 오류 |
Access Error |
0x06010000, 0x06010001, 0x06010002, 0x06010003, 0x06010004 |
Object 접근 권한 오류 |
Object Error |
0x06020000, 0x06090011 |
Object 또는 Sub-index 존재 오류 |
PDO Mapping Error |
0x06040041, 0x06040042 |
PDO Mapping 설정 오류 |
Parameter Error |
0x06040043, 0x06070010, 0x06070013, 0x06090030 |
데이터 타입, 길이, 범위 오류 |
Device Error |
0x06040047, 0x06060000, 0x08000000, 0x08000020, 0x08000022 |
장치 내부 또는 상태 오류 |
Manufacturer Error |
0x0F00FFBE, 0x0F00FFBF, 0x0F00FFC0 |
SF시리즈 제조사 전용 오류 |
11.10.5 주요 오류 원인 및 조치
Abort Code |
주요 원인 |
조치 방법 |
|---|---|---|
0x05040000 |
SDO 응답 시간 초과 |
Node ID, Baud Rate, 배선, 전원 확인 |
0x05040001 |
잘못된 SDO Command Specifier |
Byte0 명령 코드 확인 |
0x06010001 |
Write Only Object Read 시도 |
Object Access 속성 확인 |
0x06010002 |
Read Only Object Write 시도 |
Object Access 속성 확인 |
0x06020000 |
존재하지 않는 Object 접근 |
Index 값 확인 |
0x06090011 |
존재하지 않는 Sub-index 접근 |
Sub-index 값 확인 |
0x06090030 |
허용 범위 초과 값 입력 |
Min/Max 범위 확인 |
0x06040041 |
PDO Mapping 불가 Object 매핑 |
PDO Mapping 가능 여부 확인 |
0x06040042 |
PDO Mapping 길이 초과 |
총 Mapping 길이를 64 bit 이하로 조정 |
0x06070010 |
데이터 타입 또는 길이 불일치 |
SDO Write 크기 확인 |
0x08000022 |
현재 장치 상태에서 접근 불가 |
NMT 상태 및 CiA402 상태 확인 |
0x0F00FFC0 |
잘못된 NMT 상태 |
Pre-operational 또는 Operational 상태 확인 |
11.10.6 SDO Command Specifier 확인
SDO Write 시 데이터 크기에 맞는 Command Specifier를 사용해야 합니다.
Command Specifier |
Direction |
Data Size |
Description |
|---|---|---|---|
0x2F |
Client → Server |
1 Byte |
Expedited Write 8-bit |
0x2B |
Client → Server |
2 Byte |
Expedited Write 16-bit |
0x23 |
Client → Server |
4 Byte |
Expedited Write 32-bit |
0x40 |
Client → Server |
Read Request |
|
0x60 |
Server → Client |
Write Success Response |
|
0x4F |
Server → Client |
1 Byte |
Read Response 8-bit |
0x4B |
Server → Client |
2 Byte |
Read Response 16-bit |
0x43 |
Server → Client |
4 Byte |
Read Response 32-bit |
0x80 |
Server → Client |
Abort Response |
예를 들어 UNSIGNED16 Object에 4 Byte Write 명령(0x23)을 사용하면
데이터 타입 또는 길이 불일치로 Abort Code가 반환될 수 있습니다.
11.10.7 SDO Abort 처리 절차
Host Controller는 SDO Response를 수신하면 다음 순서로 처리하는 것을 권장합니다.
Response COB-ID가
0x580 + Node ID인지 확인합니다.Byte0 값을 확인합니다.
Byte0이
0x80이면 Abort Response로 판단합니다.Byte1~3에서 Object Index와 Sub-index를 확인합니다.
Byte4~7에서 Abort Code를 Little-Endian으로 변환합니다.
Abort Code Table에서 오류 원인을 확인합니다.
Object Dictionary의 Access, Data Type, Range, PDO Mapping 속성을 확인합니다.
필요한 경우 NMT 상태 또는 CiA402 상태를 변경한 후 재시도합니다.
11.10.8 SDO Abort 처리 로직
Send SDO Request
│
▼
Receive SDO Response
│
├── Byte0 = 0x60 / 0x43 / 0x4B / 0x4F
│ └── Normal Response
│
└── Byte0 = 0x80
│
▼
Parse Index / Sub-index
│
▼
Parse Abort Code
│
▼
Check Object Dictionary
│
▼
Correct Request
│
▼
Retry SDO
11.10.9 Python Abort Code 해석 예시
def parse_sdo_abort(data):
"""
data: SDO response data field, 8 bytes
"""
if len(data) != 8:
raise ValueError("SDO response must be 8 bytes")
if data[0] != 0x80:
return None
index = data[1] | (data[2] << 8)
sub_index = data[3]
abort_code = (
data[4]
| (data[5] << 8)
| (data[6] << 16)
| (data[7] << 24)
)
return index, sub_index, abort_code
data = bytes([0x80, 0x40, 0x60, 0x00, 0x02, 0x00, 0x01, 0x06])
result = parse_sdo_abort(data)
if result:
index, sub_index, abort_code = result
print(f"SDO Abort: Index=0x{index:04X}, Sub=0x{sub_index:02X}, Code=0x{abort_code:08X}")
출력 예시는 다음과 같습니다.
SDO Abort: Index=0x6040, Sub=0x00, Code=0x06010002
11.10.10 C Abort Code 해석 예시
#include <stdio.h>
#include <stdint.h>
void parse_sdo_abort(uint8_t data[8])
{
if (data[0] != 0x80) {
printf("Normal SDO response\n");
return;
}
uint16_t index;
uint8_t sub_index;
uint32_t abort_code;
index = (uint16_t)data[1] | ((uint16_t)data[2] << 8);
sub_index = data[3];
abort_code =
((uint32_t)data[4]) |
((uint32_t)data[5] << 8) |
((uint32_t)data[6] << 16) |
((uint32_t)data[7] << 24);
printf("SDO Abort\n");
printf("Index : 0x%04X\n", index);
printf("Sub-index : 0x%02X\n", sub_index);
printf("Abort Code : 0x%08X\n", abort_code);
}
int main(void)
{
uint8_t response[8] = {
0x80, 0x40, 0x60, 0x00,
0x02, 0x00, 0x01, 0x06
};
parse_sdo_abort(response);
return 0;
}
11.10.11 SDO Abort 발생 시 확인 사항
SDO Abort가 발생하면 다음 사항을 확인하십시오.
요청한 Index가 Object Dictionary에 존재하는지 확인합니다.
Sub-index가 올바른지 확인합니다.
Object의 Access 속성이 요청 방향과 일치하는지 확인합니다.
Write 데이터 크기가 Object의 Data Type과 일치하는지 확인합니다.
입력 값이 Min/Max 범위 내에 있는지 확인합니다.
PDO Mapping 대상 Object가 PDO Mapping을 지원하는지 확인합니다.
PDO Mapping 변경 시 NMT 상태가 Pre-operational인지 확인합니다.
저장 또는 복원 관련 Object 접근 시 Password 또는 Signature 값이 올바른지 확인합니다.
현재 CiA402 상태에서 해당 Object 접근이 허용되는지 확인합니다.
중요
SDO Abort Code는 단순한 통신 실패가 아니라, Object 접근 방식이 잘못되었거나 현재 장치 상태에서 요청을 처리할 수 없음을 의미합니다. Host Controller는 Abort Code를 기록하고, Object Dictionary의 Index, Sub-index, Access, Data Type, Range 및 NMT 상태를 함께 확인하여 오류 원인을 분석해야 합니다.
11.11 Data Type
Data Type은 Object Dictionary에 저장되는 데이터의 크기, 부호 여부 및 해석 방법을 정의합니다.
Host Controller는 SDO 또는 PDO를 통해 Object에 접근할 때 해당 Object의 Data Type을 기준으로 데이터 길이와 Byte 순서를 정확히 처리해야 합니다.
SF시리즈 CANopen은 CANopen 표준 데이터 형식을 사용하며, 일부
Object에서는 SF시리즈 매뉴얼 표기 방식에 따라 SINT, INT,
DINT, USINT, UINT, UDINT와 같은 약어를 사용합니다.
11.11.1 Data Type 기본 규칙
CANopen 데이터는 Object Dictionary의 Data Type에 따라 해석합니다.
항목 |
설명 |
|---|---|
Data Type |
Object 값의 데이터 형식 |
Size |
데이터 크기 |
Signed / Unsigned |
부호 있는 값 또는 부호 없는 값 |
Unit |
단위 |
Min / Max |
허용 최소값 및 최대값 |
Access |
읽기/쓰기 권한 |
PDO Mapping |
PDO 매핑 가능 여부 |
데이터 크기가 Object의 Data Type과 일치하지 않으면 SDO Abort Code가 반환될 수 있습니다.
11.11.2 기본 Data Type 목록
CANopen Type |
SF시리즈 표기 |
Size |
Range |
Description |
|---|---|---|---|---|
BOOLEAN |
BOOL |
1 Byte |
0 또는 1 |
논리값 |
INTEGER8 |
SINT |
1 Byte |
-128 ~ 127 |
부호 있는 8-bit 정수 |
INTEGER16 |
INT |
2 Byte |
-32,768 ~ 32,767 |
부호 있는 16-bit 정수 |
INTEGER32 |
DINT |
4 Byte |
-2,147,483,648 ~ 2,147,483,647 |
부호 있는 32-bit 정수 |
UNSIGNED8 |
USINT |
1 Byte |
0 ~ 255 |
부호 없는 8-bit 정수 |
UNSIGNED16 |
UINT |
2 Byte |
0 ~ 65,535 |
부호 없는 16-bit 정수 |
UNSIGNED32 |
UDINT |
4 Byte |
0 ~ 4,294,967,295 |
부호 없는 32-bit 정수 |
VISIBLE_STRING |
STRING |
Variable |
ASCII 문자열 |
문자열 데이터 |
OCTET_STRING |
BYTE ARRAY |
Variable |
Byte 배열 |
이진 데이터 |
DOMAIN |
DOMAIN |
Variable |
가변 길이 데이터 |
펌웨어 또는 대용량 데이터 |
11.11.3 Signed Integer
Signed Integer는 음수와 양수를 모두 표현할 수 있는 정수형 데이터입니다.
Type |
Size |
Minimum |
Maximum |
|---|---|---|---|
SINT / INTEGER8 |
1 Byte |
-128 |
127 |
INT / INTEGER16 |
2 Byte |
-32,768 |
32,767 |
DINT / INTEGER32 |
4 Byte |
-2,147,483,648 |
2,147,483,647 |
Signed Integer는 위치, 속도, 토크, 오차값과 같이 양방향 값을 표현할 때 사용됩니다.
대표적인 예는 다음과 같습니다.
Object |
Data Type |
Description |
|---|---|---|
0x6064 Position Actual Value |
DINT |
현재 위치 |
0x607A Target Position |
DINT |
목표 위치 |
0x60FF Target Velocity |
DINT |
목표 속도 |
0x3B69 Torque Sensor |
DINT |
토크 센서 또는 계산 토크 |
11.11.4 Unsigned Integer
Unsigned Integer는 0 이상의 값만 표현하는 정수형 데이터입니다.
Type |
Size |
Minimum |
Maximum |
|---|---|---|---|
USINT / UNSIGNED8 |
1 Byte |
0 |
255 |
UINT / UNSIGNED16 |
2 Byte |
0 |
65,535 |
UDINT / UNSIGNED32 |
4 Byte |
0 |
4,294,967,295 |
Unsigned Integer는 상태값, 설정값, 시간, 전류 제한, 전압값 등 음수가 필요 없는 데이터에 사용됩니다.
대표적인 예는 다음과 같습니다.
Object |
Data Type |
Description |
|---|---|---|
0x1001 Error Register |
USINT |
오류 레지스터 |
0x6040 Controlword |
UINT |
제어 워드 |
0x6041 Statusword |
UINT |
상태 워드 |
0x1017 Producer Heartbeat Time |
UINT |
Heartbeat 송신 주기 |
0x3B68 Warning Code |
UDINT |
경고 코드 |
11.11.5 Byte Order
SF시리즈 CANopen 데이터는 Little-Endian 형식으로 전송됩니다.
Little-Endian에서는 하위 Byte(LSB)가 먼저 전송되고, 상위 Byte(MSB)가 나중에 전송됩니다.
예를 들어 16-bit 값 0x1234는 다음과 같이 전송됩니다.
Value : 0x1234
Byte0 : 0x34
Byte1 : 0x12
32-bit 값 0x12345678은 다음과 같이 전송됩니다.
Value : 0x12345678
Byte0 : 0x78
Byte1 : 0x56
Byte2 : 0x34
Byte3 : 0x12
11.11.6 SDO 데이터 크기와 Command Specifier
SDO Write를 수행할 때에는 데이터 크기에 맞는 Command Specifier를 사용해야 합니다.
Data Type |
Size |
SDO Write Command |
Description |
|---|---|---|---|
BOOLEAN |
1 Byte |
0x2F |
1 Byte Write |
INTEGER8 / UNSIGNED8 |
1 Byte |
0x2F |
1 Byte Write |
INTEGER16 / UNSIGNED16 |
2 Byte |
0x2B |
2 Byte Write |
INTEGER32 / UNSIGNED32 |
4 Byte |
0x23 |
4 Byte Write |
SDO Read 응답의 Command Specifier는 반환되는 데이터 크기에 따라 달라집니다.
Data Size |
SDO Read Response |
|---|---|
1 Byte |
0x4F |
2 Byte |
0x4B |
4 Byte |
0x43 |
11.11.7 SDO Data Field 예시
8-bit Write 예시
0x6060:00에 0x01을 기록하여 Profile Position Mode를 설정하는
예입니다.
Field |
Value |
|---|---|
Index |
0x6060 |
Sub-index |
0x00 |
Data Type |
SINT |
Value |
0x01 |
COB-ID : 0x601
Data : 2F 60 60 00 01 00 00 00
16-bit Write 예시
0x6040:00에 0x000F를 기록하여 Enable Operation을 수행하는
예입니다.
Field |
Value |
|---|---|
Index |
0x6040 |
Sub-index |
0x00 |
Data Type |
UINT |
Value |
0x000F |
COB-ID : 0x601
Data : 2B 40 60 00 0F 00 00 00
32-bit Write 예시
0x607A:00에 5566을 기록하여 Target Position을 설정하는
예입니다.
5566은 16진수로 0x000015BE이며, Little-Endian으로 다음과 같이
전송됩니다.
5566(dec) = 0x000015BE
Byte4 : 0xBE
Byte5 : 0x15
Byte6 : 0x00
Byte7 : 0x00
SDO Frame은 다음과 같습니다.
COB-ID : 0x601
Data : 23 7A 60 00 BE 15 00 00
11.11.8 PDO 데이터 해석
PDO는 Object Dictionary에 매핑된 Data Type 순서에 따라 데이터를 해석합니다.
예를 들어 TPDO1이 다음과 같이 매핑되어 있다고 가정합니다.
Mapping Order |
Object |
Data Type |
Size |
|---|---|---|---|
1 |
Statusword |
UINT |
2 Byte |
2 |
Position Actual Value |
DINT |
4 Byte |
3 |
Modes of Operation Display |
SINT |
1 Byte |
TPDO1 Data Field는 다음과 같이 해석합니다.
Byte0~1 : Statusword
Byte2~5 : Position Actual Value
Byte6 : Modes of Operation Display
Byte7 : Reserved
예시 데이터가 다음과 같은 경우:
Data : 37 12 BE 15 00 00 08 00
해석 결과는 다음과 같습니다.
Object |
Raw Data |
Value |
|---|---|---|
Statusword |
37 12 |
0x1237 |
Position Actual Value |
BE 15 00 00 |
5566 |
Modes of Operation Display |
08 |
CSP Mode |
11.11.9 Signed 값 해석 예시
Signed Integer는 2의 보수(Two’s Complement) 형식으로 표현됩니다.
예를 들어 32-bit 데이터가 다음과 같이 수신되었다고 가정합니다.
Raw Data : FF FF FF FF
이는 Unsigned 값으로는 0xFFFFFFFF이지만, DINT로 해석하면
-1입니다.
Raw Data |
Unsigned 해석 |
DINT 해석 |
|---|---|---|
FF FF FF FF |
4,294,967,295 |
-1 |
FE FF FF FF |
4,294,967,294 |
-2 |
00 00 00 80 |
2,147,483,648 |
-2,147,483,648 |
FF FF FF 7F |
2,147,483,647 |
2,147,483,647 |
따라서 Position, Velocity, Torque와 같이 Signed Data Type을 사용하는 Object는 반드시 부호 있는 정수로 변환해야 합니다.
11.11.10 C 언어 Data Type 대응
Host Controller를 C 언어로 구현할 경우 다음 자료형을 사용하는 것을 권장합니다.
CANopen Type |
SF시리즈 표기 |
C Type |
|---|---|---|
BOOLEAN |
BOOL |
|
INTEGER8 |
SINT |
|
INTEGER16 |
INT |
|
INTEGER32 |
DINT |
|
UNSIGNED8 |
USINT |
|
UNSIGNED16 |
UINT |
|
UNSIGNED32 |
UDINT |
|
예를 들어 Little-Endian 32-bit 값을 DINT로 변환하는 코드는 다음과 같습니다.
#include <stdint.h>
int32_t le_to_int32(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3)
{
uint32_t raw =
((uint32_t)b0) |
((uint32_t)b1 << 8) |
((uint32_t)b2 << 16) |
((uint32_t)b3 << 24);
return (int32_t)raw;
}
11.11.11 Python Data Type 대응
Python에서는 int.from_bytes()를 사용하여 Byte 데이터를 쉽게 변환할
수 있습니다.
CANopen Type |
Python 변환 |
|---|---|
UNSIGNED8 |
|
INTEGER8 |
|
UNSIGNED16 |
|
INTEGER16 |
|
UNSIGNED32 |
|
INTEGER32 |
|
예시는 다음과 같습니다.
raw = bytes([0xBE, 0x15, 0x00, 0x00])
value_unsigned = int.from_bytes(raw, byteorder="little", signed=False)
value_signed = int.from_bytes(raw, byteorder="little", signed=True)
print(value_unsigned) # 5566
print(value_signed) # 5566
음수 값 예시는 다음과 같습니다.
raw = bytes([0xFF, 0xFF, 0xFF, 0xFF])
value = int.from_bytes(raw, byteorder="little", signed=True)
print(value) # -1
11.11.12 단위와 Scale
Object Dictionary의 값은 Data Type뿐만 아니라 Unit과 Scale을 함께 고려해야 합니다.
예를 들어 동일한 DINT 값이라도 Object에 따라 의미가 달라집니다.
Object |
Data Type |
Unit |
Description |
|---|---|---|---|
0x6064 Position Actual Value |
DINT |
pulse 또는 count |
현재 위치 |
0x606C Velocity Actual Value |
DINT |
pulse/s 또는 profile unit |
현재 속도 |
0x6071 Target Torque |
INT |
0.1% 또는 정격 토크 비율 |
목표 토크 |
0x6078 Motor Actual Current |
INT |
1‰ |
모터 실제 전류 |
0x3B69 Torque Sensor |
DINT |
mN·m |
토크 센서 값 |
따라서 Host Controller는 Object의 Data Type뿐만 아니라 Unit, Scale 및 Description을 함께 참조하여 값을 변환해야 합니다.
11.11.13 Data Type 사용 시 주의사항
Data Type을 사용할 때에는 다음 사항을 반드시 확인하십시오.
SDO Write 시 Object의 Data Type과 데이터 크기가 일치해야 합니다.
Multi-byte 데이터는 Little-Endian으로 송수신해야 합니다.
Signed Object는 반드시 부호 있는 값으로 해석해야 합니다.
PDO 데이터는 Mapping 순서와 Data Type에 따라 해석해야 합니다.
Unit과 Scale을 고려하지 않으면 실제 물리량이 잘못 계산될 수 있습니다.
Read Only Object에는 Write를 수행하지 마십시오.
SDO Abort Code가 발생하면 Data Type, Access, Min/Max 범위를 확인하십시오.
중요
CANopen 통신에서 Data Type 해석 오류는 잘못된 위치, 속도, 토크 명령으로 이어질 수 있습니다. Host Controller는 Object Dictionary의 Data Type, Byte Order, Unit, Scale 및 Access Attribute를 반드시 확인한 후 데이터를 송수신해야 합니다.
11.12 Access Type
Access Type은 Object Dictionary의 각 Object에 대해 Host Controller가 수행할 수 있는 접근 권한을 정의합니다.
CANopen에서는 SDO(Service Data Object)를 이용하여 Object Dictionary의 값을 읽거나 쓸 수 있으며, Object마다 읽기 가능 여부, 쓰기 가능 여부, 저장 가능 여부 및 PDO Mapping 가능 여부가 다릅니다.
Host Controller는 SDO Read/Write 또는 PDO Mapping을 수행하기 전에 반드시 해당 Object의 Access Type을 확인해야 합니다.
11.12.1 Access Type 개요
Object Dictionary의 Access Type은 다음과 같은 의미를 가집니다.
Access Type |
의미 |
Read |
Write |
설명 |
|---|---|---|---|---|
RO |
Read Only |
✓ |
읽기 전용 |
|
WO |
Write Only |
✓ |
쓰기 전용 |
|
RW |
Read / Write |
✓ |
✓ |
읽기 및 쓰기 가능 |
Const |
Constant |
✓ |
고정값, 변경 불가 |
|
R |
Read |
✓ |
읽기 가능 |
|
W |
Write |
✓ |
쓰기 가능 |
일반적으로 SF시리즈 Object Dictionary에서는 RO, RW가 가장 많이
사용됩니다.
11.12.2 Read Only (RO)
Read Only Object는 Host Controller가 값을 읽을 수 있지만, 값을 변경할 수 없는 Object입니다.
주로 장치 상태, 피드백 값, 진단 정보 등에 사용됩니다.
Object 예 |
설명 |
|---|---|
0x1001 Error Register |
오류 레지스터 |
0x6041 Statusword |
장치 상태 |
0x6061 Modes of Operation Display |
현재 운전 모드 |
0x6064 Position Actual Value |
현재 위치 |
0x606C Velocity Actual Value |
현재 속도 |
0x6077 Torque Actual Value |
현재 토크 |
0x3B68 Warning Code |
경고 코드 |
0x3B69 Torque Sensor |
토크 센서 값 |
RO Object에 SDO Write를 수행하면 SDO Abort Code가 반환됩니다.
대표적인 Abort Code는 다음과 같습니다.
Abort Code |
의미 |
|---|---|
0x06010002 |
Read Only Object에 Write 시도 |
11.12.3 Write Only (WO)
Write Only Object는 Host Controller가 값을 쓸 수 있지만, 읽을 수 없는 Object입니다.
주로 명령 실행, 저장, 복원, 초기화와 같이 특정 동작을 Trigger하는 Object에 사용될 수 있습니다.
사용 예 |
설명 |
|---|---|
Parameter Store Command |
파라미터 저장 명령 |
Restore Default Command |
기본값 복원 명령 |
Reset Command |
특정 기능 초기화 명령 |
WO Object에 SDO Read를 수행하면 SDO Abort Code가 반환됩니다.
Abort Code |
의미 |
|---|---|
0x06010001 |
Write Only Object에 Read 시도 |
참고
모든 SF시리즈 제품에서 WO Object를 동일하게 제공하는 것은 아닙니다. 해당 Object의 상세 Access Type은 Object Dictionary 상세 표를 확인하십시오.
11.12.4 Read / Write (RW)
Read / Write Object는 Host Controller가 값을 읽고 변경할 수 있는 Object입니다.
주로 설정값, 제어 명령, 운전 파라미터 등에 사용됩니다.
Object 예 |
설명 |
|---|---|
0x6040 Controlword |
장치 상태 제어 |
0x6060 Modes of Operation |
운전 모드 설정 |
0x607A Target Position |
목표 위치 |
0x60FF Target Velocity |
목표 속도 |
0x6071 Target Torque |
목표 토크 |
0x6081 Profile Velocity |
프로파일 속도 |
0x6083 Profile Acceleration |
프로파일 가속도 |
0x6084 Profile Deceleration |
프로파일 감속도 |
0x1017 Producer Heartbeat Time |
Heartbeat 송신 주기 |
RW Object는 SDO Write를 통해 값을 변경할 수 있지만, 입력 값이 허용 범위를 벗어나면 SDO Abort Code가 반환될 수 있습니다.
Abort Code |
의미 |
|---|---|
0x06090030 |
값이 허용 범위를 초과 |
0x06070010 |
데이터 타입 또는 길이 불일치 |
0x08000022 |
현재 장치 상태에서 접근 불가 |
11.12.5 Constant Object
Constant Object는 장치 정보 또는 고정된 표준값을 나타내는 Object입니다.
Host Controller는 값을 읽을 수 있지만, 변경할 수 없습니다.
Object 예 |
설명 |
|---|---|
Device Type |
장치 유형 |
Manufacturer Device Name |
제조사 장치명 |
Manufacturer Hardware Version |
하드웨어 버전 |
Manufacturer Software Version |
소프트웨어 버전 |
Identity Object |
Vendor ID, Product Code 등 |
Constant Object는 장치 식별 및 시스템 구성 확인에 사용됩니다.
11.12.6 Access Type과 SDO 동작
SDO 접근 가능 여부는 Access Type에 따라 결정됩니다.
Access Type |
SDO Read |
SDO Write |
비고 |
|---|---|---|---|
RO |
가능 |
불가 |
상태 및 피드백 Object |
WO |
불가 |
가능 |
명령 실행 Object |
RW |
가능 |
가능 |
설정 및 제어 Object |
Const |
가능 |
불가 |
고정 정보 Object |
SDO Write를 수행할 때에는 다음 조건을 모두 만족해야 합니다.
Object가 Write 가능한 Access Type이어야 합니다.
Data Type과 Write 데이터 길이가 일치해야 합니다.
입력 값이 Min/Max 범위 내에 있어야 합니다.
현재 NMT 상태에서 접근 가능해야 합니다.
현재 CiA402 상태에서 변경 가능한 Object이어야 합니다.
11.12.7 Access Type과 PDO Mapping
PDO Mapping 가능 여부는 Access Type과 별도로 정의됩니다.
즉, Object가 RW라고 해서 반드시 PDO Mapping이 가능한 것은 아니며, Object
Dictionary의 PDO Mapping 항목을 별도로 확인해야 합니다.
Object 종류 |
일반적인 PDO 방향 |
예 |
|---|---|---|
Control Object |
RPDO |
Controlword, Target Position |
Feedback Object |
TPDO |
Statusword, Actual Position |
Configuration Object |
PDO Mapping 불가 |
Heartbeat Time, Identity Object |
Diagnostic Object |
TPDO |
Error Code, Warning Code |
11.12.8 RPDO에 적합한 Access Type
RPDO는 Master에서 SF시리즈로 제어 데이터를 전송하는 방향입니다.
따라서 RPDO에는 일반적으로 Write 가능한 Object를 매핑합니다.
Object |
Access |
RPDO Mapping |
|---|---|---|
0x6040 Controlword |
RW |
가능 |
0x6060 Modes of Operation |
RW |
가능 |
0x607A Target Position |
RW |
가능 |
0x60FF Target Velocity |
RW |
가능 |
0x6071 Target Torque |
RW |
가능 |
Read Only Object를 RPDO에 매핑하면 의미가 없거나 Mapping이 거부될 수 있습니다.
11.12.9 TPDO에 적합한 Access Type
TPDO는 SF시리즈에서 Master로 상태 데이터를 전송하는 방향입니다.
따라서 TPDO에는 일반적으로 Read 가능한 Object를 매핑합니다.
Object |
Access |
TPDO Mapping |
|---|---|---|
0x6041 Statusword |
RO |
가능 |
0x6061 Modes of Operation Display |
RO |
가능 |
0x6064 Position Actual Value |
RO |
가능 |
0x606C Velocity Actual Value |
RO |
가능 |
0x6077 Torque Actual Value |
RO |
가능 |
0x3B68 Warning Code |
RO |
가능 |
0x3B69 Torque Sensor |
RO |
가능 |
TPDO는 장치 상태를 Master에 전달하기 위한 용도이므로, 상태값과 피드백값을 중심으로 구성하는 것이 좋습니다.
11.12.10 Backup Attribute
Object Dictionary 상세 표에는 Access Type 외에도 Backup 항목이
포함될 수 있습니다.
Backup은 해당 Object의 값이 비휘발성 메모리에 저장되는지 여부를 의미합니다.
Backup |
의미 |
|---|---|
YES |
저장 가능 |
NO |
전원 재인가 시 기본값 또는 초기값으로 복귀 |
Backup이 YES인 Object라도 값이 자동으로 저장되는 것은 아닐 수
있습니다. 이 경우 별도의 Store Parameters 명령을 수행해야 합니다.
대표적인 저장 관련 Object는 다음과 같습니다.
Object |
Description |
|---|---|
0x1010 Store Parameters |
현재 파라미터 저장 |
0x1011 Restore Default Parameters |
기본 파라미터 복원 |
참고
설정값을 변경한 후 전원 재인가 뒤에도 유지하려면, 해당 Object가 Backup을 지원하는지 확인하고 필요한 경우 Store Parameters 명령을 수행하십시오.
11.12.11 Update Attribute
Update는 Object 값이 적용되는 시점을 의미합니다.
Update Type |
의미 |
|---|---|
Immediately |
Write 후 즉시 적용 |
Reset |
장치 재시작 후 적용 |
Communication Reset |
Reset Communication 후 적용 |
Power Cycle |
전원 재인가 후 적용 |
Operation Dependent |
운전 상태에 따라 적용 |
예를 들어 Motion Parameter는 즉시 적용될 수 있지만, Node ID나 통신 관련 설정은 장치 재시작 또는 통신 재시작 후 적용될 수 있습니다.
11.12.12 Access Type과 장치 상태
일부 Object는 RW이더라도 모든 상태에서 변경할 수 있는 것은 아닙니다.
장치 상태 |
설정 Object 변경 |
Motion Command |
PDO Mapping 변경 |
|---|---|---|---|
Initialization |
제한 |
불가 |
불가 |
Pre-operational |
가능 |
제한 |
가능 |
Operational |
가능 |
가능 |
권장하지 않음 |
Stopped |
제한 |
불가 |
제한 |
Fault |
제한 |
불가 |
제한 |
PDO Mapping, 통신 파라미터 및 일부 보호 파라미터는 Pre-operational 상태에서 변경하는 것을 권장합니다.
11.12.13 Access Type별 SDO 예시
RO Object Read
Statusword(0x6041)를 읽는 예입니다.
Request
COB-ID : 0x601
Data : 40 41 60 00 00 00 00 00
Response
COB-ID : 0x581
Data : 4B 41 60 00 xx xx 00 00
RO Object Write 시도
Statusword(0x6041)에 Write를 시도하면 Abort가 발생할 수 있습니다.
Request
COB-ID : 0x601
Data : 2B 41 60 00 00 00 00 00
Abort Response
COB-ID : 0x581
Data : 80 41 60 00 02 00 01 06
Abort Code 0x06010002는 Read Only Object에 Write를 시도했음을
의미합니다.
RW Object Write
Controlword(0x6040)에 Enable Operation 명령을 쓰는 예입니다.
Request
COB-ID : 0x601
Data : 2B 40 60 00 0F 00 00 00
Response
COB-ID : 0x581
Data : 60 40 60 00 00 00 00 00
11.12.14 Access Type 사용 시 주의사항
Access Type을 사용할 때에는 다음 사항을 확인하십시오.
SDO Read/Write 전 Object의 Access Type을 확인하십시오.
RO Object에는 Write하지 마십시오.
WO Object는 Read하지 마십시오.
RW Object라도 현재 장치 상태에 따라 Write가 제한될 수 있습니다.
PDO Mapping 가능 여부는 Access Type과 별도로 확인하십시오.
Backup이 필요한 설정값은 Store Parameters 명령을 수행하십시오.
Update 방식이 Reset 또는 Power Cycle인 경우 장치 재시작 후 값을 확인하십시오.
SDO Abort 발생 시 Access Type, Data Type, Min/Max, NMT 상태를 함께 확인하십시오.
중요
Access Type은 Object Dictionary 접근 가능 여부를 결정하는 기본 조건입니다. 잘못된 Access Type으로 SDO 접근을 수행하면 Abort Code가 반환되며, 잘못된 Object를 PDO에 매핑하면 실시간 제어 데이터가 정상적으로 처리되지 않을 수 있습니다. Host Controller는 Object Dictionary의 Access, Backup, Update 및 PDO Mapping 속성을 함께 확인하여 안전하게 통신을 구현해야 합니다.
11.13 State Machine
SF시리즈 CANopen 제어에는 두 가지 상태 머신이 사용됩니다.
State Machine |
표준 |
목적 |
|---|---|---|
NMT State Machine |
CiA 301 |
CANopen 통신 상태 관리 |
PDS FSA |
CiA 402 |
Servo Drive 상태 및 Motion Enable 관리 |
NMT State Machine은 SDO, PDO, EMCY, Heartbeat 등 CANopen 통신 객체의 사용 가능 여부를 결정합니다.
PDS FSA(Power Drive System Finite State Automaton)는 Controlword와 Statusword를 이용하여 Servo Enable, Quick Stop, Fault Reset 및 Motion 실행 가능 상태를 제어합니다.
실제 Motion Command를 실행하려면 다음 두 조건을 모두 만족해야 합니다.
NMT 상태가 Operational이어야 합니다.
CiA 402 상태가 Operation Enabled이어야 합니다.
11.13.1 State Machine 구성
SF시리즈 CANopen 제어 구조는 다음과 같이 두 계층으로 구성됩니다.
CANopen Master
│
▼
NMT State Machine
│
├─ Pre-operational
├─ Operational
└─ Stopped
│
▼
CiA 402 PDS FSA
│
├─ Switch On Disabled
├─ Ready to Switch On
├─ Switched On
├─ Operation Enabled
└─ Fault
│
▼
Motion Control
11.13.2 NMT State Machine
NMT(Network Management) State Machine은 CANopen Node의 통신 상태를 관리합니다.
전원이 인가되면 SF시리즈는 Initialization 상태에서 내부 초기화를 수행하고, 초기화가 완료되면 Boot-up 메시지를 전송한 후 Pre-operational 상태로 진입합니다.
Power ON
│
▼
Initialization
│
│ Boot-up Message
▼
Pre-operational
│
│ NMT Start Remote Node
▼
Operational
│
│ NMT Stop Remote Node
▼
Stopped
11.13.3 NMT State Description
NMT State |
Description |
|---|---|
Initialization |
전원 인가 후 초기화 중인 상태 |
Pre-operational |
SDO 통신 및 설정 가능, PDO 통신 불가 |
Operational |
SDO 및 PDO 통신 가능 |
Stopped |
NMT 및 Heartbeat만 응답 가능 |
11.13.4 NMT 상태별 사용 가능한 Object
Communication Object |
Initialization |
Pre-operational |
Operational |
Stopped |
|---|---|---|---|---|
NMT |
✓ |
✓ |
✓ |
|
Boot-up |
✓ |
|||
SDO |
✓ |
✓ |
||
PDO |
✓ |
|||
SYNC |
✓ |
✓ |
||
EMCY |
✓ |
✓ |
||
Heartbeat |
✓ |
✓ |
✓ |
참고
PDO를 이용한 실시간 제어 및 피드백은 반드시 NMT 상태가 Operational일 때 수행해야 합니다.
11.13.5 CiA 402 PDS FSA
PDS FSA(Power Drive System Finite State Automaton)는 Servo Drive의 전원, Enable, Fault 및 Motion 가능 상태를 관리합니다.
Host Controller는 Controlword(0x6040) 를 이용하여 상태 전이를 요청하고, Statusword(0x6041) 를 읽어 현재 상태를 확인합니다.
Not Ready to Switch On
│
▼
Switch On Disabled
│
│ Shutdown
▼
Ready to Switch On
│
│ Switch On
▼
Switched On
│
│ Enable Operation
▼
Operation Enabled
│
├───────────────┐
│ │
▼ ▼
Quick Stop Active Fault
▲
│
Fault Reaction Active
11.13.6 CiA 402 State Description
State |
Description |
Motion Command |
|---|---|---|
Not Ready to Switch On |
장치 초기화 중 |
불가 |
Switch On Disabled |
전원은 인가되었으나 Servo Enable 불가 상태 |
불가 |
Ready to Switch On |
Servo Enable 준비 상태 |
불가 |
Switched On |
Servo Power 준비 완료 |
불가 |
Operation Enabled |
Servo Enable 완료, Motion 가능 |
가능 |
Quick Stop Active |
Quick Stop 동작 중 |
제한 |
Fault Reaction Active |
Fault 발생 후 보호 동작 수행 중 |
불가 |
Fault |
오류 상태 |
불가 |
11.13.7 Controlword
Controlword(Object 0x6040)는 CiA 402 상태 전이를 제어하는 명령
Object입니다.
Bit |
Name |
Description |
|---|---|---|
Bit0 |
Switch On |
Switch On 명령 |
Bit1 |
Enable Voltage |
전압 Enable |
Bit2 |
Quick Stop |
Quick Stop 제어 |
Bit3 |
Enable Operation |
Operation Enable |
Bit4 |
Operation Mode Specific |
운전 모드별 기능 |
Bit5 |
Operation Mode Specific |
운전 모드별 기능 |
Bit6 |
Operation Mode Specific |
운전 모드별 기능 |
Bit7 |
Fault Reset |
Fault Reset |
Bit8 |
Halt |
정지 명령 |
Bit9 |
Operation Mode Specific |
운전 모드별 기능 |
Bit10~15 |
Reserved / Manufacturer Specific |
예약 또는 제조사 전용 |
11.13.8 Controlword 주요 명령
Command |
Controlword |
Description |
|---|---|---|
Shutdown |
0x0006 |
Ready to Switch On 상태로 전환 |
Switch On |
0x0007 |
Switched On 상태로 전환 |
Enable Operation |
0x000F |
Operation Enabled 상태로 전환 |
Disable Operation |
0x0007 |
Operation Enabled 해제 |
Disable Voltage |
0x0000 |
전압 Disable |
Quick Stop |
0x0002 |
Quick Stop 수행 |
Fault Reset |
0x0080 |
Fault 상태 해제 |
11.13.9 Statusword
Statusword(Object 0x6041)는 현재 CiA 402 상태를 나타내는 피드백
Object입니다.
Bit |
Name |
Description |
|---|---|---|
Bit0 |
Ready to Switch On |
Ready 상태 |
Bit1 |
Switched On |
Switched On 상태 |
Bit2 |
Operation Enabled |
Operation Enabled 상태 |
Bit3 |
Fault |
Fault 상태 |
Bit4 |
Voltage Enabled |
전압 Enable 상태 |
Bit5 |
Quick Stop |
Quick Stop 상태 |
Bit6 |
Switch On Disabled |
Switch On Disabled 상태 |
Bit7 |
Warning |
Warning 발생 |
Bit8 |
Manufacturer Specific |
제조사 전용 |
Bit9 |
Remote |
원격 제어 가능 |
Bit10 |
Target Reached |
목표값 도달 |
Bit11 |
Internal Limit Active |
내부 제한 활성 |
Bit12 |
Operation Mode Specific |
운전 모드별 상태 |
Bit13 |
Operation Mode Specific |
운전 모드별 상태 |
Bit14~15 |
Manufacturer Specific |
제조사 전용 |
11.13.10 Statusword 상태 판정
Host Controller는 Statusword의 특정 Bit 조합을 이용하여 현재 CiA 402 상태를 판정합니다.
State |
Statusword Mask |
Expected Value |
|---|---|---|
Not Ready to Switch On |
0x004F |
0x0000 |
Switch On Disabled |
0x004F |
0x0040 |
Ready to Switch On |
0x006F |
0x0021 |
Switched On |
0x006F |
0x0023 |
Operation Enabled |
0x006F |
0x0027 |
Quick Stop Active |
0x006F |
0x0007 |
Fault Reaction Active |
0x004F |
0x000F |
Fault |
0x004F |
0x0008 |
예를 들어 Statusword가 0x0027이면 다음과 같이 해석할 수 있습니다.
Statusword = 0x0027
Bit0 = 1 : Ready to Switch On
Bit1 = 1 : Switched On
Bit2 = 1 : Operation Enabled
Bit5 = 1 : Quick Stop 정상 상태
State = Operation Enabled
11.13.11 Servo Enable Sequence
SF시리즈를 Motion 가능한 상태로 전환하기 위한 일반적인 절차는 다음과 같습니다.
Power ON
│
▼
Boot-up 수신
│
▼
NMT Start
│
▼
Set Operation Mode
│
▼
Shutdown
│
▼
Switch On
│
▼
Enable Operation
│
▼
Motion Command
11.13.12 Servo Enable Controlword Sequence
Step |
Action |
Object |
Value |
확인할 Statusword |
|---|---|---|---|---|
1 |
Operation Mode 설정 |
0x6060 |
Mode Value |
0x6061 확인 |
2 |
Shutdown |
0x6040 |
0x0006 |
Ready to Switch On |
3 |
Switch On |
0x6040 |
0x0007 |
Switched On |
4 |
Enable Operation |
0x6040 |
0x000F |
Operation Enabled |
5 |
Target Value 전송 |
0x607A / 0x60FF / 0x6071 |
목표값 |
Statusword 확인 |
11.13.13 Operation Mode와 State Machine 관계
Operation Mode는 Object 0x6060으로 설정하며, 현재 적용된 운전
모드는 Object 0x6061에서 확인할 수 있습니다.
Mode Value |
Operation Mode |
Motion Object |
|---|---|---|
0x01 |
Profile Position Mode |
Target Position |
0x03 |
Profile Velocity Mode |
Target Velocity |
0x04 |
Profile Torque Mode |
Target Torque |
0x08 |
Cyclic Synchronous Position Mode |
Target Position |
0x09 |
Cyclic Synchronous Velocity Mode |
Target Velocity |
0x0A |
Cyclic Synchronous Torque Mode |
Target Torque |
Operation Mode는 Motion Command를 실행하기 전에 먼저 설정해야 합니다.
11.13.14 Fault State
Fault 상태는 장치 내부 오류가 발생했을 때 진입하는 보호 상태입니다.
Fault 상태에서는 일반적인 Motion Command가 실행되지 않으며, Host Controller는 오류 원인을 확인한 후 Fault Reset 절차를 수행해야 합니다.
Fault 발생 시 확인해야 하는 Object는 다음과 같습니다.
Object |
Description |
|---|---|
0x6041 Statusword |
Fault Bit 확인 |
0x603F Error Code |
현재 오류 코드 |
EMCY Message |
오류 발생 시 전송되는 긴급 메시지 |
0x1001 Error Register |
오류 유형 확인 |
11.13.15 Fault Reset Sequence
Fault Reset은 오류 원인을 제거한 후 수행해야 합니다.
Fault Detected
│
▼
Read EMCY / Error Code
│
▼
Remove Error Cause
│
▼
Controlword = 0x0080
│
▼
Shutdown
│
▼
Switch On
│
▼
Enable Operation
Step |
Action |
Controlword |
Description |
|---|---|---|---|
1 |
Fault Reset |
0x0080 |
Fault 해제 요청 |
2 |
Shutdown |
0x0006 |
Ready to Switch On |
3 |
Switch On |
0x0007 |
Switched On |
4 |
Enable Operation |
0x000F |
Operation Enabled |
경고
오류 원인을 제거하지 않은 상태에서 Fault Reset을 반복하지 마십시오. 동일 오류가 반복될 경우 장치, 전원, 배선, 부하 및 통신 상태를 점검해야 합니다.
11.13.16 Quick Stop State
Quick Stop은 비상 감속 정지를 수행하기 위한 상태입니다.
Quick Stop 명령은 Controlword의 Quick Stop 관련 Bit를 통해 수행되며, 장치는 설정된 Quick Stop Deceleration에 따라 감속합니다.
Object |
Description |
|---|---|
0x6040 Controlword |
Quick Stop 명령 |
0x6041 Statusword |
Quick Stop 상태 확인 |
0x605A Quick Stop Option Code |
Quick Stop 동작 방식 |
0x6085 Quick Stop Deceleration |
Quick Stop 감속도 |
Quick Stop 이후에는 장치 상태를 확인한 후 다시 Enable Operation 절차를 수행해야 합니다.
11.13.17 NMT State와 CiA 402 State 관계
NMT State와 CiA 402 State는 서로 다른 계층의 상태입니다.
NMT State |
CiA 402 State |
의미 |
|---|---|---|
Pre-operational |
Switch On Disabled / Ready 등 |
SDO 설정 가능, PDO 제어 불가 |
Operational |
Operation Enabled |
PDO 실시간 제어 가능 |
Operational |
Fault |
통신은 가능하나 Motion 불가 |
Stopped |
유지 또는 정지 상태 |
NMT/Heartbeat 외 통신 제한 |
즉, NMT가 Operational이라고 해서 항상 Motion이 가능한 것은 아닙니다. Motion을 실행하려면 CiA 402 상태가 반드시 Operation Enabled이어야 합니다.
11.13.18 Host Controller 상태 관리 로직
Host Controller는 다음과 같은 상태 관리 로직을 구현하는 것을 권장합니다.
Start
│
▼
Wait Boot-up
│
▼
NMT Start
│
▼
Read Statusword
│
├─ Fault
│ └─ Fault Reset Sequence
│
├─ Switch On Disabled
│ └─ Shutdown
│
├─ Ready to Switch On
│ └─ Switch On
│
├─ Switched On
│ └─ Enable Operation
│
└─ Operation Enabled
└─ Motion Command
11.13.19 Python 상태 판정 예시
def decode_pds_state(statusword):
if (statusword & 0x004F) == 0x0000:
return "Not Ready to Switch On"
if (statusword & 0x004F) == 0x0040:
return "Switch On Disabled"
if (statusword & 0x006F) == 0x0021:
return "Ready to Switch On"
if (statusword & 0x006F) == 0x0023:
return "Switched On"
if (statusword & 0x006F) == 0x0027:
return "Operation Enabled"
if (statusword & 0x006F) == 0x0007:
return "Quick Stop Active"
if (statusword & 0x004F) == 0x000F:
return "Fault Reaction Active"
if (statusword & 0x004F) == 0x0008:
return "Fault"
return "Unknown"
statusword = 0x0027
print(decode_pds_state(statusword))
출력 예시는 다음과 같습니다.
Operation Enabled
11.13.20 C 상태 판정 예시
#include <stdio.h>
#include <stdint.h>
const char* decode_pds_state(uint16_t statusword)
{
if ((statusword & 0x004F) == 0x0000)
return "Not Ready to Switch On";
if ((statusword & 0x004F) == 0x0040)
return "Switch On Disabled";
if ((statusword & 0x006F) == 0x0021)
return "Ready to Switch On";
if ((statusword & 0x006F) == 0x0023)
return "Switched On";
if ((statusword & 0x006F) == 0x0027)
return "Operation Enabled";
if ((statusword & 0x006F) == 0x0007)
return "Quick Stop Active";
if ((statusword & 0x004F) == 0x000F)
return "Fault Reaction Active";
if ((statusword & 0x004F) == 0x0008)
return "Fault";
return "Unknown";
}
int main(void)
{
uint16_t statusword = 0x0027;
printf("PDS State: %s\n", decode_pds_state(statusword));
return 0;
}
11.13.21 State Machine 사용 시 주의사항
State Machine을 사용할 때에는 다음 사항을 확인하십시오.
NMT 상태와 CiA 402 상태를 구분하여 처리하십시오.
PDO 제어는 NMT Operational 상태에서만 수행하십시오.
Motion Command는 CiA 402 Operation Enabled 상태에서만 수행하십시오.
Controlword 전송 후에는 반드시 Statusword를 확인하십시오.
Fault 상태에서는 먼저 Error Code와 EMCY를 확인하십시오.
Fault Reset은 오류 원인을 제거한 뒤 수행하십시오.
Operation Mode 설정 후
0x6061을 읽어 실제 적용 여부를 확인하십시오.Quick Stop 후에는 상태를 확인하고 필요 시 Enable Operation 절차를 다시 수행하십시오.
상태 전이 중에는 Target Position, Target Velocity, Target Torque 명령을 연속적으로 전송하지 마십시오.
중요
CANopen Motion Control의 안정성은 NMT State Machine과 CiA 402 PDS
FSA를 올바르게 조합하여 구현하는 것에 달려 있습니다. Host
Controller는 항상 Heartbeat, Statusword, Error Code,
EMCY를 함께 모니터링하고, 현재 상태에서 허용되는 명령만
전송해야 합니다.
11.14 Bit Definition
본 절에서는 SF시리즈 CANopen 통신에서 자주 사용되는 주요 Object의 Bit 정의를 설명합니다.
CANopen에서는 하나의 Object 값 안에 여러 상태 또는 제어 정보를 Bit 단위로 포함하는 경우가 많습니다. 대표적으로 다음 Object는 Bit 단위 해석이 필요합니다.
Object |
Index |
Description |
|---|---|---|
Controlword |
0x6040 |
CiA 402 상태 제어 |
Statusword |
0x6041 |
CiA 402 상태 표시 |
Error Register |
0x1001 |
오류 유형 표시 |
COB-ID |
0x1005, 0x1014, 0x1400, 0x1800 등 |
CAN Identifier 및 Enable/Disable |
PDO Mapping Entry |
0x1600, 0x1A00 등 |
PDO 매핑 데이터 구성 |
SDO Command Specifier |
SDO Byte0 |
SDO Read/Write 명령 구분 |
Digital Inputs |
0x60FD |
디지털 입력 상태 |
Digital Outputs |
0x60FE |
디지털 출력 상태 |
11.14.1 Bit Numbering
본 문서에서는 Bit 번호를 다음과 같이 정의합니다.
Bit15 Bit0
+--------------------------------------------------+
| MSB LSB |
+--------------------------------------------------+
용어 |
설명 |
|---|---|
Bit0 |
최하위 비트, LSB |
Bit15 |
16-bit 값의 최상위 비트 |
Bit31 |
32-bit 값의 최상위 비트 |
LSB |
Least Significant Bit 또는 Least Significant Byte |
MSB |
Most Significant Bit 또는 Most Significant Byte |
SF시리즈 CANopen은 Multi-byte 데이터를 Little-Endian으로 전송합니다.
예를 들어 16-bit 값 0x6040은 CAN Data Field에서 다음 순서로
전송됩니다.
0x6040 → 40 60
11.14.2 Controlword Bit Definition
Controlword(Object 0x6040)는 CiA 402 State Machine을 제어하기 위한
16-bit 명령 Object입니다.
Bit |
Name |
Description |
|---|---|---|
Bit0 |
Switch On |
Switch On 상태 전이 요청 |
Bit1 |
Enable Voltage |
드라이브 전압 Enable |
Bit2 |
Quick Stop |
Quick Stop 제어 |
Bit3 |
Enable Operation |
Operation Enabled 상태 전이 요청 |
Bit4 |
Operation Mode Specific |
운전 모드별 제어 Bit |
Bit5 |
Operation Mode Specific |
운전 모드별 제어 Bit |
Bit6 |
Operation Mode Specific |
운전 모드별 제어 Bit |
Bit7 |
Fault Reset |
Fault Reset 요청 |
Bit8 |
Halt |
모션 정지 요청 |
Bit9 |
Operation Mode Specific |
운전 모드별 제어 Bit |
Bit10 |
Reserved |
예약 |
Bit11 |
Manufacturer Specific |
제조사 전용 |
Bit12 |
Manufacturer Specific |
제조사 전용 |
Bit13 |
Manufacturer Specific |
제조사 전용 |
Bit14 |
Manufacturer Specific |
제조사 전용 |
Bit15 |
Manufacturer Specific |
제조사 전용 |
11.14.3 Controlword Command Pattern
Controlword의 주요 명령 패턴은 다음과 같습니다.
Command |
Controlword |
Bit Pattern |
Description |
|---|---|---|---|
Disable Voltage |
0x0000 |
0000 0000 0000 0000 |
전압 Disable |
Shutdown |
0x0006 |
0000 0000 0000 0110 |
Ready to Switch On 전환 |
Switch On |
0x0007 |
0000 0000 0000 0111 |
Switched On 전환 |
Enable Operation |
0x000F |
0000 0000 0000 1111 |
Operation Enabled 전환 |
Quick Stop |
0x0002 |
0000 0000 0000 0010 |
Quick Stop 수행 |
Fault Reset |
0x0080 |
0000 0000 1000 0000 |
Fault Reset 요청 |
11.14.4 Controlword Bit Mask
Controlword를 생성할 때에는 다음 Bit Mask를 사용할 수 있습니다.
Name |
Bit |
Mask |
|---|---|---|
SWITCH_ON |
Bit0 |
0x0001 |
ENABLE_VOLTAGE |
Bit1 |
0x0002 |
QUICK_STOP |
Bit2 |
0x0004 |
ENABLE_OPERATION |
Bit3 |
0x0008 |
FAULT_RESET |
Bit7 |
0x0080 |
HALT |
Bit8 |
0x0100 |
예를 들어 Enable Operation 명령은 다음 Bit 조합으로 구성됩니다.
Enable Operation = Bit0 + Bit1 + Bit2 + Bit3
0x0001 + 0x0002 + 0x0004 + 0x0008 = 0x000F
11.14.5 Statusword Bit Definition
Statusword(Object 0x6041)는 CiA 402 State Machine의 현재 상태를
나타내는 16-bit 피드백 Object입니다.
Bit |
Name |
Description |
|---|---|---|
Bit0 |
Ready to Switch On |
Ready to Switch On 상태 |
Bit1 |
Switched On |
Switched On 상태 |
Bit2 |
Operation Enabled |
Operation Enabled 상태 |
Bit3 |
Fault |
Fault 상태 |
Bit4 |
Voltage Enabled |
드라이브 전압 Enable 상태 |
Bit5 |
Quick Stop |
Quick Stop 상태 |
Bit6 |
Switch On Disabled |
Switch On Disabled 상태 |
Bit7 |
Warning |
Warning 발생 |
Bit8 |
Manufacturer Specific |
제조사 전용 |
Bit9 |
Remote |
원격 제어 가능 상태 |
Bit10 |
Target Reached |
목표값 도달 |
Bit11 |
Internal Limit Active |
내부 제한 활성 |
Bit12 |
Operation Mode Specific |
운전 모드별 상태 |
Bit13 |
Operation Mode Specific |
운전 모드별 상태 |
Bit14 |
Manufacturer Specific |
제조사 전용 |
Bit15 |
Manufacturer Specific |
제조사 전용 |
11.14.6 Statusword State Mask
Host Controller는 Statusword의 특정 Bit 조합을 이용하여 CiA 402 상태를 판정할 수 있습니다.
State |
Mask |
Expected Value |
|---|---|---|
Not Ready to Switch On |
0x004F |
0x0000 |
Switch On Disabled |
0x004F |
0x0040 |
Ready to Switch On |
0x006F |
0x0021 |
Switched On |
0x006F |
0x0023 |
Operation Enabled |
0x006F |
0x0027 |
Quick Stop Active |
0x006F |
0x0007 |
Fault Reaction Active |
0x004F |
0x000F |
Fault |
0x004F |
0x0008 |
예를 들어 Statusword가 0x0027이면 다음과 같이 판정합니다.
Statusword = 0x0027
0x0027 & 0x006F = 0x0027
State = Operation Enabled
11.14.7 Statusword Bit Mask
Name |
Bit |
Mask |
|---|---|---|
READY_TO_SWITCH_ON |
Bit0 |
0x0001 |
SWITCHED_ON |
Bit1 |
0x0002 |
OPERATION_ENABLED |
Bit2 |
0x0004 |
FAULT |
Bit3 |
0x0008 |
VOLTAGE_ENABLED |
Bit4 |
0x0010 |
QUICK_STOP |
Bit5 |
0x0020 |
SWITCH_ON_DISABLED |
Bit6 |
0x0040 |
WARNING |
Bit7 |
0x0080 |
REMOTE |
Bit9 |
0x0200 |
TARGET_REACHED |
Bit10 |
0x0400 |
INTERNAL_LIMIT_ACTIVE |
Bit11 |
0x0800 |
11.14.8 Operation Mode Specific Bit
Controlword와 Statusword의 일부 Bit는 운전 모드에 따라 의미가 달라집니다.
Profile Position Mode
Object |
Bit |
Name |
Description |
|---|---|---|---|
Controlword |
Bit4 |
New Set-point |
새로운 위치 명령 실행 |
Controlword |
Bit5 |
Change Set Immediately |
Set-point 즉시 변경 |
Controlword |
Bit6 |
Absolute / Relative |
절대 위치 또는 상대 위치 선택 |
Controlword |
Bit8 |
Halt |
감속 정지 |
Statusword |
Bit10 |
Target Reached |
목표 위치 도달 |
Statusword |
Bit12 |
Set-point Acknowledge |
Set-point 수신 확인 |
Statusword |
Bit13 |
Following Error |
위치 추종 오차 |
Profile Velocity Mode
Object |
Bit |
Name |
Description |
|---|---|---|---|
Controlword |
Bit8 |
Halt |
감속 정지 |
Statusword |
Bit10 |
Target Reached |
목표 속도 도달 또는 정지 완료 |
Statusword |
Bit11 |
Internal Limit Active |
속도 또는 전류 제한 활성 |
Statusword |
Bit12 |
Speed |
속도 관련 상태 |
Statusword |
Bit13 |
Maximum Slippage / Error |
속도 오차 또는 모드별 상태 |
Profile Torque Mode
Object |
Bit |
Name |
Description |
|---|---|---|---|
Controlword |
Bit8 |
Halt |
토크 램프에 따른 정지 |
Statusword |
Bit10 |
Target Reached |
목표 토크 도달 또는 정지 완료 |
Statusword |
Bit11 |
Internal Limit Active |
토크 또는 전류 제한 활성 |
Statusword |
Bit12 |
Mode Specific |
토크 모드별 상태 |
Statusword |
Bit13 |
Mode Specific |
토크 모드별 상태 |
Cyclic Synchronous Position Mode
Object |
Bit |
Name |
Description |
|---|---|---|---|
Controlword |
Bit8 |
Halt |
동기 위치 제어 정지 요청 |
Statusword |
Bit10 |
Target Reached |
목표 위치 도달 |
Statusword |
Bit11 |
Internal Limit Active |
내부 제한 활성 |
Statusword |
Bit12 |
Target Ignored / Mode Specific |
목표값 처리 상태 |
Statusword |
Bit13 |
Following Error |
위치 추종 오차 |
Cyclic Synchronous Velocity Mode
Object |
Bit |
Name |
Description |
|---|---|---|---|
Controlword |
Bit8 |
Halt |
동기 속도 제어 정지 요청 |
Statusword |
Bit10 |
Target Reached |
목표 속도 도달 또는 정지 완료 |
Statusword |
Bit11 |
Internal Limit Active |
내부 제한 활성 |
Statusword |
Bit12 |
Mode Specific |
속도 모드별 상태 |
Statusword |
Bit13 |
Mode Specific |
속도 모드별 상태 |
Cyclic Synchronous Torque Mode
Object |
Bit |
Name |
Description |
|---|---|---|---|
Controlword |
Bit8 |
Halt |
토크 램프에 따른 정지 |
Statusword |
Bit10 |
Target Reached |
목표 토크 도달 또는 정지 완료 |
Statusword |
Bit11 |
Internal Limit Active |
내부 제한 활성 |
Statusword |
Bit12 |
Mode Specific |
토크 모드별 상태 |
Statusword |
Bit13 |
Mode Specific |
토크 모드별 상태 |
참고
Bit12, Bit13은 운전 모드에 따라 의미가 달라질 수 있으므로, Host Controller는 현재 Operation Mode(0x6061)를 확인한 후 해석해야 합니다.
11.14.9 Error Register Bit Definition
Error Register(Object 0x1001)는 장치의 오류 유형을 나타내는 8-bit
Object입니다.
Bit |
Mask |
Description |
|---|---|---|
Bit0 |
0x01 |
Generic Error |
Bit1 |
0x02 |
Current Error |
Bit2 |
0x04 |
Voltage Error |
Bit3 |
0x08 |
Temperature Error |
Bit4 |
0x10 |
Communication Error |
Bit5 |
0x20 |
Device Profile Specific Error |
Bit6 |
0x40 |
Reserved |
Bit7 |
0x80 |
Manufacturer Specific Error |
예를 들어 Error Register 값이 0x04이면 Voltage Error가 발생한
것입니다.
0x04 = Bit2
Error Type = Voltage Error
11.14.10 EMCY Data Bit / Byte Definition
EMCY 메시지는 오류 발생 시 SF시리즈가 Master로 전송하는 8 Byte 메시지입니다.
Byte |
Name |
Description |
|---|---|---|
Byte0 |
Error Code Low Byte |
Emergency Error Code LSB |
Byte1 |
Error Code High Byte |
Emergency Error Code MSB |
Byte2 |
Error Register |
Object 0x1001 값 |
Byte3 |
Reserved |
예약 |
Byte4 |
Reserved |
예약 |
Byte5 |
Reserved |
예약 |
Byte6 |
Reserved |
예약 |
Byte7 |
Reserved |
예약 |
EMCY Error Code는 Little-Endian으로 해석합니다.
Data : 10 32 04 00 00 00 00 00
Error Code = 0x3210
Error Register = 0x04
11.14.11 COB-ID Bit Definition
CANopen COB-ID는 11-bit CAN Identifier를 기반으로 하며, PDO Communication Parameter에서는 32-bit 값으로 관리됩니다.
11-bit CANopen COB-ID
Bit10 Bit7 Bit6 Bit0
+---------------------+----------------------+
| Function Code | Node ID |
+---------------------+----------------------+
Bit Range |
Description |
|---|---|
Bit10~Bit7 |
Function Code |
Bit6~Bit0 |
Node ID |
32-bit PDO COB-ID Parameter
PDO Communication Parameter의 COB-ID는 32-bit 값으로 표현됩니다.
Bit31 Bit0
+------+-------+-------+-----------------------------+
|Valid | RTR | Frame | CAN Identifier |
+------+-------+-------+-----------------------------+
Bit |
Description |
|---|---|
Bit31 |
PDO Valid Bit |
Bit30 |
RTR 허용 여부 |
Bit29 |
Frame Format |
Bit28~11 |
Extended Identifier 사용 시 Identifier 영역 |
Bit10~0 |
Standard CAN Identifier |
PDO Valid Bit
Bit31 |
Meaning |
|---|---|
0 |
PDO Enable |
1 |
PDO Disable |
예를 들어 Node ID가 1인 TPDO1의 기본 COB-ID는 0x181입니다.
TPDO1 Enable = 0x00000181
TPDO1 Disable = 0x80000181
11.14.12 PDO Mapping Entry Bit Definition
PDO Mapping Entry는 32-bit 값으로 구성됩니다.
Bit31 Bit16 Bit15 Bit8 Bit7 Bit0
+----------------------+-----------------------+----------------+
| Object Index | Sub-index | Bit Length |
+----------------------+-----------------------+----------------+
Bit Range |
Description |
|---|---|
Bit31~Bit16 |
Object Index |
Bit15~Bit8 |
Sub-index |
Bit7~Bit0 |
Object Length in bits |
Mapping Entry 계산식은 다음과 같습니다.
Mapping Entry = (Index << 16) | (Sub-index << 8) | Bit Length
예를 들어 Controlword 0x6040:00을 16 bit로 매핑하는 경우:
Index = 0x6040
Sub-index = 0x00
Bit Length = 0x10
Mapping Entry = 0x60400010
11.14.13 SDO Command Specifier Bit Definition
SDO 메시지의 Byte0은 Command Specifier이며, SDO 요청 또는 응답의 종류를 나타냅니다.
SDO Request / Response 주요 값
Byte0 |
Direction |
Description |
|---|---|---|
0x2F |
Client → Server |
1 Byte Write |
0x2B |
Client → Server |
2 Byte Write |
0x23 |
Client → Server |
4 Byte Write |
0x40 |
Client → Server |
Read Request |
0x60 |
Server → Client |
Write Success Response |
0x4F |
Server → Client |
1 Byte Read Response |
0x4B |
Server → Client |
2 Byte Read Response |
0x43 |
Server → Client |
4 Byte Read Response |
0x80 |
Server → Client |
Abort Response |
SDO Abort Response Byte0
SDO Abort Response는 항상 Byte0에 0x80을 사용합니다.
Byte0 = 0x80
Meaning = SDO Abort Response
Abort Code는 Byte4~Byte7에 Little-Endian으로 저장됩니다.
Data : 80 40 60 00 02 00 01 06
Index = 0x6040
Sub-index = 0x00
Abort Code = 0x06010002
11.14.14 Heartbeat / NMT State Byte Definition
Heartbeat 메시지의 Data Byte는 NMT 상태를 나타냅니다.
Data |
NMT State |
|---|---|
0x00 |
Boot-up |
0x04 |
Stopped |
0x05 |
Operational |
0x7F |
Pre-operational |
예를 들어 Node ID가 1인 장치가 Operational 상태이면 다음 Heartbeat
메시지를 전송합니다.
COB-ID : 0x701
Data : 05
11.14.15 Digital Inputs Bit Definition
Digital Inputs(Object 0x60FD)는 디지털 입력 상태를 32-bit 값으로
표시합니다.
제품 구성에 따라 실제 입력 신호의 의미가 달라질 수 있으므로, 사용자는 제품의 I/O 설정과 Object Dictionary를 함께 확인해야 합니다.
일반적인 해석 방식은 다음과 같습니다.
Bit Range |
Description |
|---|---|
Bit0~Bit15 |
CiA 402 Device Profile 관련 입력 |
Bit16~Bit31 |
Manufacturer Specific 또는 물리 입력 신호 |
일반적인 사용 예시는 다음과 같습니다.
Bit |
Description |
|---|---|
Bit0 |
Negative Limit Switch 또는 Device Profile Input |
Bit1 |
Positive Limit Switch 또는 Device Profile Input |
Bit2 |
Home Switch 또는 Device Profile Input |
Bit16 |
Digital Input 1 |
Bit17 |
Digital Input 2 |
Bit18 |
Digital Input 3 |
Bit19 |
Digital Input 4 |
Bit20~Bit31 |
Manufacturer Specific |
참고
실제 Digital Input Bit 배치는 제품 모델, I/O 설정 및 펌웨어 버전에 따라 달라질 수 있습니다. 적용 전 실제 Object Dictionary 및 I/O 설정을 확인하십시오.
11.14.16 Digital Outputs Bit Definition
Digital Outputs(Object 0x60FE)는 디지털 출력 상태를 제어하거나
표시하는 32-bit Object입니다.
일반적으로 Digital Outputs는 출력값과 출력 Mask를 함께 사용합니다.
Sub-index |
Description |
|---|---|
0x00 |
Sub-index 개수 |
0x01 |
Physical Outputs |
0x02 |
Bit Mask |
일반적인 Bit 구성은 다음과 같습니다.
Bit Range |
Description |
|---|---|
Bit0~Bit15 |
CiA 402 Device Profile 관련 출력 |
Bit16~Bit31 |
Manufacturer Specific 또는 물리 출력 신호 |
예시는 다음과 같습니다.
Bit |
Description |
|---|---|
Bit16 |
Digital Output 1 |
Bit17 |
Digital Output 2 |
Bit18 |
Digital Output 3 |
Bit19 |
Digital Output 4 |
Bit20~Bit31 |
Manufacturer Specific |
참고
Digital Output을 사용할 때에는 Bit Mask 설정을 함께 확인해야 합니다. Mask가 비활성화된 Bit는 출력값을 기록해도 실제 출력에 반영되지 않을 수 있습니다.
11.14.17 Supported Drive Modes Bit Definition
Supported Drive Modes(Object 0x6502)는 장치가 지원하는 운전 모드를
Bit Field로 표시합니다.
일반적인 CiA 402 Drive Mode Bit 구성은 다음과 같습니다.
Bit |
Mode |
Description |
|---|---|---|
Bit0 |
PP |
Profile Position Mode |
Bit2 |
PV |
Profile Velocity Mode |
Bit3 |
PT |
Profile Torque Mode |
Bit5 |
HM |
Homing Mode |
Bit6 |
IP |
Interpolated Position Mode |
Bit7 |
CSP |
Cyclic Synchronous Position Mode |
Bit8 |
CSV |
Cyclic Synchronous Velocity Mode |
Bit9 |
CST |
Cyclic Synchronous Torque Mode |
예를 들어 0x0000038D는 Bit0, Bit2, Bit3, Bit7, Bit8, Bit9가
활성화된 상태로 해석할 수 있습니다.
Bit0 = PP
Bit2 = PV
Bit3 = PT
Bit7 = CSP
Bit8 = CSV
Bit9 = CST
11.14.18 Warning Code Bit / Value Definition
Warning Code(Object 0x3B68)는 현재 경고 상태를 나타냅니다.
Warning Code는 Bit Field라기보다 Code Value 방식으로 해석합니다.
Warning Code |
Description |
|---|---|
0x0000 |
No Warning |
0xFF00 |
Soft Velocity Error Warning |
0xFF01 |
Soft Position Error Warning |
0xFF02 |
Soft Locked-Rotor Protection Warning |
Warning이 발생하면 Statusword의 Warning Bit(Bit7)가 함께 활성화될 수 있습니다.
11.14.19 Bit Check Example
Host Controller는 Bit Mask를 이용하여 상태를 확인할 수 있습니다.
Python 예시
STATUSWORD_FAULT = 0x0008
STATUSWORD_OPERATION_ENABLED = 0x0004
STATUSWORD_WARNING = 0x0080
statusword = 0x0027
if statusword & STATUSWORD_OPERATION_ENABLED:
print("Operation Enabled")
if statusword & STATUSWORD_FAULT:
print("Fault")
if statusword & STATUSWORD_WARNING:
print("Warning")
C 예시
#include <stdint.h>
#include <stdio.h>
#define STATUSWORD_FAULT 0x0008
#define STATUSWORD_OPERATION_ENABLED 0x0004
#define STATUSWORD_WARNING 0x0080
int main(void)
{
uint16_t statusword = 0x0027;
if (statusword & STATUSWORD_OPERATION_ENABLED) {
printf("Operation Enabled\n");
}
if (statusword & STATUSWORD_FAULT) {
printf("Fault\n");
}
if (statusword & STATUSWORD_WARNING) {
printf("Warning\n");
}
return 0;
}
11.14.20 Bit Definition 사용 시 주의사항
Bit Field를 사용할 때에는 다음 사항을 반드시 확인하십시오.
Multi-byte 데이터는 Little-Endian으로 해석하십시오.
Controlword는 현재 CiA 402 상태에 따라 유효한 명령만 전송하십시오.
Statusword는 단일 Bit가 아니라 Mask와 Expected Value를 이용하여 상태를 판정하십시오.
Bit12, Bit13은 Operation Mode에 따라 의미가 달라질 수 있습니다.
Manufacturer Specific Bit는 제품 모델 및 펌웨어 버전에 따라 의미가 달라질 수 있습니다.
PDO Mapping Entry의 Bit Length 합계는 64 bit를 초과하지 않아야 합니다.
PDO COB-ID의 Bit31을 잘못 설정하면 PDO가 비활성화될 수 있습니다.
Error Register는 오류 유형만 나타내므로, 실제 오류 원인은 EMCY Error Code 또는 0x603F Error Code를 함께 확인하십시오.
Digital Input/Output Bit는 실제 I/O 설정과 일치하는지 확인하십시오.
중요
Bit 해석 오류는 Servo Enable 실패, Fault Reset 실패, 잘못된 Motion Command 또는 피드백 데이터 오해로 이어질 수 있습니다. Host Controller는 Object Dictionary의 Data Type, Access Type, PDO Mapping, Operation Mode 및 Bit Definition을 함께 확인하여 통신 로직을 구현해야 합니다.