누리로봇 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 동작 상태 모니터링

일반적인 통신 절차는 다음과 같습니다.

  1. CAN Bus 초기화

  2. Master와 Slave 연결

  3. NMT 명령을 이용한 네트워크 시작

  4. SDO를 이용한 초기 파라미터 설정

  5. PDO를 이용한 실시간 제어 및 상태 피드백

  6. Heartbeat 및 EMCY를 통한 상태 감시


2.2 네트워크 구성 예시 (Network Configuration Example)

일반적인 누리로봇 SF시리즈 CANopen 네트워크는 다음과 같이 구성됩니다.

../_images/Pasted_image_20260626085343.png

누리로봇 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 제어 순서

모션을 수행하기 위해서는 다음 순서에 따라 제어를 진행해야 합니다.

  1. CAN 통신 연결

  2. NMT를 Operational 상태로 전환

  3. 필요한 운전 파라미터 설정

  4. Operation Mode 설정

  5. Controlword를 이용하여 Servo Enable

  6. 목표값(Target Value) 전송

  7. Statusword를 확인하여 동작 상태 모니터링

  8. 필요 시 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 절차는 다음과 같습니다.

  1. 오류 원인 제거

  2. Statusword 확인

  3. Fault Reset(Controlword = 0x0080) 실행

  4. 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는 다음 순서로 피드백을 처리하는 것을 권장합니다.

  1. Heartbeat 수신 여부 확인

  2. EMCY 메시지 확인

  3. Statusword 확인

  4. Actual Position / Velocity / Torque 확인

  5. 필요 시 SDO Read 수행

  6. 오류 발생 시 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는 먼저 장치와 정상적으로 통신할 수 있는 환경을 구성해야 합니다.

초기화 과정은 다음 순서로 수행하는 것을 권장합니다.

  1. CAN Bus 초기화

  2. Baud Rate 설정

  3. Node ID 확인

  4. Boot-up 메시지 수신 확인

  5. 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를 수신하면 다음 순서로 처리하는 것을 권장합니다.

  1. EMCY 수신

  2. Error Code 확인

  3. Statusword 확인

  4. Motion 정지

  5. 오류 원인 제거

  6. Fault Reset 수행

  7. 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으로 제어하기 위한 기본 예제를 제공합니다.

예제는 다음 절차를 기준으로 작성되었습니다.

  1. NMT Start 명령 전송

  2. Operation Mode 설정

  3. Controlword 설정

  4. Target Position 전송

  5. 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

can0가 정상적으로 활성화되어 있는지 확인

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 데이터 처리

경고

본 코드는 통신 및 제어 절차 설명용 예제입니다. 실제 장비에 적용하기 전에는 반드시 무부하 상태에서 테스트하고, 위치 제한, 속도 제한, 토크 제한 및 비상 정지 회로를 확인하십시오.


다운로드

sf.eds

중요

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

코드의 --node-id와 장치 Node ID 일치

Baud Rate

코드의 --bitrate와 장치 Baud Rate 일치

CAN Interface

can0, PCAN, Kvaser 등 실제 인터페이스 이름 확인

PDO Mapping

장치가 Dynamic PDO Mapping을 지원하는지 확인

Operation Mode

사용할 모드가 장치에서 지원되는지 확인

Limit 설정

위치, 속도, 전류, 토크 제한값 확인

Safety

무부하 상태에서 먼저 시험


실행 시 권장 순서
  1. CAN Interface 활성화

  2. SF시리즈 전원 인가

  3. Boot-up 또는 Heartbeat 수신 확인

  4. SDO Read로 Node 응답 확인

  5. Pre-operational 상태에서 Heartbeat 및 PDO 설정

  6. Operational 상태로 전환

  7. Statusword 확인

  8. Fault 상태이면 Fault Reset

  9. Operation Mode 설정

  10. Servo Enable

  11. Motion Command 실행

  12. 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은 다음 절차에 따라 수행하십시오.

  1. EMCY 또는 Error Code 확인

  2. 오류 원인 제거

  3. Statusword에서 Fault 상태 확인

  4. Controlword에 0x0080 전송

  5. Shutdown 명령 전송

  6. Switch On 명령 전송

  7. Enable Operation 명령 전송

  8. 정상 운전 재개

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 IndexSub-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을 변경할 때에는 반드시 안전한 상태에서 다음 절차에 따라 수행하십시오.

  1. NMT 상태를 Pre-operational로 전환합니다.

  2. 해당 PDO를 비활성화합니다.

  3. Mapping Object의 Sub-index 0x000을 기록합니다.

  4. 필요한 Mapping Entry를 Sub-index 0x01부터 순서대로 기록합니다.

  5. Mapping Object의 Sub-index 0x00에 Mapping Entry 개수를 기록합니다.

  6. 해당 PDO를 다시 활성화합니다.

  7. NMT 상태를 Operational로 전환합니다.

  8. PDO 데이터 송수신이 정상적으로 동작하는지 확인합니다.


11.6.11 PDO 비활성화 및 활성화

PDO를 비활성화하려면 Communication Parameter의 COB-ID에서 Bit 311로 설정합니다.

PDO Disable = COB-ID | 0x80000000

PDO를 활성화하려면 COB-ID의 Bit 310으로 설정합니다.

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 상태로 전환한 후 설정하는 것을 권장합니다.

권장 절차는 다음과 같습니다.

  1. NMT Enter Pre-operational 전송

  2. PDO 비활성화

  3. PDO Mapping 변경

  4. PDO Communication Parameter 설정

  5. PDO 활성화

  6. NMT Start Remote Node 전송

  7. 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 메시지를 수신하면 다음 절차에 따라 처리하는 것을 권장합니다.

  1. EMCY COB-ID에서 Node ID를 확인합니다.

  2. Byte0~1의 Emergency Error Code를 해석합니다.

  3. Byte2의 Error Register를 확인합니다.

  4. Statusword(0x6041)를 읽어 Fault 상태를 확인합니다.

  5. Error Code(0x603F)를 읽어 현재 오류 코드를 확인합니다.

  6. Motion Command를 정지합니다.

  7. 오류 원인을 제거합니다.

  8. Fault Reset을 수행합니다.

  9. 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

항상 0x80

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 060x06010002로 해석해야 합니다.


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를 수신하면 다음 순서로 처리하는 것을 권장합니다.

  1. Response COB-ID가 0x580 + Node ID인지 확인합니다.

  2. Byte0 값을 확인합니다.

  3. Byte0이 0x80이면 Abort Response로 판단합니다.

  4. Byte1~3에서 Object Index와 Sub-index를 확인합니다.

  5. Byte4~7에서 Abort Code를 Little-Endian으로 변환합니다.

  6. Abort Code Table에서 오류 원인을 확인합니다.

  7. Object Dictionary의 Access, Data Type, Range, PDO Mapping 속성을 확인합니다.

  8. 필요한 경우 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:000x01을 기록하여 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:000x000F를 기록하여 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:005566을 기록하여 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

uint8_t

INTEGER8

SINT

int8_t

INTEGER16

INT

int16_t

INTEGER32

DINT

int32_t

UNSIGNED8

USINT

uint8_t

UNSIGNED16

UINT

uint16_t

UNSIGNED32

UDINT

uint32_t

예를 들어 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

int.from_bytes(data, "little", signed=False)

INTEGER8

int.from_bytes(data, "little", signed=True)

UNSIGNED16

int.from_bytes(data, "little", signed=False)

INTEGER16

int.from_bytes(data, "little", signed=True)

UNSIGNED32

int.from_bytes(data, "little", signed=False)

INTEGER32

int.from_bytes(data, "little", signed=True)

예시는 다음과 같습니다.

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를 수행할 때에는 다음 조건을 모두 만족해야 합니다.

  1. Object가 Write 가능한 Access Type이어야 합니다.

  2. Data Type과 Write 데이터 길이가 일치해야 합니다.

  3. 입력 값이 Min/Max 범위 내에 있어야 합니다.

  4. 현재 NMT 상태에서 접근 가능해야 합니다.

  5. 현재 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를 실행하려면 다음 두 조건을 모두 만족해야 합니다.

  1. NMT 상태가 Operational이어야 합니다.

  2. 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을 함께 확인하여 통신 로직을 구현해야 합니다.