Skip to content

튜토리얼 2: Elmo 모터 드라이버

CANbus 노드 및 연결

본 튜토리얼에서는 Elmo Solo Whistle 모터 드라이버로 CANbus 통신시스템 인터페이스를 구축하는 예제를 다룹니다. 시스템 인터페이스를 구성할 CANbus 장치인 Elmo Solo Whistle 모터 드라이버와 추가 장치에 대한 정보는 아래 표와 같습니다.


종류 설명 수량
SOL-WHI20/100E04 Elmo Gold Solo Whistle 모터 드라이버 1
HT02300-A00-HZ Emoteq, Inc brushless DC 모터 1
8PIN 고정식 단자대 - 1
USB to CAN 케이블 USB to CAN 컨버터 1
Connfly serial 9PIN 케이블 M형 CAN 컨버터 와 Elmo Solo 모터 드라이버 CAN Port 연결용 1
EElmo CANIN port 3PIN 케이블 - 1
Elmo 12PIN port 용 케이블 홀 센서 연결용 케이블 1
파워 서플라이 - 1

CANbus 시스템 구성 요소

Emoteq 모터 연결하기

시스템 구성을 위해 먼저 모터를 설치합니다. 아래의 사진을 참고하여 Emoteq 모터를 클램프로 고정하고, 모터에서 나오는 홀 센서의 PowerIN, PowerReturn, Sensor A, B, C 및 Motor Phase A, B, C 케이블을 8핀 고정식 단자대에 구분해서 연결합니다.


모터의 고정과 단자 연결이 완료되면, 아래 그림과 표를 참고하여 모터의 Motor Leads 단자와 Elmo Gold Driver 의 Phase output 단자를 연결합니다. 자세한 내용은 Emoteq 의 Direct Drive Housed and Frameless Brushless DC Motors Engineering GuideSolo Whistle Digital Servo Drive Installation Guide 를 참고하십시오.


PIN Signal >Function
1 PTC Positive Temperature Coefficient
2 PTC Positive Temperature Coefficient
3 N/C Not Connected
4 N/C Not Connected
AC Motor DC Motor
5 PE Protective earth Motor Motor
6 M1 Motor phase Motor N/C
7 M2 Motor phase Motor Motor
8 M3 Motor phase Motor Motor

모터 파워 커넥터 PIN

정리하자면, 다음과 같이 PIN 을 연결해야 합니다.

Emoteq Brushless Motor Elmo Gold Solo Driver
PIN matching position
(RED) A Motor leads Motor phase M1
(WHT) B Motor leads Motor phase M2
(BLK) C Motor leads Motor phase M3

Motor leads PIN 에 대응하는 Motor phase PIN

USB to CAN 컨버터 연결하기

모터 연결이 완료되면, USB to CAN 컨버터로 PC 와 Elmo Solo Whistle 모터 드라이버를 연결합니다.

먼저 Elmo 모터 드라이버의 CANIN port 에 연결되는 Elmo CANIN 3PIN 케이블의 끝에 Connfly 9PIN port 를 연결합니다. 이때, CANIN port 의 CAN H, CAN L, GND 의 위치와 USB to CAN 의 CAN H, CAN L, GND 의 위치를 확인하여 케이블이 해당 PIN 을 각각 짝지어 이어줄 수 있도록 연결합니다. 각 Port 의 PIN 맵은 다음과 같습니다. 자세한 내용은 Solo Whistle Digital Servo Drive Installation Guide 와 Ixxat 의 USB-to-CAN V2 USER MANUAL 을 참고하십시오.


Pin CANIN Pin CANOUT Signal Function
J6/1 J7/1 CAN_GND CAN ground
J6/2 J7/2 CAN_L CAN_L busline (dominant low)
J6/3 J7/3 CAN_H CAN_H busline (dominant high)

Elmo Solo Whistle 모터 드라이버 CAN Communication Pin 맵

Pin Allocation of USB to CAN V2 Compact and Embedded
Pin No.
Signal D-Sub 9 RJ45
CAN high 7 1
CAN low 2 2
CAN GND 3, 6 3, 7

Pin Allocation of USB to CAN V2 Compact

정리하면, 다음과 같이 PIN을 연결해야 합니다.

D-Sub 9 Signal
USB to CAN V2 Compact Elmo Solo Whistle 모터 드라이버
PIN matching position
7 CAN high CAN_H J6/3
2 CAN low CAN_L J6/2
3 CAN GND CAN_GND J6/1

USB to CAN & 모터 드라이버 PIN Matching Position

Elmo CANIN to CAN 컨버터 케이블을 연결하고 Connfly 9-pin port 를 USB to CAN 컨버터에 연결합니다. 그리고 Elmo CANIN 케이블을 Elmo Solo Whistle 모터 드라이버의 CANIN port 에 연결합니다.

USB to CAN 컨버터의 USB 를 PC 의 USB port 에 연결하는 것으로 모터 드라이버의 CAN 통신의 CANIN 환경 구축을 완료합니다.

Emoteq 모터 홀 센서 연결하기

다음 과정은 모터의 홀 센서를 연결할 차례입니다. Elmo Solo Whistle 모터 드라이버는 홀 센서 만 연결하는 것도 지원하기 때문에 모터 드라이버 의 12 PIN 커넥터에서 필요한 PIN 을 모터의 홀 센서 PIN 이 고정된 8PIN 고정식 단자대까지 연결주기만 하면 됩니다.

Elmo 사에서 제공하는 12PIN 케이블이 있으면 바로 모터 드라이버 에 연결하면 되지만, 본 튜토리얼을 진행할 때, 해당 케이블이 없다면 모터 드라이버 의 12PIN 커넥터의 PIN 맵을 확인해서 5V, PR, 홀 센서 A, B, C PIN 만을 가져오는 케이블을 직접 제작하도록 합니다. 모터 드라이버 의 12PIN 커넥터의 PIN 맵은 다음과 같습니다.


Incremental encoder Interpolated Analog Encoder Resolver Tachometer and Potentiometer
SOL-WHIAXX/YYYEZZ SOL-WHIAXX/YYYIZZ SOL-WHIAXX/YYYRZZ SOL-WHIAXX/YYYTZZ
Pin (J4) Signal Function Signal Function Signal Function Signal Function
1 HC Hall sensor C input HC Hall sensor C input NC HC Hall sensor C input
3 HA Hall sensor A input HA Hall sensor A input NC HA Hall sensor A input
4 PE Protective Earth PE Protective Earth PE Protective Earth PE Protective Earth
5 SUPRET Supply return SUPRET Supply return SUPRET Supply return SUPRET Supply return
6 +5V Encoder/Hall +5V supply +5V Encoder/Hall +5V supply +5V Encoder/Hall +5V supply +5V Encoder/Hall +5V supply
11 CHA- Channel A complement A- Sine A complement S3 Sine A complement Tac 1- Tacho Input 1 Neg. (20V max)
12 CHA Channel A A+ Sine A S1 Sine A Tac 1+ Tacho Input 1 Pos. (20V max)
7 INDEX- Index complement R- Reference complement R2 Vref complement f=1/TS, 50mA Maximum NC
8 INDEX Index R+ Reference R1 Vref f=1/TS, 50mA Max POT Potentiometer Input(5V max)
2 HB Hall sensor B input HB Hall sensor B input NC HB Hall sensor B input
9 CHB- Channel B complement B- Cosine B complement S4 Cosine B complement Tac 2- Tacho Input 2 Neg. (50V max)
10 CHB Channel B B+ Cosine B S2 Cosine B Tac 2+ Tacho Input 2 Pos. (50V max)

Main Feedback Port PIN detail

모터 드라이버의 5V, PR, 홀 센서 A, B, C PIN 에 케이블을 연결하였으면, PIN 의 Function 에 주의하여 각 케이블의 끝을 고정식 8PIN 단자대에 연결하도록 합니다. 모두 연결하게 되면, 아래 그림과 같은 모습을 볼 수 있습니다.


모터 드라이버와 홀 센서 PIN 연결

STEP 연결하기

홀 센서 까지 모두 연결을 완료하였다면, 이제는 CANOUT port 에 STEP 을 연결할 차례입니다. 이미 CANIN 을 PC 와 연결하였는데도 STEP 을 추가로 연결해야 하는 이유는 Elmo Solo Whistle 모터 드라이버의 CAN port 가 non-isolated 연결을 지원하기 때문입니다.

먼저 Elmo Solo Whistle 모터 드라이버의 CANOUT port 에 3PIN CAN 케이블을 연결하도록 합니다.


위와 같이, STEP 의 CAN H, L, GND 위치에 주의하여 CANOUT 케이블의 3개의 도선을 각각 연결해주도록 합니다. 이때, STEP 의 RS485/CAN 의 PIN 맵과 Elmo 모터 드라이버의 CANOUT port PIN 맵을 참고합니다. 해당 PIN 맵은 USB to CAN 컨버터 연결하기그림와 같습니다.

정리하면 다음과 같이 PIN을 연결해주어야 합니다.

Solo Whistle 모터 드라이버 STEP RS485/CAN Port
PIN matching position
J7/3 CAN_H CAN_H 6
J7/2 CAN_L CAN_L 7
J7/1 GND GND 5

모터 드라이버 & STEP PIN Matching Position

파워 서플라이 연결하기

마지막으로 파워 서플라이 1개를 설치하고, 12~195 VDC 전원을 인가해주어야 합니다. 파워 서플라이의 전원선을 연결하고, 전극 케이블 사이의 전위차는 12~195 VDC 가 되도록 전극 케이블을 연결합니다. 이 전극 케이블을 Elmo Solo Whistle 모터 드라이버에 연결합니다. 이때, 모터 드라이버의 PIN 위치를 잘 확인하여 연결하며, PIN 위치에 대한 설명은 다음과 같습니다.


>
Pin (J1) Signal Function
1 VL+ Auxiliary supply input
2 PR Auxiliary supply input return
3 VP+ Pos. power input
4 VP+ Pos. power input
5 PR Power return
6 PR Power return
7 PE Protective earth
8 N/C Not connected
9 N/C Not connected

Main & Auxiliary Power Pin details

Elmo Solo Whistle 모터 드라이버의 전원선 연결을 마치면 STEP 에 Ethernet 케이블과 전원선을 연결해주도록 하여 STEP 전원을 켭니다. 그리고 파워 서플라이의 전원까지 켜면 Elmo Solo Whistle 모터 드라이버의 CANOUT 커넥터 앞에 위치한 LED 가 적색으로 점등되며 전원이 정상적으로 들어오게 됩니다. 이제 모든 시스템 구성을 완료했습니다.

CANopen DSP-305 프로토콜 기반 모터 드라이버 초기화

STEP CANbus 통신 설정

Elmo Solo Whistle 모터 드라이버를 non-isolated 상태로 만들어 주기 위해 CANout port 에 연결되어 있는 STEP 의 CAN 통신 설정을 모터 드라이버의 기본 설정에 맞추어 변경해주어야 합니다. 이를 통해, STEP 과 PC, Elmo Solo Whistle 모터 드라이버 간의 CANbus 통신 상태도 확인이 가능합니다.

먼저, PuTTY 와 같은 SSH 프로그램을 실행하여 STEP 에 접속합니다. Advanced IP Scanner 와 같은 프로그램을 이요하여 STEP 의 IP 를 확인한 다음 PuTTY 에 입력하여 해당 STEP 에 접속합니다. 그 다음 STEP 의 CAN 통신용 SERCAN 드라이버가 제대로 설치되어 있는지 확인하기 위해 아래 명령어를 입력합니다.

1
$ ls -l /usr/bin/*SERCAN*

이때, 제대로 설치되어 있지 않다면, SERCAN 펌웨어 업데이트 를 참고하여 SERCAN 펌웨어를 업데이트 하십시오.

Elmo Solo Whistle 모터 드라이버의 기본 설정에 맞도록 STEP 에서 설정해주어야 할 CANbus 통신 옵션은 비트레이트 단 한 개입니다. Elmo Solo Whistle 모터 드라이버의 초기 비트레이트 설정이 500K 이므로 STEP 의 비트레이트 설정이 500K 인지 다음 명령어로 확인합니다.

1
$ sudo SERCAN_setBitrate

STEP 의 비트레이트가 500K 가 아니라면 다음 명령어를 사용해 변경해주도록 합니다.

1
$ sudo SERCAN_setBitrate 500K

USB to CAN 컨버터 드라이버 설치

STEP 의 설정 후, Elmo Solo Whistle 모터 드라이버의 CANIN port 에 연결된 USB to CAN 컨버터를 조작할 VCI Driver 를 설치해야 합니다. VCI Driver 는 PC 에서 USB to CAN 컨버터를 인식하도록 만들어 주고, PC 에서 입력한 CANbus 메시지를 컨버터를 통해 Elmo Solo Whistle 모터 드라이버로 보내주는 역할을 하므로 필수적입니다. 또한, VCI Driver 설치 후에는 USB to CAN 컨버터를 연결 해제하고 다시 연결하여 CANbus 통신 설정을 완료합니다.

canAnalyser3 Mini 를 이용한 초기화 진행

CANbus 통신 설정

PC 에서 CANbus 통신을 사용하기 위해서는 USB to CAN 컨버터와 VCI Driver, canAnalyser3 Mini 가 필요합니다. PC 에 USB to CAN 컨버터를 연결하고, VCI Driver 를 설치하는 과정은 이미 완료했으므로, 이제 canAnalyser3 Mini 로 직접 CANbus 메시지를 작성하여 Elmo Solo Whistle 모터 드라이버에 전송하고 응답을 받는 방법을 알아보도록 합니다.


canAnalyser3 Mini 실행 화면

canAnalyser3 Mini 를 실행하여 컨버터의 비트레이트를 모터 드라이버의 기본 설정과 동일하게 해주어야 합니다. 그러므로 프로그램의 좌측 상단의 Bus settings 를 클릭합니다.


canAnalyser3 Mini 내 Bus settings

비트레이트 500K 의 CAN 통신을 사용해야 하므로, 아래 그림과 같이 창 좌측에서 CAN 을 선택하고, 우측에서 비트레이트를 500 CiA 로 설정합니다.


Bus setting 탭 설정 화면

설정이 모두 끝나면 OK 를 눌러 창을 닫고 canAnalyser3 Mini 로 돌아옵니다.

모드 변경 (Configuration)


사용 명령어 입력 화면

이제 본격적으로 모터 드라이버의 초기화를 진행합니다. 초기화는 LSS (Layer Setting Services) 라고 불리는 DSP-305 통신규약을 바탕으로 이루어집니다. 따라서 초기화에서 다루는 CANbus (CANopen) 메시지는 모든 CANbus (CANopen) 통신 기기에서 공통적으로 사용할 수 있습니다.

먼저, LSS 를 지원하는 기기 (일반적으로 모든 CANopen 장치) 에는 Configuraton 모드와 Operation 모드 2개의 LSS 모드가 있습니다. Configuration 모드는 LSS 슬레이브로, LSS 마스터로부터 오는 Configuration 명령을 받고 처리하는 모드입니다. Operation 모드는 LSS 슬레이브로, LSS 마스터로부터 오는 명령 중 모드 변경 외의 모든 Configuration 명령을 무시하는 모드입니다.

Elmo Solo Whistle 모터 드라이버는 부팅 후 연결된 다른 노드들에게 ID 70100 00 이라는 부팅 메시지를 전송하고 자동으로 Operation 모드로 전환됩니다.


모터 드라이버 부팅 시의 수신 메시지

위 그림에서 확인할 수 있듯이, Start 버튼 클릭 후 Elmo 모터 드라이버의 전원을 켰을 때 모터 드라이버로부터 수신되는 CANbus 메시지가 바로 부팅 메시지입니다.

따라서 사용자의 편의를 위해 Elmo Solo Whistle 모터 드라이버의 초기 설정을 변경해주는 작업이 초기화 과정이며, 이를 위해서는 부팅 후에 Configuration 모드로 전환하는 메시지를 입력해주어야 합니다.

메시지의 입력 전, 먼저 canAnalyser3 Mini 의 Start 버튼을 클릭하여 PC 의 USB to CAN 컨버터와 Elmo 모터 드라이버 사이의 CANbus 통신을 활성화합니다.

이제 Elmo 모터 드라이버 (LSS 슬레이브) 의 모드를 바꿔줍니다. 모드를 Configuration 으로 바꾸는 CANopen DSP-305 (LSS) 메시지는 다음과 같습니다 ((자세한 내용은 Elmo Motion Control CANopen DSP 305 Implementation Guide Ver. 1.1 을 참고하십시오).


모든 슬레이브의 Configuration 모드 전환 (CANopen)

CANopen 메시지에서 h 가 붙은 숫자는 16진수를 의미하며, 아무 표시도 없이 숫자만 있는 경우는 10진수를 의미한다는 것에 유의하도록 합니다.

이 CANopen DSP-305(LSS) 메시지를 CANbus 메시지로 변환하면 다음과 같습니다. CANopen 메시지와는 달리 CANbus 메시지는 모든 숫자가 16진수입니다. 따라서 이 표에서는 숫자만 있어도 16진수를 표현했다는 것에 유의하도록 합니다 (XX 는 00h 즉, NULL 을 의미).

Receiver ID Data Field Data Field
D1 D2 D3 D4 D5 D6 D7 D8
7E5 04 01 XX XX XX XX XX XX

모든 슬레이브의 Configuration 모드 전환 (CANbus)

canAnalyser3 Mini 의 메시지 전송은 CANbus 방식이므로, 위 표를 참고하여 메시지를 작성 및 전송하면, 아래 그림과 같은 결과가 나옵니다. 그림에서도 확인할 수 있듯 이 메시지는 Elmo 모터 드라이버로부터 응답이 없습니다.


Configuration 모드 전환

Node-ID 설정

모드를 전환한 뒤에는 Node-ID 를 재설정해주어야 합니다. Node-ID 는 PDO (데이터 메시지를 해석하는 object) 의 ID 및 SDO (PDO 를 정의하는 object) 의 ID 와 COB-ID 를 결정합니다. 또한, Elmo Solo Whistle 모터 드라이버의 Node-ID 초기값은 항상 0x7F 로 다축 프로젝트를 진행하는 경우 각각의 노드들을 구분하기 위해서 Node-ID 재설정은 필수입니다.

본 튜토리얼에서는 Node-ID 초기값이 0x7F 인 모터 드라이버를 0x01 로 변경합니다. 이에 해당하는 CANopen DSP-305(LSS) 메시지는 다음과 같습니다.


슬레이브 Node-ID 변경 (CANopen)

이 CANopen DSP-305(LSS) 메시지를 CANbus 메시지로 변환하면 다음과 같습니다.

Receiver ID Data Field Data Field
D1 D2 D3 D4 D5 D6 D7 D8
7E5 11 01 XX XX XX XX XX XX

슬레이브 Node-ID 변경 (CANbus)

canAnalyser3 Mini 의 메시지 전송은 CANbus 방식이므로, 위 표를 참고하여 메시지를 작성 및 전송하면, 아래 그림과 같은 결과가 나옵니다. 그림에서도 확인할 수 있듯 이 메시지는 모터 드라이버로부터 오는 응답이 있습니다.


Node-ID 설정 (01)

위 그림에서 확인한 Node-ID 변경에 대한 Elmo 모터 드라이버의 CANbus 응답 메시지는 다음과 같습니다.

Transmitter ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
7E4 11 00 00 XX XX XX XX XX

슬레이브 Node-ID 확인 (CANbus)

이 CANbus 메시지를 CANopen DSP-305(LSS) 메시지로 변환하면 다음과 같습니다.


슬레이브 Node-ID 확인 (CANopen)

이때, Error Code 의 의미는 다음과 같습니다.

Error Code Meaning
00h Protocol successfully completed
01h Node-ID out of range
02h~FEh Reserved for further use by CiA
FFh Implementation specific error occured

Node-ID Switching Error Code

또한, Specific Error Code 의 의미는 다음과 같습니다.

Error Code Specific Error Code Meaning
00h~FEh 00h
FFh 02h Incorrect mode. No other options at this time.

Meanning of Specific Error Code of Node-ID Switching

Error Code 표들을 참고하면 위 그림에서 진행한 Node-ID 설정이 성공적으로 된 것을 알 수 있습니다.

비트 타이밍 파라미터 설정

Node-ID 를 재설정한 뒤에는 비트 타이밍 파라미터를 재설정해주어야 합니다. 비트 타이밍 파라미터는 통신 속도를 결정합니다. 또한, 통신 속도가 서로 다르면 통신이 이루어지지 않기 때문에 연결된 노드들의 비트 타이밍 파라미터 확인 및 설정은 필수입니다.

본 튜토리얼에서는 비트 타이밍 파라미터를 Elmo Solo Whistle 모터 드라이버의 초기값인 500kBit 를 그대로 사용합니다. 따라서 이 설정을 굳이 해줄 필요는 없지만 비트 타이밍 파라미터의 변경이 필요할 시에는 다음의 CANopen DSP-305 (LSS) 메시지를 참고하십시오.


비트 타이밍 설정 (CANopen)

여기서 Table Selector 에 넣어주어야 하는 숫자는 아래 표와 같이 선택할 수 있습니다. 예를 들어, 500 CiA 를 선택하고자 하는 경우, 500 CiA 는 Standard CiA Bit Timing Table 에 위치하므로 0을 넣어주면 됩니다 (자세한 내용은 Elmo Motion Control CANopen DSP 305 Implementation Guide Ver. 1.1 을 참고하십시오).

Table (10진수) Table (16진수) Selection
0 00h Standard CiA Bit Timing Table
1~127 01h~7Fh Reserved for further use by CiA
128~255 80h~FFh For use by manufacturer for specific but timings

Table Selector Table

만약, Table SelectorStandard CiA Bit Timing Table 로 선택했다면, 다음으로 Table Index 에 넣어주어야 하는 숫자는 다음 표에서 선택할 수 있습니다. 예를 들어 500 kBit 를 선택하고자 하는 경우, 2를 넣어주면 됩니다.

Table (10진수) Table (16진수) Baud Rate
0 00h 1000 k Bit
0 00h 1000 k Bit
1 01h 800 k Bit
2 02h 500 k Bit
3 03h 250 k Bit
4 04h 125 k Bit
5 05h Reserved
6 06h 50 k Bit
7 07h Not supported
8 08h Not supported

Standard CiA Bit Timing Table

이 CANopen DSP-305(LSS) 메시지를 CANbus 메시지로 변환하면 다음과 같습니다.

Receiver ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
7E5 13 ## ## XX XX XX XX XX

비트 타이밍 선택 (CANbus)

canAnalyser3 Mini 의 메시지 전송은 CANbus 방식이므로, 위 표들을 참고하여 메시지를 작성 및 전송하면, 아래 그림과 같이 이 메시지에 대한 Elmo 모터 드라이버로부터의 응답이 있습니다.


비트 타이밍 설정 (500K)

비트 타이밍 변경 시 Elmo 모터 드라이버로부터의 CANbus 응답 메시지는 다음과 같습니다.

Transmitter ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
7E4 13 00 00 XX XX XX XX XX

비트 타이밍 확인 메시지 (CANbus)

이 CANbus 메시지를 CANopen DSP-305(LSS) 메시지로 변환하면 다음과 같습니다.


비트 타이밍 확인 메시지 (CANopen)

이때, Error Code 에 들어가는 숫자에 따른 의미는 다음과 같습니다.

Error Code Meaning
00h Protocol successfully completed
01h Node-ID out of range
02h~FEh Reserved for further use by CiA
FFh Implementation specific error occured

Bit Timing Select Error Code

또한, Specific Error Code 에 들어가는 숫자에 따른 의미는 다음과 같습니다.

Error Code Specific Error Code Meaning
00h~FEh 00h
FFh 02h Incorrect mode.
FFh 03h Out of range

Specific Error Code of Bit Timing Selecting

Error Code 표들을 참고하면 위 그림에서 진행한 비트 타이밍 파라미터 설정이 성공적으로 된 것을 알 수 있습니다.

파라미터 저장

Node-ID 와 비트 타이밍 파라미터의 변경 메시지를 보낸 후에는 해당 값들을 비휘발성 메모리에 저장하도록 하는 메시지를 반드시 전송해주어야 합니다. 그렇지 않으면 휘발성 메모리에 저장되었던 Node-ID 와 비트 타이밍 파라미터가 Node 재시동 시 삭제되어 기본 값으로 자동 변경됩니다.

변경한 Node-ID 와 비트 타이밍은 Node 의 시동 중에는 적용되지 않고, Node 는 재시동 시 비휘발성 메모리에 저장된 Node-ID 와 비트 타이밍 파라미터로 CANbus 네트워크를 구축하기 때문에 Node-ID 와 비트 타이밍의 저장은 필수입니다.

그러면 이제 전송할 메시지를 알아보도록 하겠습니다. 전송할 CANopen DSP-305(LSS) 메시지는 다음과 같습니다.


설정 파라미터 저장 (CANopen)

이 CANopen DSP-305(LSS) 메시지를 CANbus 메시지로 변환하면 다음과 같습니다.

Receiver ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
7E5 17 XX XX XX XX XX XX XX

설정 파라미터 저장 (CANbus)

canAnalyser3 Mini 의 메시지 전송은 CANbus 방식이므로, 위 표를 참고하여 메시지를 작성 및 전송하면, 아래 그림과 같은 결과가 나옵니다. 그림에서도 확인할 수 있듯 이 메시지는 Elmo 모터 드라이버로부터의 응답이 있습니다.


모터 드라이버의 비휘발성 메모리 저장 명령어

메시지 전송 시에 Elmo 모터 드라이버로부터의 CANbus 응답은 다음과 같습니다.

Transmitter ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
7E4 17 00 00 XX XX XX XX XX

설정 파라미터 확인 (CANbus)

이 CANbus 메시지를 CANopen DSP-305(LSS) 메시지로 변환하면 다음과 같습니다.


설정 파라미터 확인 (CANopen)

이때, Error Code 에 들어가는 숫자에 따른 의미는 다음과 같습니다.

Error Code Meaning
00h Protocol successfully completed
01h Store configuration is not supported
02h Storage media access error
03h~FEh Reserved for further use by CiA
FFh Implementation specific error occurred

파라미터 저장 Error Code

또한, Specific Error Code 에 들어가는 숫자에 따른 의미는 다음과 같습니다.

Error Code Specific Error Code Meaning
00h~FEh 00h
FFh 02h Incorrect mode. No other options at this time.

파라미터 저장 Specific Error Code

Error Code 표들을 참고하면 위 그림에서 진행한 파라미터 저장이 성공적으로 된 것을 알 수 있습니다.

Node-ID 확인

앞에서 Node-ID 를 바꿔주는 메시지를 보냈다면, 재시동 전까지는 현재 시동 중인 Node-ID 를 출력합니다. 하지만, Node-ID 를 잃어버렸을 때나 Node-ID 변경 후 변경 유무를 확인하는 용도로 다음과 같은 메시지를 사용합니다.

현재 시동중인 Node 의 Node-ID 를 받아오도록 하는 CANopen DSP-305(LSS) 메시지는 다음과 같습니다.


Node-ID 요청 (CANopen)

이 CANopen DSP-305(LSS) 메시지를 CANbus 메시지로 변환하면 다음과 같습니다.

Receiver ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
7E5 5E XX XX XX XX XX XX XX

Node-ID 요청 (CANbus)

canAnalyser3 Mini 의 메시지 전송은 CANbus 방식이므로, 위 표를 참고하여 메시지를 작성 및 전송하면, 아래 그림과 같은 결과가 나옵니다. 그림에서도 확인할 수 있듯 이 메시지는 Elmo 모터 드라이버로부터의 응답이 있습니다.


현재 시동 중인 Node 의 Node-ID 확인

메시지 전송 시에 Elmo 모터 드라이버로부터의 CANbus 응답 메시지는 다음과 같습니다.

Transmitter ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
7E4 5E ## 00 XX XX XX XX XX

Node-ID 확인 (CANbus)

이 CANbus 메시지를 CANopen DSP-305(LSS) 메시지로 변환하면 다음과 같습니다.


Node-ID 확인 (CANopen)

위 표에서 NID 위치에 오는 숫자가 Node-ID 입니다. 다시 말해, Elmo 모터 드라이버로부터의 CANbus 응답 메시지 Data Field 의 D2 자리 숫자가 Node-ID 입니다.

그림에서는 본래 Node-ID 가 01 이었던 Node 의 Node-ID 를 01로 변경하는 메시지를 주었기에 구분되지 않습니다. 만약, 본래 Node-ID 가 127 이었던 Node 의 Node-ID 를 01 로 변경하는 메시지를 준 뒤, 리셋하지 않고 Node-ID 요청 메시지를 전송하면 D2 자리에 01h (Node-ID: 1) 가 아니라 7Fh (Node-ID: 127) 로 나타납니다.

Node 리셋

비휘발성 메모리에 변경한 Node-ID 와 비트 타이밍 파라미터를 저장한 후, 변경한 설정을 적용하기 위해서 Node 를 리셋해야 합니다. 리셋하도록 하는 CANopen 메시지는 다음과 같습니다.

COB-ID rtr len NMT Function (1byte) Target Node (1byte)
0x000 0 2 0x81 0x01

DSP-301 Node 리셋 메시지의 NMT 프로토콜

이 메시지를 CANbus 형식으로 바꾸면 다음과 같습니다.

Receiver ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
000 81 01 XX XX XX XX XX XX

Node 리셋 메시지 (CANbus)

이때, 타겟 Node 자리 (D2) 에 들어 갈 16진수는 현재 시동 중인 Node 중 리셋 할 Node 의 Node-ID 입니다. 시동 중이던 Node 의 Node-ID 가 01이 아니라면 해당하는 자리에 01대신 자신이 리셋하고자 하는 Node 의 Node-ID를 적어 메시지를 송신합니다. 이때, Node-ID 자리에 00을 입력하면, 연결된 모든 Node 를 리셋하도록 하는 메시지가 됩니다.


모터 드라이버의 Node-ID 1 리셋 (저장한 설정들로 재부팅)

리셋 메시지를 송신하면 위 그림과 같이 Elmo 모터 드라이버가 재부팅되어 새롭게 설정한 Node-ID, 비트 타이밍이 적용되게 됩니다.

비트 타이밍 파라미터를 변경하지 않은 경우, 재부팅과 동시에 ID 701의 00 00이라는 부팅 성공 메시지가 수신되는 것을 확인할 수 있습니다. 하지만, 비트 타이밍 파라미터를 변경한 경우, 재부팅 후 부팅 성공 메시지가 수신되지 않으며, stuff error 가 발생합니다.

이 에러는 비트 타이밍 파라미터를 재설정으로 Elmo 모터 드라이버와 USB to CAN 컨버터의 통신 속도가 달라져 생기는 에러입니다. 이 경우, canAnalyser3 Mini 에서 STOP 을 클릭하여 잠시 CANbus 통신을 멈추고 bus setting 으로 가서 비트레이트를 Elmo 모터 드라이버에서 변경한 비트 타이밍으로 재설정해준 뒤, 다시 Start 를 눌러야 합니다.

이러한 방식으로 Elmo 모터 드라이버의 통신 설정을 바꿔준 후에는 USB to CAN 컨버터의 통신 설정도 모터 드라이버의 설정과 맞게 재설정해야합니다. 재설정 후에야 원활한 CANbus 통신이 가능해집니다.

재부팅 후에는 Node 가 자동으로 Operation 모드에 있도록 설정됩니다. 따라서 재부팅 후에 Operation 모드로 돌아가는 CANopen DSP-305 (LSS) 메시지를 송신 할 필요는 없습니다.

모드 변경 (Operation)

앞에서 설명한 바와 같이, 재부팅 후에는 Node 가 자동으로 Operation 모드로 돌아갑니다. 하지만 Configuration 모드에서 Node 의 값을 확인하기만 했을 경우 재부팅을 하진 않습니다. 이 경우에는 Operation 모드로 돌아가도록 하는 메시지를 송신하면 됩니다.

모드를 Operation 으로 바꾸는 CANopen DSP-305(LSS) 메시지는 다음과 같습니다.


모든 슬레이브의 Operation 모드 전환 (CANopen)

이 CANopen DSP-305(LSS) 메시지를 CANbus 메시지로 변환하면 다음과 같습니다.

Receiver ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
7E5 04 01 XX XX XX XX XX XX

모든 슬레이브의 Operation 모드 전환 (CANbus)

canAnalyser3 Mini 의 메시지 전송은 CANbus 방식이므로, 위 표를 참고하여 메시지를 작성 및 전송하면, 아래 그림과 같은 결과가 나옵니다. 그림에서도 확인할 수 있듯 이 메시지는 Elmo 모터 드라이버로부터의 응답이 없습니다.


Operation 모드 전환

NMT 프로토콜

LSS 프로토콜을 사용하여 Node 의 설정을 변경 및 확인하였다면, 이제 모터를 튜닝하고, Elmo 모터 드라이버를 작동시킬 차례입니다.

이에 앞서 NMT 프로토콜에 대해 먼저 알아두어야 합니다. NMT 프로토콜은 Elmo 모터 드라이버가 LSS Operation 모드에 있을 때, 모터 드라이버의 제어 범위를 변경하도록 하는 메시지의 정해진 형식입니다.

NMT 프로토콜에 따른 CANopen 메시지는 다음과 같이 정의됩니다.

COB-ID rtr len NMT Function Target Node
0x000 0 2 1byte 1byte

NMT 프로토콜에 따른 CANopen 메시지 형식

기본적으로 Operation 모드에 있는 Elmo 모터 드라이버가 Operational, Pre-operational, Stopped 중 어떤 상태에 있느냐에 따라 제어 범위가 다르기 때문에 원하는 제어 범위에 따라 상태를 변경해주는 것이 좋습니다. 각 상태에 따라 제어할 수 있는 범위는 다음 표에 자세히 설명되어 있습니다.

Function Stopped Pre-operational Operational
NMT Yes Yes Yes
EMCY No Yes Yes
PDO No No Yes
SDO No Yes Yes
GUARD Yes Yes Yes
SYNC No Yes Yes
TIMESTAMP No Yes Yes

Node 상태 따른 제어 범위

  • 기본적으로 Node 는 부팅 후에 Operation 모드의 Pre-operational 상태에 있습니다.

상태 변경 (Operational)

ID 가 01인 Node 의 상태를 Operational 으로 변경하도록 하는 CANopen 메시지는 NMT 프로토콜에 의해 다음과 같이 정해집니다.

COB-ID rtr len NMT Function Target Node
0x000 0 2 0x01 0x01

Operational 상태로 변경하는 CANopen 메시지 형식

이 CANopen 메시지를 CANbus 메시지 형식으로 변환하면 다음과 같습니다.

Receiver ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
000 01 01 XX XX XX XX XX XX

Operational 상태로의 변경 (CANbus)

상태 변경 (Stopped)

Node 의 상태를 Stopped 으로 변경하도록 하는 CANopen 메시지는 NMT 프로토콜에 의해 다음과 같이 정해집니다.

COB-ID rtr len NMT Function Target Node
0x000 0 2 0x02 0x01

Stop 상태로 변경하는 CANopen 메시지 형식

이 CANopen 메시지를 CANbus 메시지 형식으로 변환하면 다음과 같습니다.

Receiver ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
000 02 01 XX XX XX XX XX XX

Stopped 상태로의 변경 (CANbus)

상태 변경 (Pre-operational)

Node 의 상태를 Pre-operational 상태로 변경하도록 하는 CANopen 메시지는 NMT protocal에 의해 다음과 같이 정해집니다.

COB-ID rtr len NMT Function Target Node
0x000 0 2 0x80 0x01

Pre-operational 상태로 변경하는 CANopen 메시지 형식

이 CANopen 메시지를 CANbus 메시지 형식으로 변환하면 다음과 같습니다.

Receiver ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
000 80 01 XX XX XX XX XX XX

Pre-operational 상태로의 변경 (CANbus)

Node 리셋

Node 의 휘발성 메모리를 모두 삭제하고 비휘발성 메모리를 기반으로 재부팅하도록 하는 리셋 NMT 프로토콜 CANopen 메시지는 상태 변경 NMT 프로토콜 CANopen 메시지와는 다르게 LSS Configuration 모드에서도 사용할 수 있습니다.

ID 가 01인 Node 를 리셋하도록 하는 CANopen 메시지는 NMT 프로토콜에 의해 다음과 같이 정해집니다.

COB-ID rtr len NMT Function Target Node
0x000 0 2 0x81 0x01

리셋 CANopen 메시지 형식

이 CANopen 메시지를 CANbus 메시지 형식으로 변환하면 다음과 같습니다.

Receiver ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
000 81 01 XX XX XX XX XX XX

Node 리셋 (CANbus)

Node 의 통신 리셋

Node 의 통신 리셋은 Node 의 Object Dictionary (OD) 중 통신에 관한 OD 를 리셋하는 것을 의미합니다. 이 메시지는 상태 변경하 NMT 프로토콜 CANopen 메시지와는 다르게 LSS Configuration 모드에서도 사용할 수 있습니다.

ID 가 01인 Node 의 통신 설정을 리셋하도록 하는 CANopen 메시지는 NMT 프로토콜에 의해 다음과 같이 정해집니다.

COB-ID rtr len NMT Function Target Node
0x000 0 2 0x82 0x01

Node 의 통신 리셋 CANopen 메시지 형식

이 CANopen 메시지를 CANbus 메시지 형식으로 변환하면 다음과 같습니다.

Receiver ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
000 82 01 XX XX XX XX XX XX

Node 의 통신 리셋 (CANbus)

Binary interpreter 를 이용한 모터 제어

이제부터 본격적으로 SDO, PDO 를 사용하는 CANopen 프로토콜에 대하여 알아보도록 합니다. CANopen 프로토콜은 기본적으로 CiA 에서 정리한 DSP-301 프로토콜을 말합니다. 모든 CANopen 프로토콜 지원 장치(Node) 가 이 프로토콜을 따릅니다.

DSP-301에 따르면, CANopen 프로토콜은 통신 (EtherCAT, CANbus) 위에 구현된 통신 메시지의 형식에 대한 규약입니다. 예를 들면, 신문 기사의 형식이 CANopen 프로토콜이고, 신문 기사의 언어 (language) 가 통신(EtherCAT, CANbus) 인 것입니다.

CANopen 프로토콜의 구조는 다음과 같습니다. 제어 PC 와 Node 사이의 통신은 PDO (Process Data Object) 가 매개합니다. 제어 PC 가 RxPDO (Receiver PDO) 에게 수치로만 구성된 CANopen 메시지를 송신하면, RxPDO 가 이 메시지를 해석해서 Node 에게 명령을 전달하고, Node 가 수치를 토대로 제어를 실행합니다. 제어가 실행된 뒤, Node 는 피드백 수치를 TxPDO (Transmitter PDO) 에 전달하고, TxPDO 는 수치를 모아 CANopen 메시지로 만들어 제어 PC 에 송신합니다.

이 때, RxPDO 는 제어 PC 가 전송해준 수치가 어떤 제어 값(ex. Target Torque) 을 의미하는 것인지 미리 알고 있어야 하고, TxPDO 는 제어 PC 에 어떤 상태값 (ex. Target Torque 또는 Actual Torque) 을 전송할 지 미리 알고 있어야 합니다. 즉, RxPDO 가 받을 수치 값이 무엇인지, TxPDO 가 전송 할 수치 값이 무엇인지 미리 알려주어야 한다는 것인데, 이 역할을 수행하는 것이 SDO(Service Data Object) 입니다.

이 표현은 다음과 같이 구체화 할 수 있습니다. 제어 PC 가 RxPDO 에 수치를 전송해주기 전에 SDO 에게 ‘수치를 수신 받게 될 RxPDO 는 어떤 RxPDO 인지’, ‘RxPDO 에 어떤 수치를 던져줄 것인지’ 알려주어야 한다는 것입니다. 이 과정을 RxPDO 매핑 이라고 합니다.

또한, 제어 PC 가 TxPDO 로부터 수치를 전송 받기 전에 SDO 에게 ‘수치를 전송할 TxPDO 는 어떤 TxPDO 인지’, ‘TxPDO 가 어떤 수치를 던져주어야 하는지’ 알려주어야 한다는 것입니다. 이 과정을 TxPDO 매핑 이라고 합니다.

매핑에는 데이터와 PDO 를 지칭하는 표현이 필요합니다. 여기서 CANopen 프로토콜은 이 표현을 IndexSub index 로 나누어 정리합니다. 예를 들면, Target Torque ValueTarget Torque 라는 IndexValue 라는 Sub index 로, Index 6071Sub index 00 으로 표현됩니다. 이 IndexSub index 를 정리한 것을 Object Dictionary (OD) 라고 합니다.

하지만, DSP-301은 보편적인 CANopen 프로토콜 지원 장치를 제어하는 메시지 형식만을 설명합니다. 실제 CANopen 장치 (Node) 는 센서부터 모터 드라이버에 이르기까지 다양하며, 각자의 기능이 다르기 때문에 DSP-301 프로토콜만으로 다른 기능에 대한 제어 명령을 만들어 주기에는 한계가 있습니다. 그러므로 Node 의 기능에 따라 그 기능을 제어하기 위한 추가적인 OD 목록인 DSP-401~410 프로토콜까지 확장된 개념을 적용할 필요가 있습니다.

본 튜토리얼에서 사용하는 Elmo 모터 드라이버는 CANopen 프로토콜의 구분 중 Motion Control 부분에 속하기 때문에 DSP-301 프로토콜과 DSP-301을 기반으로 하는 DSP-402 (Motion control) 프로토콜을 사용합니다.

따라서 이를 이용하여, Binary interpreter 를 사용한 모터 제어를 해볼 것입니다. 보통 SDO 를 통해 PDO 를 설정하고 제어를 시작해야 하지만, Elmo 모터 드라이버는 RxPDO2, TxPDO2 에 Binary interpreter 를 지원합니다. 이것은 CANopen DSP-301 프로토콜 상위에 새로운 제어 문자가 정의되어 있음을 의미입니다. 이 경우 CANopen 프로토콜를 사용하기는 하지만, RxPDO 에 데이터를 모두 16진수 ASCII 코드로 변환한 제어문자로 받으며, TxPDO 로부터 나오는 응답 역시 16진수 ASCII 코드로 출력하도록 합니다. 또한, SDO 설정(PDO 매핑) 을 해줄 필요는 없습니다. 제어하고자 하는 데이터와 수치에 해당하는 문자열을 ASCII 코드로 변환하여 CANbus 통신으로 전송해주는 것만으로 제어가 가능합니다.

여기서 말하는 새로운 제어문자는 Elmo Motion Control, Inc.의 SimplIQ Command Reference Manual Ver.3.0 에 자세히 설명되어 있으므로 해당 문서를 참고해주시길 바랍니다.

Composer 를 통한 제어 방법

Binary interpreter PDO 를 사용하는 일반적인 방법은 SimplIQ Command Reference Manual Ver.3.0 을 통해 사용할 제어문자를 선택하고 이를 ASCII 코드 16진수로 바꿔 canAnalyser3 Mini 로 RxPDO2 에 전송하는 것입니다. 이를 위해 Elmo Motion Control, Inc. 에서는 사용자들이 모터 드라이버의 작동을 직관적으로 처리하고 확인 할 수 있도록 Binary interpreter CANopen 프로토콜을 기반으로 하는 GUI 인 Composer 라는 프로그램을 제공합니다. 그러므로 먼저 Composer 를 활용하는 방법에 대해 알아보도록 합니다.

STEP CANbus 통신 설정

Composer 를 사용하기 전, STEP 의 CANbus 통신을 설정합니다. 자세한 내용은 본 튜토리얼의 STEP CANbus 통신 설정을 참고하십시오.

VCI Driver 설치

STEP CANbus 통신 설정 후, USB to CAN 컨버터를 인식하고 사용할 수 있도록 VCI Driver 를 설치합니다. 자세한 내용은 본 튜토리얼의 USB to CAN 컨버터 드라이버 설치를 참고하십시오.

VCI Driver 를 설치한 후에는 반드시 canAnalyser3 Mini 를 이용한 초기화 진행을 통해 초기화를 하고 다음 작업을 실시하십시오.

Composer 설치

Composer 사용을 위해 먼저 Composer 를 설치합니다. Composer 의 설치파일은 Elmo Motion Control, Inc. 홈페이지 ProductsApplication Studio 항목에서 제공합니다.

모터 튜닝


Composer 실행 화면

Composer 를 관리자 모드로 실행하여 Create a New Application 을 클릭하면 CANbus 통신 연결 설정 화면이 나옵니다. 본 튜토리얼에서는 Composer 가 설치된 PC 에서 USB to CAN 컨버터로 모터 드라이버와 통신을 하므로 설정에서 모터 드라이버의 Node-ID 및 비트레이트를 입력해주어야 합니다.


통신 속성 설정

이 정보의 입력을 위해 Application Name and Communication type 창 우측 하단의 Properties 를 클릭합니다. CAN Properties 창이 나타나면 CAN 탭에서 모터 드라이버의 Node-ID 와 비트레이트를 설정합니다.


Board 탭 컨버터 정보 입력

그 다음, Board 탭으로 이동하여 USB to CAN 컨버터의 정보를 입력합니다. 그리고 우측 하단의 Connect 버튼을 누르면, Composer 가 모터 드라이버와의 CANbus 네트워크를 사용할 수 있게 됩니다. 다만, canAnalyser3 Mini 가 Start 상태이거나 CANbus 네트워크 통신 회로가 연결되어 있지 않으면 에러 창이 뜨게 됩니다. 이 경우, CANbus 네트워크의 회로 연결 상태 및 설정을 전체적으로 다시 확인해주어야 합니다.


모터 정보 입력

정상적으로 연결이 되면, 모터의 메뉴얼을 확인하여 모터의 종류 및 Continuous Stall Current, Maximum Mechanical Speed 를 입력하고 우측 하단의 다음 버튼을 눌러줍니다.


홀 센서 정보 입력

다음 버튼을 누르면 센서의 세부 정보를 입력하는 창이 나옵니다. 본 튜토리얼에서는 홀 센서를 연결하므로 홀 센서를 선택하고, 홀 센서의 Pair of Poles 정보를 입력하고 우측 하단의 다음 버튼을 눌러줍니다.


모터 세부 사항 입력

그 다음, 모터 드라이버에 연결한 모터의 세부 사항을 입력하는 창이 나옵니다. 모터 드라이버는 이곳에 입력된 정보를 바탕으로 모터를 제어하므로, 모터의 메뉴얼을 참고해서 이 칸을 채워줍니다. 본 튜토리얼에서는 Emoteq, Inc Direct Drive Housed and Frameless Brushless DC Motor Engineering Guide 를 참고해서 값을 입력하고 다음 버튼을 누릅니다.


모터 입력 신호의 Function Behavior 설정

이번에는 모터에 입력되는 신호를 정의하는 창이 나옵니다. 본 튜토리얼에서는 모터 드라이버에서 모터에 Phase Input 용으로 3개의 케이블을 연결하였으므로, Input 1부터 3까지의 Function 을 Begin (Motor Start) 으로 설정해주고, Level 을 High 로 설정합니다. Function을 클릭했을 때, 나오는 다양한 메뉴는 Elmo Motion Control 의 Composer Manual 2-10 page 에 설명되어 있습니다. 입력을 마치면 다음 버튼을 누릅니다.


모터 출력 신호의 Function Behavior 설정

모터로부터 출력되는 신호의 Function Behavior 를 설정하는 창이 나타나면 이 부분은 설정해주지 않고 넘어갑니다. 본 튜토리얼에서 모터로부터 모터 드라이버로 홀 센서 Output 케이블은 연결했지만, 그 외의 다른 Output 케이블은 연결하지 않기 때문입니다.


모터 튜닝 단계 설정

그 다음은 모터의 튜닝 절차에 대해 설정합니다. 본 튜토리얼에서는 토크 (전류) 제어부터 위치 제어, 속도 제어까지 모두 가능하도록, Step 1~4 까지 모두 체크하고 다음 버튼을 누릅니다. 이 때, Step 5는 Dual Loop 가 지원되는 모터 드라이버만 사용가능 하며, 본 튜토리얼에서 사용하는 모터 드라이버는 해당 기능은 지원하지 않기 때문에 사용할 수 없습니다.


모터 튜닝 진행

지금까지의 설정을 마치고 다음 버튼을 클릭하고 Run 을 클릭하면, 이전에 입력한 정보들을 바탕으로 Composer 가 자동으로 Binary interpreter 에 보내는 CANopen 메시지를 생성하여 CANbus 네트워크로 모터 드라이버에 전송해주게 됩니다. 이에 따라 모터 드라이버의 튜닝이 진행됩니다. 튜닝이 끝나고 성공적으로 진행되었다는 메시지가 있으면, 를 눌러 다음 과정을 진행합니다.


엔코더 설정 진행

그 다음 엔코더 설정을 시작합니다. 모터를 움직여 엔코더 상태를 체크 및 조정하는 단계입니다. 엔코더의 Pair of Poles 가 맞는지 확인한 뒤, Run 을 클릭하여 설정을 진행합니다. 자동으로 모터를 움직여 엔코더 상태를 체크 및 조정하는 작업이 시작됩니다. 이 때, 모터와 클램프 간의 체결 상태를 한 번 더 확인하시길 바랍니다.

작업 중, 모터가 움직인 방향을 Positive 로 설정할 것인가에 대한 확인 질문이 나옵니다. 모터가 움직였던 방향을 Positive 로 설정하고 싶다면 를, Negative 로 설정하고 싶다면 아니요를 선택합니다. 선택을 마치면 설정을 토대로 엔코더를 설정하는 작업이 이어서 진행됩니다. 성공적으로 완료되었다는 메시지를 확인하면 예를 클릭하여 다음 설정으로 넘어가도록 합니다.


Target Velocity, Position 모드 게인 설정

그럼 Target Velocity 모드와 Target Position 모드일 때 제어 게인을 설정하는 창이 연이어 나옵니다. 본 튜토리얼에서는 최종적으로 코드를 사용하여 Closed Loop Control 을 만들 것이므로, 본 설정을 굳이 해줄 필요는 없습니다. 이번 장에서는 모터의 작동이 정상적으로 이루어지는지 확인해주는 것인 만큼 본 설정은 선택 사항입니다.


설정된 데이터 확인

설정을 모두 마치면 우측 하단의 다음 버튼을 눌러서 지금까지 설정한 사항을 최종적으로 확인합니다. 그리고 마침 버튼을 클릭하여 설정을 적용합니다. Composer 가 설정을 완료하면 설정 데이터를 저장하는 창이 나타나며, 지금까지 했던 모터 튜닝 데이터를 저장 합니다.

저장을 완료하면 튜닝은 완료되고, Composer 로 모터 드라이버를 제어하여 모터를 움직이는 것이 가능하도록 도와주는 Composer Smart Terminal 이 나타납니다.

모터 위치 제어 (Composer GUI)

튜닝 완료 후, 먼저 모터 위치 제어를 해보도록 합니다. Composer 는 위치 제어에 대해 다음의 두 가지 방법을 제공합니다. 첫 번째는 Composer GUI 를 이용하는 방법이고, 두 번째는 Composer Command 창을 사용하여 진행하는 방법입니다. 두 방법 중 본 튜토리얼에서는 Composer GUI 를 사용하여 위치 제어를 하는 방법에 대해 알아보도록 하겠습니다. Composer Command 창을 사용하여 위치 제어를 진행하는 방법은 Elmo motion Control SimplIQ Command Reference Manual 을 참고해주시길 바랍니다. 다만, Composer Command 창을 사용한 토크 제어 방법은 토크 제어 부분에서 설명하고 있으니 참고바랍니다.


Target Position 모드 실행

Composer 의 좌측 상단 리본에서 모드가 Position 모드로 되어 있는지 확인합니다. 만약, Position 모드 표시가 드롭다운 목록에서 비활성 상태라면, 모터가 현재 모드로 작동 중인 상태인 것이므로 Composer 의 좌측 상단의 리본에서 Motor STOP 버튼을 클릭합니다. 그 다음 Test MotionDesired SpeedDesired Position 을 입력하고 Go 버튼을 클릭하여 위치 제어를 실행합니다. 그리고 모터가 Desired Position 에 도달했을 경우에도 계속 가동 상태에 있기때문에 Test MotionSTOP 또는 좌측 상단에 있는 STOP 버튼을 클릭하여야 합니다.


Motion monitor 실행 버튼

위치 제어 모드를 포함하여 토크 (전류) 제어 모드, 속도 모드로 모터를 제어하면, 동작하는 모터의 정보 및 상태가 엔코더로 피드백 됩니다. Composer 는 이 정보를 GUI 창으로 보여줍니다. 위치 제어가 제대로 동작하는지 확인하기 위해서 좌측 상단의 모니터 모양 Motion monitor 를 실행합니다.


Motion monitor 실행 화면

Motion monitor 를 실행하게 되면, 프로그램 창 하단에 GUI 가 나타나며, 이 창을 확인하면 모터의 위치, 토크 및 속도를 확인할 수 있습니다.


엔코더 피드백 값 설정

Motion monitor 에서 피드백 받을 수 있는 값은 최대 2개입니다. 이 2개의 값을 무엇으로 받을 지 위 그림과 같이 Motion monitor 의 Display 1 과 2에 각각 설정해주면 됩니다. 이를 설정하고 Smart Terminal 을 통해 모터를 작동시키면 원하는 피드백 값을 받을 수 있습니다.

모터 토크 제어 (Composer GUI)

이번에는 Target Torque (Current) 제어를 진행하도록 합니다. Composer 는 토크 제어에 대해서도 Composer GUI 와 command 창을 이용한 두 가지 방법을 제공합니다. 먼저 Composer GUI 를 사용하여 토크 제어를 하는 방법에 대해 알아보도록 합니다.


Target Torque (Current) 모드로 변경

Composer 의 좌측 상단 리본에서 모드가 Current 모드로 되어 있는지 확인합니다. 만약 이 모드 표시가 비활성 상태이면, 모터가 현재 작동 중인 상태인 것이므로, Composer 의 좌측 상단의 리본에서 Motor STOP 버튼을 클릭합니다.


Target Torque 설정

이제 Composer 의 Torque (Current) Control 을 실행합니다. 토크 제어 방법은 위 그림처럼, Smart Terminal Test MotionTorque commandDesired Current 를 입력하고 Go 버튼을 클릭하는 것입니다. Go 버튼을 클릭하면 모터가 동작합니다.

이때, 모터는 Desired Current 에 도달하여도 계속 가동 상태에 있으므로 Test MotionSTOP 을 클릭하거나 좌측 상단의 STOP 버튼을 클릭해주어야 멈춥니다.


모터 동작 시 Terminal 모습

모터 토크 제어 (Composer Command)

앞서 언급했듯이 Composer 는 토크 제어에 대해 두 가지 방법을 제공합니다. 이번에는 두 번째 방법인 Composer Command 창을 사용하여 토크 제어를 진행해보도록 합니다. 해당하는 내용은 Elmo motion Control SimplIQ Command Reference Manual 에도 설명되어 있으므로 참고해주시길 바랍니다.

먼저 Composer 의 좌측 상단의 모드가 Current 모드로 되어 있는지 확인합니다. 만약, 다른 모드로 되어있다면 드롭다운 메뉴에서 Current 모드를 클릭합니다. 또한, 이 모드 표시가 비활성 상태이면, 모터가 현재 모드로 작동 중인 상태인 것이므로, Composer 의 좌측 상단의 STOP 버튼을 클릭하여 모드를 활성화합니다.


모드 상태 변경

그 다음으로 모드를 1 상태로 변경합니다. 위 그림과 같이 Command 창에 MO=1을 입력하고, Send 버튼을 눌러 전송합니다.


Target current 변경

모드를 1로 변경하고 Target current 를 전송합니다. 모터를 1A 로 동작시키고 싶다면, 위 그림처럼 Command 창에 TC=1 을 입력해주면 됩니다. 모터를 다시 멈추고 싶다면 TC=0 의 명령어를 전송하여 모터에 입력되는 신호를 0A 로 변경합니다. 이후, 다른 모드로 변경할 경우 좌측 상단의 STOP 버튼을 클릭합니다.

연결 해제 및 재연결

Composer 와 모터 드라이버 사이의 CANbus 네트워크 연결을 끊거나 다시 연결하는 방법에 대하여 알아봅니다. CANbus 네트워크 연결을 종료하고 싶다면, Composer 의 우측 상단 메뉴에서 아래와 같은 버튼을 클릭합니다. 단, 모터와 모터 드라이버가 정지 상태인 것을 확인한 경우에만 연결 해제를 진행합니다.


우측 상단 연결 해제 버튼

다시 모터 드라이버와 Composer 사이에 CANbus 네트워크를 연결하고 싶다면, Composer 의 좌측 상단 메뉴 중 File 을 클릭하여 New Application 또는 Open Application 을 클릭합니다. New Application 은 설정이 다른 모터 및 모터 드라이버로 새롭게 연결할 때 사용하고, Open Application 은 이미 저장된 모터 튜닝 데이터가 있는 모터 및 모터 드라이버를 연결할 때 사용합니다. 또한, New Application 을 실행하고 연결 해제 버튼 왼쪽의 전화기 버튼을 클릭하면, 앞서 다룬 Composer 의 처음 실행화면이 나타납니다.

Binary interpreter 에 직접 CANbus 메시지 전송

Composer 를 사용하여 직관적으로 Binary interpreter 를 사용해보았습니다. 그러면 이제 Binary interpreter 에 직접 CANbus 메시지를 보내서 모터와 모터 드라이버를 제어하는 방법에 대해 알아보도록 합니다. Composer 를 사용할 때에는 이 메시지들을 Composer 가 자동적으로 생성해주었지만, Binary interpreter 에 직접 보내는 CANbus 메시지의 형식은 쉽게 말해 Composer 에 입력하는 Command를 ASCII 코드를 hex 값으로 변환한 것입니다.

자세한 설명을 위해 Binary interpreter 에 직접 CANbus 메시지를 보내서 토크 제어를 진행해보도록 하겠습니다. 우선 Composer 로 모터 튜닝을 진행해준 뒤, 모드를 Current 모드로 변경합니다. 그리고 Composer 와 모터 드라이버 사이의 CANbus 네트워크 연결을 해제합니다.

그 다음, canAnalyser3 Mini 를 실행하여 canAnalyser3 Mini 와 모터 드라이버 사이의 CANbus 네트워크를 연결합니다. Composer 로 1A 전류 제어를 하기 위해서 MO=1TC=1을 각각 입력 및 전송해준 것 처럼, 이 부분을 Composer 를 사용하지 않고 Binary interpreter 에 직접 CANbus 메시지를 보내어 토크 제어를 진행합니다.

먼저 canAnalyser3 Mini 와 모터 드라이버 사이의 CANbus 네트워크를 연결해준 상태에서 MO=1에 해당하는 메시지를 보내도록 하겠습니다. ASCII 코드표를 참고해서 MO=1을 CANbus 메시지 양식으로 바꾸면 다음과 같으며 이 CANbus 메시지를 canAnalyser3 Mini에 입력 및 전송해주도록 합니다 ('=' 기호는 hex 코드 00 00으로 대응되며, 이때 사용하는 모터 드라이버의 Node-ID 는 1입니다).

Receiver ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
301 4D 4F 00 00 01 XX XX XX

모드 1 설정 (CANbus)

이제, TC=1 에 해당하는 메시지를 보내도록 합니다. ASCII 코드표를 참고해서 TC=1을 CANbus 메시지 양식으로 바꾸면 다음과 같으며 이 CANbus 메시지를 canAnalyser3 Mini에 입력 및 전송해주도록 합니다.

Receiver ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
301 54 43 00 00 01 XX XX XX

모터 전류 (1A) 설정 (CANbus)

위 두 메시지를 보내면 모터는 1A 로 동작하게 됩니다. 그리고 모터를 멈추고 싶다면 TC=0에 해당하는 메시지를 보내줍니다. ASCII 코드표를 참고해서 TC=0을 CANbus메시지 양식으로 바꾸면 다음과 같습니다. 이 CANbus 메시지를 canAnalyser3 Mini 에 동일한 방식으로 입력 및 전송합니다.

Receiver ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
301 54 43 00 00 00 XX XX XX

모터 정지 (0A) 설정 (CANbus)

CANopen DSP-301, DSP-402 프로토콜 기반 모터 제어

이번 장에서는 CANopen DSP-301 과 확장된 OD 를 제공하는 DSP-402 를 참고하여, RxPDO 에 수치로만 구성된 CANopen 메시지를 송신하는 일반적인 CANopen 통신방식을 사용하여 모터 및 모터 드라이버의 제어하는 법에 대해 다룹니다. 이 방법은 SDO 에 RxPDO 와 TxPDO 매핑을 하고, 제어에 필요한 추가 정보 (ex. Motor Max Current) 에 해당하는 OD 를 찾아 정보를 입력해주는 방식으로 진행됩니다. 이 때, RxPDO 제어 데이터에 대한 응답 메시지는 TxPDO 로부터 받는 수치입니다.

STEP CANbus 통신 설정

우선 STEP 의 CANbus 통신을 설정합니다. 자세한 내용은 본 튜토리얼의 STEP CANbus 통신 설정을 참고하십시오.

VCI Driver 설치

STEP CANbus 통신 설정 후 마찬가지로 VCI Driver 를 설치합니다. 자세한 내용은 본 튜토리얼의 USB to CAN 컨버터 드라이버 설치를 참고하십시오.

VCI Driver 를 설치한 후에는 반드시 canAnalyser3 Mini 를 이용한 초기화 진행을 통해 초기화를 하고 다음 작업을 실시하십시오.

SDO 설정

우선 SDO 설정에 앞서 모터 드라이버를 LSS operation 모드의 MNT operational 상태로 만들어주어야 합니다. 이에 관한 내용은 본 튜토리얼 NMT 프로토콜에 설명되어 있으므로, 여기에서는 LSS operation 모드의 MNT operational 상태로 변경하는 메시지에 대해서만 설명합니다. 해당하는 메시지는 다음과 같습니다.

Receiver ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
000 01 01 XX XX XX XX XX XX

Operational 상태로의 변경 (CANbus)

모터 드라이버를 LSS operation 모드의 MNT operational 상태로 만들어주었다면, 이제 SDO 설정을 시작합니다. 우선 SDO 로 보내는 CANopen 메시지의 형식에 관해 알아보겠습니다. 특정 OD 에 저장된 값을 확인하고 싶을 때는 다음과 같은 형식의 CANopen 메시지를 SDO 에 전송합니다 (이때, SDO 의 CAN Header 는 CAN-ID 를 의미하며, CAN Header = 0x600 + Node-ID 의 식을 따릅니다).

CAN Header rtr len Byte 0 B1 B2 B3 B4 B5 B6 B7
0x600 + Node-ID 0 8 Command Index Sub Index 0

SDO 를 통한 OD 저장 값 확인 (CANopen)

이때, Byte 0 의 자리에 들어가는 16진수 Command Code 가 해당 OD 에 SDO 를 통해 작업할 것이 (읽기/쓰기) 무엇인지 구분해주는 역할을 합니다. OD 읽기를 진행하고 싶다면 아래 표에 해당하는 16진수 Command Code 를 Byte 0 Command Code 에 넣어주어야 합니다.

Command Code Meaning
0x40 Read Object Dictionary

16진수 Command Code (OD 읽기)

이 16진수 Command Code 는 본래 유의미한 정보를 담고 있는 2진수 값으로, 이 값을 16진수로 변환하여 Byte 0 자리에 입력 및 전송해주는 것입니다. OD 읽기에 대한 Command Code 의 2진수 값은 다음과 같은 의미를 가집니다.

Command Code Bits Value Meaning
7-5 010 CCS-Client Command Specifier
4-0 00000 Not used

2진수 Command Code (OD 읽기)

이를 모두 종합한 예시를 보면 아래와 같습니다. Node-ID 가 1인 모터 드라이버의 RxPDO1 (Index: 1600, Sub index: 0) 의 매핑 상태를 확인하고 싶다면, 이에 해당하는 CANopen 메시지는 아래와 같이 구성됩니다.

CAN Header rtr len Byte 0 B1 B2 B3 B4 B5 B6 B7
0x601 0 8 0x40 1600h 0 0

SDO 를 통한 RxPDO1 매핑 상태 확인 (CANopen)

위 CANopen 메시지를 본 튜토리얼에서는 CANbus 통신을 통해 전송해야 하므로, 이 메시지를 CANbus 메시지 형식으로 변환해주어야 합니다. 이 때, CANbus 통신 방식은 데이터를 수신할 때, 낮은 번호의 Byte 를 먼저 수신합니다. 그리고 Index 와 같이 2개 이상의 Byte 가 이어진 데이터를 수신할 때는, 먼저 받은 데이터를 전체 데이터 중 가장 마지막 숫자로 인식합니다. 이 점에 주의해서 메시지 형식 변환을 완료하면 아래 표와 같은 CANbus 메시지가 됩니다.

Receiver ID Data Field
Command Index Sub index Reserved
D1 D2 D3 D4 D5 D6 D7 D8
601 40 00 16 00 XX XX XX XX

SDO 를 통한 RxPDO1 매핑 상태 확인 (CANbus)

이렇게 SDO 에 OD 값을 읽도록 하는 메시지를 보내면, SDO 는 이에 대해 다음의 CANbus 메시지 응답을 보냅니다 (응답 메시지의 Transmitter-ID 가 81이면 이는 작업을 처리하는데 오류가 일어남을 알려주는 응답이며, 이 오류에 대한 자세한 설명은 Elmo Motion Control DSP-301, DSP-402 Manual 을 참고하십시오).

Transmitter ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
580 + Node-ID Command Index Sub index Data

OD Command 에 대한 응답 (CANbus)

응답을 자세히 살펴보면, 먼저 D1에 있는 16진수 Command Code 는 OD 의 값이 몇 byte 인지 알려주는 역할을 합니다. 각 숫자가 의미하는 바는 아래 표에 설명되어 있습니다.

Command Code Meaning
0x43 Read Dictionary Object reply, expedited 4 bytes sent
0x47 Read Dictionary Object reply, expedited 3 bytes sent
0x4B Read Dictionary Object reply, expedited 2 bytes sent
0x4F Read Dictionary Object reply, expedited 1 bytes sent

OD 응답의 16진수 Command Code 의미

위 16진수 Command Code 역시 2진수의 유의미한 수를 16진수로 변환한 것입니다. 2진수 Command Code 의 형태는 다음과 같습니다. 예를 들어, 1byte 의 데이터를 받으면, Command Code 는 01001111가 됩니다. 이처럼 3-2Bit 자리를 각각 대입해서 16진수로 변환하면 아래 표와 같은 결과를 확인할 수 있습니다.

Command Code Bits Value Meaning
7-5 010 SCS-Server Command Specifier
4 0 (Not used) Segment toggle bit
3-2 (n) Data size
n=3(11b) 1 data bytes sent
n=2(10b) 2 data bytes sent
n=1(01b) 3 data bytes sent
n=0(00b) 4 data bytes sent
1 1 Expedited transfer
0 1 Data set size is indicated

OD 응답의 2진수 Command Code 의미

다시 OD 읽기 명령에 대한 SDO 의 응답을 확인해봅니다. 여기서 D2-3 에 있는 Index 는 해당하는 데이터가 저장된 OD 를 의미하고, D4 의 Sub index 는 해당하는 데이터가 저장된 OD 의 내부 위치를 의미합니다. 그리고, D5-D8 까지가 데이터가 됩니다. 그런데 이 데이터를 읽을 때는 Index 처럼 숫자가 CANbus 통신의 데이터 수신방식에 맞게 나열되어 있음에 유의해주어야 합니다. 예를 들어, 데이터가 D5-D8까 지 '00 10 40 60'의 순이라면, 이것은 '6040 10 00'이라는 데이터를 의미한다는 것입니다.

이제 특정 OD 에 저장된 값을 쓰도록 하는 메시지의 형식에 대해 알아보도록 합니다. 이 경우, 다음과 같은 형식의 CANopen 메시지를 SDO 에 전송합니다.

CAN Header rtr len Byte 0 B1 B2 B3 B4 B5 B6 B7
0x600 + Node-ID 0 8 Command Index Sub index Data

SDO 를 통한 OD 쓰기 (CANopen)

이때, Byte 0 의 자리에 들어가는 16진수 Command Code 가 해당 OD 에 SDO 로 진행할 것이 무엇인지 구분해주는 역할을 합니다. OD 쓰기를 진행하고 싶다면 아래 표에 해당하는 16진수 Command Code 를 CANopen 메시지 패킷의 Byte 0 Command Code 자리에 넣어주어야 합니다.

Command Code Meaning
0x23 Write Dictionary Object, expedited, 4 bytes sent
0x27 Write Dictionary Object, expedited, 3 bytes sent
0x2B Write Dictionary Object, expedited, 2 bytes sent
0x2F Write Dictionary Object, expedited, 1 bytes sent

OD 쓰기에 대한 16진수 Command Code

위 16진수 Command Code 역시, 본래 Command 에 관해 유의미한 정보를 담고 있는 2진수 값으로, 이 2진수 값을 16진수로 변환하여 Byte 0 자리에 입력 및 전송해주는 것입니다. OD 쓰기를 의미하는 Command Code 의 2진수 값은 다음과 같은 의미를 가집니다.

Command Code Bits Value Meaning
7-5 011 SCS–Server Command Specifier
4 0 (Not used) Segment toggle bit
3-2 (n) Data size
n=3 (11b) 1 data bytes sent
n=2 (10b) 2 data bytes sent
n=1 (01b) 3 data bytes sent
n=0 (00b) 4 data bytes sent
1 1 Expedited transfer
0 1 Data set size is indicated

OD 쓰기에 대한 2진수 Command Code

이것을 종합한 예시를 보면 다음과 같습니다. Node-ID 가 1인 모터 드라이버의 RxPDO1 에 Controlword 를 전송하는 것으로 모터를 제어하고 싶다면, RxPDO1(Index: 1600, Sub index: 1) 에 Controlword 를 매핑해야 합니다. 이 경우 SDO 로 보내는 RxPDO1 매핑 CANopen 메시지는 아래 표와 같이 구성됩니다.

CAN Header rtr len Byte 0 B1 B2 B3 B4 B5 B6 B7
0x601 0 8 0x23 1600h 1 6040 00 10h

SDO 를 통해 RxPDO1 에 Controlword 쓰기 (CANopen)

위 CANopen 메시지를 본 튜토리얼에서는 CANbus 통신을 통해 전송할 것이므로, 이 메시지를 마찬가지로 CANbus 메시지 형식으로 변환해주어야 합니다. 변환을 완료하면 다음과 같은 CANbus 메시지가 됩니다.

Receiver ID Data Field
Command Index Sub Index Data
D1 D2 D3 D4 D5 D6 D7 D8
601 23 00 16 01 10 00 40 60

SDO 를 통해 RxPDO1 에 Controlword 쓰기 (CANbus)

이렇게 값를 쓰도록 하는 메시지를 보내면, SDO 는 이에 대해 다음의 CANbus 메시지 응답을 보냅니다 (이 때에도 마찬가지로 응답 메시지의 Transmitter-ID 가 81이라면 이는 오류가 발생한 것이므로 Elmo Motion Control DSP-301, DSP-402 Manual 을 참고하십시오).

Transmitter ID Data Field
D1 D2 D3 D4 D5 D6 D7 D8
580 + Node-ID Command Index Sub index Data

OD 쓰기에 대한 응답 (CANbus)

응답에서 D1 에 있는 16진수 Command Code 는 OD 의 값이 몇 byte 인지 알려주는 역할을 합니다.

Command Code Meaning
0x60 Writing Dictionary Object is done Successfully

OD 쓰기 응답에 대한 16진수 Command Code 의미

이 16진수 Command Code 역시 2진수의 유의미한 수를 16진수로 변환된 것입니다. Command Code 의 2진수 형태는 01100000이며, 이를 16진수로 변환하면 위의 표와 같은 결과가 나온다는 것을 확인할 수 있습니다.

Command Code Bits Value Meaning
7-5 011 SCS–Server Command Specifier
4 0 (Not used) Segment toggle bit

OD 쓰기 응답에 대한 2진수 Command Code 의 의미

다시 OD 쓰기에 대한 SDO 의 응답을 확인해보도록 합니다. 여기서 D2-3 에 있는 Index 는 명령에 따라 해당하는 데이터가 저장된 OD 를 의미하고, D4 의 Sub index 는 해당하는 데이터가 저장된 OD 의 내부 위치를 의미합니다. 그런데, Index 를 읽을 때면 숫자가 CANbus 통신의 데이터 수신방식에 맞게 나열되어 있음에 유의해야 합니다. 예를 들어, Index 가 D2-D3 까지 '00 16'의 순이라면, 이것은 '1600'이라는 데이터를 의미합니다.

PDO 매핑

이제 본격적으로 모터 제어를 위한 SDO 설정 작업을 시작하도록 하겠습니다. 본 튜토리얼에서 다룰 제어 방법은 타겟 토크 (전류) 제어입니다. 이를 위해서는 우선 SDO 로 RxPDO, TxPDO 매핑을 해주어야 합니다. 그 뒤, SDO 로 모터 토크 제어에 필요한 정보에 해당하는 OD 를 확인해서 모터 스펙을 입력해주어야 합니다. 그 다음 마지막으로 RxPDO 매핑 데이터를 참고해서 제어를 위한 수치 데이터들을 전송합니다. 수치 데이터 전송이 성공적으로 완료되면 모터 드라이버의 타겟 토크 제어가 시작되어 모터가 동작하게 됩니다.

우선 RxPDO, TxPDO 매핑을 진행합니다. Elmo Solo Whistle 모터 드라이버는 다음 표와 같이 RxPDO1에 기본적으로 Controlword 가, TxPDO1에 Statusword 가 매핑되어 있어 타겟 토크 제어를 위해 추가적으로 매핑해야할 필요는 없습니다.

Index Sub index Name Default Value
1600h 0 Number of mapped entries 1
1 Controlword 6040 00 10h
2 Nothing mapped 0

모터 드라이버의 RxPDO1 기본 값

RxPDO1의 매핑 상태를 보여주는 위 표를 좀 더 자세히 살펴보도록 합시다. RxPDO1의 매핑 상태는 OD 에서 Index 1600h 에 해당합니다. 또, Sub index0 은 Sub index 몇 번까지 RxPDO1으로 받을 것인지 나타내는 매핑 항목 수를 의미합니다. 표를 보면, Sub index1까지 RxPDO1에 받을 것임을 알 수 있습니다. 즉, 모터 제어 시에 RxPDO 에 Commandword 2Byte 로 된 CANbus 메시지를 보내면 된다는 뜻입니다.

RxPDO 매핑 상태의 Sub index1은 기본적으로 Controlword 가 매핑되어 있습니다. Defalt Value 를 보아도 Controlword 2Byte 가 매핑되어 있음을 확인할 수 있는데, Defalt Value 의 6040 은 Controlword 를 가리키는 OD 이고, 00 10 은 2byte 를 의미하기 때문입니다. 이것은 모터 제어 시에 RxPDO 에 Commandword 를 포함한 CANbus 메시지를 보내도록 하며, 그 Commandword 는 2Byte hex code 로 되어있다는 것을 의미합니다.

Index Sub index Name Default Value
1A00h 0 Number of mapped entries 1
1 Statusword 6041 00 10h
2 Nothing mapped 0

모터 드라이버의 TxPDO1 기본 값

TxPDO1의 매핑 상태는 OD 에서 Index 1A00h 에 해당합니다. Sub index0은 마찬가지로 Sub index 몇 번까지 TxPDO1를 통해 값을 피드백 받을 것인지 나타내는 매핑 항목 수를 의미합니다. 표를 보면, Sub index1까지 TxPDO1에 받을 것임을 알 수 있습니다. Sub index1은 기본적으로 Statusword 가 매핑되어 있습니다. Defalt Value 를 보아도 Statusword 2Byte 가 매핑되어 있음을 확인할 수 있는데, Defalt Value 의 6041은 Statusword 를 가리키는 OD 이고, 00 10 은 2byte 를 의미하기 때문입니다. TxPDO 로부터 RxPDO 로 보낸 메시지에 대해 응답을 받을 때, Statusword 2Byte hex code 를 받는 것을 의미합니다. 이때, TxPDO 로부터 오는 메시지는 굳이 RXPDO 에 메시지를 보내주지 않더라도 모터 구동 중에는 주기적으로 수신됩니다. 따라서 모터 구동 중에는 모터의 실시간 상태를 주기적으로 수신받게 됩니다.

다만, PDO 에 대한 정보를 추가로 매핑하고 싶다면, 총 메시지의 길이가 8byte 인 것에 유의해서 추가할 수 있습니다. 이때, RxPDO 에 매핑 가능한 OD 는 쓰기가 지원되는 OD 여야 하고, TxPDO 에 매핑 가능한 OD 는 읽기가 지원되는 OD 여야 합니다.

예를 들어, 구동 중인 모터의 실제 위치 정보를 Statusword 와 함께 받고 싶다면, 실제 위치를 TxPDO 의 Sub index2에 매핑하고, Sub index0의 값을 2로 변경해주어야 합니다 (실제 위치는 읽기 전용 데이터이기 때문에 TxPDO 로 받아볼 수 있습니다). 실제 위치를 TxPDO 의 Sub index2에 매핑하는 CANbus 메시지는 다음과 같습니다. 여기서 데이터가 의미하는 바는 4byte 실제 위치입니다. 6064h 가 실제 위치의 Index 이고, 00 20h 가 4byte 를 의미하기 때문입니다.

Receiver ID Data Field
Command Index Sub index Data
D1 D2 D3 D4 D5 D6 D7 D8
601 23 00 1A 02 20 00 64 60

SDO 를 통해 TxPDO1 Sub index2에 실제 위치 쓰기 (CANbus)

Sub index0의 값을 2로 변경해주는 방법은 다음 2개의 CANbus 메시지를 차례로 전송하는 것입니다. 이렇게 진행하는 것은 매핑 항목 수는 1에서 2로 바로 수정하는 것이 불가능하고, 항상 0으로 초기화한 다음 바꾸고 싶은 숫자로 수정해야 하기 때문입니다.

Receiver ID Data Field
Command Index Sub index Data
D1 D2 D3 D4 D5 D6 D7 D8
601 23 00 1A 00 00 00 00 00

SDO 를 통해 TxPDO1 매핑 항목 수 0으로 변경 (CANbus)

Receiver ID Data Field
Command Index Sub Index Data
D1 D2 D3 D4 D5 D6 D7 D8
601 23 00 1A 00 02 00 00 00

SDO 를 통해 TxPDO1 매핑 항목 수 2로 변경(CANbus)

위 예시의 메시지 전송을 완료하면, 구동 중인 모터의 실제 위치를 Statusword 와 함께 실시간으로 받는 것이 가능합니다. 다만, 해당 위치 정보는 CANbus 데이터 양식에 따라 16진수이므로 10진수로 변경해주어야 한다는 것과, 수신 받은 데이터가 '12 34 56'이면, 읽는 방법은 '563412h' 라는 것에 주의하도록 합니다.

위의 예시는 선택사항입니다. 본 튜토리얼에서는 기본 설정을 이용하여 토크 제어를 진행하도록 합니다. 하지만 만약 RxPDO 에 Controlword 가, TxPDO 에 Statusword 가 기본적으로 매핑되어 있지 않다면, SDO 로 PDO 매핑을 진행해야 합니다. 그 방법은 다음과 같습니다.

먼저 RxPDO1의 Sub index1에 Controlword 를 매핑합니다. 이 작업을 위해 SDO 에 보내야하는 메시지는 다음과 같습니다.

Receiver ID Data Field
Command Index Sub Index Data
D1 D2 D3 D4 D5 D6 D7 D8
601 23 00 16 01 10 00 40 60

SDO 를 통한 RxPDO1 Sub index1 의 Controlword 매핑 (CANbus)

다음으로, RxPDO 의 매핑 항목 수를 1로 변경합니다. 이 작업을 위해 SDO 에 보내주어야 하는 메시지는 아래 표와 같습니다.

Receiver ID Data Field
Command Index Sub Index Data
D1 D2 D3 D4 D5 D6 D7 D8
601 23 00 16 00 01 00 00 00

SDO 를 통해 RxPDO1 매핑 항목 수 1로 변경 (CANbus)

이번에는 TxPDO1의 Sub index1에 Statusword 를 매핑합니다. 이 작업을 위해 SDO 에 보내주어야 하는 메시지는 다음과 같습니다.

Receiver ID Data Field
Command Index Sub Index Data
D1 D2 D3 D4 D5 D6 D7 D8
601 23 00 1A 01 10 00 41 60

SDO 를 통한 TxPDO1 Sub index1의 Statusword 매핑 (CANbus)

다음으로, TxPDO의 매핑 항목 수를 1로 변경합니다. 이 작업을 위해 SDO 에 보내야하는 메시지는 아래 표와 같습니다.

Receiver ID Data Field
Command Index Sub Index Data
D1 D2 D3 D4 D5 D6 D7 D8
601 23 00 1A 00 01 00 00 00

SDO 를 통해 TxPDO1 매핑 항목 수 1로 변경 (CANbus)

이미 Controlword 가 RxPDO1의 Sub index1에 매핑되어 있고, RxPDO1의 매핑 항목 수가 1이라면 추가적인 RxPDO 매핑 필요없습니다. 또한, 이미 Statusword 가 TxPDO1의 Sub index1에 매핑되어 있고, TxPDO1의 매핑 항목 수가 1이라면 추가적인 TxPDO 매핑은 필요없습니다. Elmo Solo Whistle 모터 드라이버는 기본적으로 이 두 가지 사항을 충족하므로, 추가적으로 데이터를 받고 싶거나 제어를 위해 추가적으로 데이터를 전송하고 싶지 않다면 PDO 매핑은 진행할 필요가 없습니다.

모터 데이터 매핑

타겟 토크 제어를 하기 위해서 추가적으로 입력해야 할 정보는 토크 모드 (4) 와 타겟 토크 값입니다. 먼저 모터 드라이버를 토크 모드로 변경하기 위한 모터 드라이버 모드에 해당하는 OD 의 Index 는 6060h 이며, 값은 04h 입니다. 따라서 토크 모드로 변경은 아래의 CANbus 메시지와 같습니다.

Receiver ID Data Field
Command Index Sub index Data
D1 D2 D3 D4 D5 D6 D7 D8
601 2F 60 60 00 04 XX XX XX

SDO 를 통한 모터 드라이버 모드 변경 (CANbus)

위 설정이 정상적으로 완료되면 다음과 같은 응답을 받습니다.

Transmitter ID Data Field
Command Index Sub index Reserved
D1 D2 D3 D4 D5 D6 D7 D8
581 60 60 60 00 00 00 00 00

SDO 를 통한 모터 드라이버 모드 변경 응답 (CANbus)

그 다음, 타겟 토크 값을 설정합니다. 이에 해당하는 OD 의 Index 는 6071h 입니다. 여기에 입력해주어야 할 데이터는 Continuous stall Torque 를 '100.0'으로 두었을 때의 상대적인 토크 값입니다. 본 튜토리얼에서는 Continuous stall Torque 의 '10.0%' 를 타겟 토크로 설정하여 모터를 제어해보도록 하겠습니다. 이 때, 10.0%는 데이터 값 10진수 100, 16진수 0x64에 대응하고, 5.0%는 데이터 값 10진수 50, 16진수 0x32에 대응합니다. 따라서, Continuous stall Torque의 10.0%를 타겟 토크로 설정하도록 하는 CANbus 메시지는 다음과 같습니다.

Receiver ID Data Field
Command Index Sub index Data
D1 D2 D3 D4 D5 D6 D7 D8
601 2B 71 60 00 64 00 XX XX

SDO 를 통한 타겟 토크 10.0% 설정 (CANbus)

위 설정이 정상적으로 완료되면, 다음과 같은 응답을 받습니다.

Transmitter ID Data Field
Command Index Sub index Reserved
D1 D2 D3 D4 D5 D6 D7 D8
581 60 71 60 00 00 00 00 00

SDO 를 통한 타겟 토크 10.0% 설정에 대한 응답 (CANbus)

모터 구동

SDO 설정이 모두 완료되면 이제 RxPDO1에게 Controlword 를 전송하는 것으로 모터 구동을 시작합니다. Controlword 를 전송하기 위해 Controlword 에 대해 알아보도록 합니다. Controlword 는 유의미한 16Bit 2진수를 2Byte 16진수로 변환한 값입니다. 2진수 Controlword 는 아래 표와 같은 의미를 가지고 있는데, 모터 구동을 위해서는 Fault Reset, Shutdown, Switch ON, Enable Operation 에 해당하는 Controlword 를 차례로 전송해야 합니다.

Controlword Bits Meaning Optional/Mandatory
15-11 Manufacturer specific Optional
10-9 Reserved Optional
8 Halt Optional
7 Fault reset Mandatory
6-4 Operation mode specific Optional
3 Enable operation Mandatory
2 Quick stop Mandatory
1 Enable voltage Mandatory
0 Switch on Mandatory

2진수 Controlword 데이터 표현

Bit Operation Mode
Velocity Mode Profile Position Mode Profile Velocity Mode Profile Torque Mode Homing Mode Interpolation Position Mode
4 Rfg enable New set-point Reserved Reserved Homing operation start Enable ip mode
5 Rfg unlock Change set immediately Reserved Reserved Reserved Reserved
6 Rfg use ref Abs/rel Reserved Reserved Reserved Reserved
8 Halt Halt Halt Halt Halt Halt

Operation 모드의 상세 데이터 표현

Fault Reset, Shutdown, Switch ON, Enable Operation 에 해당하는 Controlword 는 다음과 같은 2진수 Contorlwod 배열을 가집니다.

Command Bits of the controlword Transitions
7 3 2 1 0
Fault Reset Enable Operation Quick stop Enable Voltage Switch On
Shutdown 0 X 1 1 0 2,6,8
Switch ON 0 0 1 1 1 3*
Switch ON 0 1 1 1 1 3**
Disable Voltage 0 X 0 1 X 7,9,10,12
Quick Stop 0 X 0 1 X 7,10,11
Disable Operation 0 0 1 1 1 5
Enable Operation 0 1 1 1 1 4,16
Fault Reset 0 X X X X 15

각 Controlword 에 해당하는 2진수 배열 (표에 나타나는 Bit 값 이외에는 0 으로 입력)

다만, 위 표에서 주의할 점은 * 표시 된 것은 SWITCH_ON 이 성공적으로 이루어지는 Controlword 이고, ** 표시 된 것은 SWITCH_ON 상태처럼 여겨지지만, 드라이버는 그 상태에 있지 않도록 처리하는 Controlword 라는 것입니다.

위 표를 확인하고, RxPDO 에 Fault Reset 메시지를 먼저 전송합니다. Fault Reset 에 해당하는 2진수는 000000000000000 이므로, 이것을 16진수 2Byte 로 나타내면 00 00 입니다. 따라서 Fault Reset 을 하도록 하는 CANbus 메시지는 다음과 같습니다.

Receiver ID Data Field
Controlword Reserved
D1 D2 D3 D4 D5 D6 D7 D8
201 00 00 XX XX XX XX XX XX

RxPD01 Fault Reset (CANbus)

다음으로, Shutdown 에 해당하는 메시지를 전송합니다. Shutdown 에 해당하는 2진수 Controlword 는 000000000000110 이므로, 이것을 16진수 2Byte 로 나타내면 00 06 입니다. 따라서 Shutdown CANbus 메시지는 다음과 같습니다.

Receiver ID Data Field
Controlword Reserved
D1 D2 D3 D4 D5 D6 D7 D8
201 06 00 XX XX XX XX XX XX

RxPDO1 Shutdown (CANbus)

다음은, Switch ON 에 해당하는 메시지를 전송합니다. Switch ON 에 해당하는 2진수 Controlword 는 000000000001111 이므로, 이것을 16진수 2Byte 로 나타내면 00 0F 입니다. 따라서 Switch ON 을 하는 CANbus 메시지는 다음과 같습니다.

Receiver ID Data Field
Controlword Reserved
D1 D2 D3 D4 D5 D6 D7 D8
201 0F 00 XX XX XX XX XX XX

RxPDO1 Switch ON (CANbus)

마지막으로 Enable Operation 에 해당하는 메시지를 전송합니다. Enable Operation 에 해당하는 2진수 Controlword 는 000000000001111 이므로, 이것을 16진수 2Byte 로 나타내면 00 0F 입니다. 따라서 Enable Operation 을 하도록 하는 CANbus 메시지는 다음과 같습니다.

Receiver ID Data Field
Controlword Reserved
D1 D2 D3 D4 D5 D6 D7 D8
201 0F 00 XX XX XX XX XX XX

RxPDO1 Enable operation (CANbus)

설정이 모두 완료되면, 마지막 CANbus 메시지에 다음과 같은 응답을 수신합니다.

Transmitter ID Data Field
Controlword Reserved
D1 D2 D3 D4 D5 D6 D7 D8
181 37 06 XX XX XX XX XX XX

RxPDO1 Motor ON 응답 (CANbus)

D2 가 06이면 성공적으로 모터가 작동합니다. 모터의 동작을 확인하였으면, 이제는 모터를 중지시키고, 타겟 토크도 0으로 만들어보겠습니다. 방법은 Terminate operating mode Controlword 를 전송하고, Quick Stop Controlword 를 전송하는 것입니다.

Terminate operating mode Controlword 를 포함한 CANbus 메시지는 다음과 같습니다. 이것을 RxPDO1 (201)에 전송합니다.

Receiver ID Data Field
Controlword Reserved
D1 D2 D3 D4 D5 D6 D7 D8
201 0B 00 XX XX XX XX XX XX

RxPDO1 Terminate operating (CANbus)

Quick Stop Controlword 를 포함한 CANbus 메시지는 다음과 같습니다. 이것을 RxPDO1 (201)에 전송합니다.

Receiver ID Data Field
Controlword Reserved
D1 D2 D3 D4 D5 D6 D7 D8
201 0F 00 XX XX XX XX XX XX

RxPDO1 Quick Stop (CANbus)

위 두 메시지를 전송하면 모터 구동이 중지됩니다.

모터 구동 (C++ 예제)

DSP-301과 DSP-402 프로토콜을 사용하여 타겟 토크 제어를 하는 지금까지의 과정을 C++ 프로젝트 파일로 옮겨서 타겟 토그 제어를 진행해보도록 하겠습니다. 이를 위한 소스 코드는 다음과 같습니다.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
/* NRMKFoundation, Copyright 2016- Neuromeka. All rights reserved.
 *
 * This library is commercial and cannot be redistributed, and/or modified
 * WITHOUT ANY ALLOWANCE OR PERMISSION OF Neuromeka
 *
 *
 * This Code only services the torque mode
 */

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mman.h>
#include <math.h>
#include <time.h>

#include <native/task.h>
#include <native/timer.h>
#include <rtdk.h>

#include "NRMKsercan_tp.h"
#include "NRMKhw_tp.h"

TP_PORT test_port=1;

int rtsercan_fd  = -1;

RT_TASK write_task;
RT_TASK read_task;
int working=1;
int TargetTor;
int trigger;
int i;
int t;

double PI = 3.14159265359;

int gt;

CAN_FRAME node_reset;
CAN_FRAME stop_motor;
CAN_FRAME Torque0;
CAN_FRAME Start_operational_state;
CAN_FRAME Enable_power1;
CAN_FRAME Enable_power2;
CAN_FRAME Enable_power3;
CAN_FRAME Starting_Torque_mode;
CAN_FRAME mode_Check;
CAN_FRAME Set_TargetTor;

CAN_FRAME Rnode_reset;
CAN_FRAME Rstop_motor;
CAN_FRAME RTorque0;
CAN_FRAME RStart_operational_state;
CAN_FRAME REnable_power1;
CAN_FRAME REnable_power2;
CAN_FRAME REnable_power3;
CAN_FRAME REnable_power4;
CAN_FRAME RStarting_Torque_mode1;
CAN_FRAME RStarting_Torque_mode2;
CAN_FRAME Rmode_Check;
CAN_FRAME RSet_TargetTor;

void cleanup_all(void)
{
    working=0;
    sleep(5);
    rt_task_delete(&write_task);
    rt_task_delete(&read_task);
//  Quick_Stop();

}

/*******************************************************************************/
void catch_signal(int sig)
{
    cleanup_all();
    return;
}

/*******************************************************************************/
void write_thread(void* arg)
{
    if(trigger == 0)
    {
        //Packet Definition************************
        node_reset.can_id=0x000;
        node_reset.can_dlc=2;
        for (i=0; i<2; ++i) node_reset.data[i]=0;
        node_reset.data[0]=0x81;

        stop_motor.can_id=0x201;
        stop_motor.can_dlc=2;
        for (i=0; i<2; ++i) stop_motor.data[i]=0;
        stop_motor.data[0]=0x0b;

        Torque0.can_id=601;
        Torque0.can_dlc=8;
        for (i=0; i<8; ++i) Torque0.data[i]=0;
        Torque0.data[0]=0x2b;
        Torque0.data[1]=0x71;
        Torque0.data[2]=0x60;

        Start_operational_state.can_id=0x000;
        Start_operational_state.can_dlc=2;
        for (i=0; i<2; ++i) Start_operational_state.data[i]=0;
        Start_operational_state.data[0]=0x01;

        Enable_power1.can_id=0x201;
        Enable_power1.can_dlc=2;
        for (i=0; i<2; ++i) Enable_power1.data[i]=0;
        Enable_power1.data[0]=0x00;

        Enable_power2.can_id=0x201;
        Enable_power2.can_dlc=2;
        for (i=0; i<2; ++i) Enable_power2.data[i]=0;
        Enable_power2.data[0]=0x06;

        Enable_power3.can_id=0x201;
        Enable_power3.can_dlc=2;
        for (i=0; i<2; ++i) Enable_power3.data[i]=0;
        Enable_power3.data[0]=0x0f;

        Starting_Torque_mode.can_id=0x601;
        Starting_Torque_mode.can_dlc=8;
        for (i=0; i<8; ++i) Starting_Torque_mode.data[i]=0;
        Starting_Torque_mode.data[0]=0x2f;
        Starting_Torque_mode.data[1]=0x60;
        Starting_Torque_mode.data[2]=0x60;
        Starting_Torque_mode.data[4]=0x04;

        mode_Check.can_id=0x601;
        mode_Check.can_dlc=8;
        for (i=0; i<8; ++i) mode_Check.data[i]=0;
        mode_Check.data[0]=0x40;
        mode_Check.data[1]=0x61;
        mode_Check.data[2]=0x60;

        Set_TargetTor.can_id=0x601;
        Set_TargetTor.can_dlc=8;
        for (i=0; i<8; ++i) Set_TargetTor.data[i]=0;
        Set_TargetTor.data[0]=0x2b;
        Set_TargetTor.data[1]=0x71;
        Set_TargetTor.data[2]=0x60;

        // Elmo Driver reset*******************
        RTSERCAN_write(rtsercan_fd, node_reset);
        sleep(5);
        /*
        while(1)
        {
            printf("node resetting...\n");
        }
        */

        // Set Elmo Driver ready*******************
        RTSERCAN_write(rtsercan_fd, Start_operational_state);
        printf("Starting the operational state \n");

        RTSERCAN_write(rtsercan_fd, Enable_power1);
        sleep(1);
        RTSERCAN_write(rtsercan_fd, Enable_power2);
        sleep(3);
        /*
        while(1)
        {
            printf("power setting...\n");
        }
        */
        RTSERCAN_write(rtsercan_fd, Enable_power3);
        sleep(1);
        RTSERCAN_write(rtsercan_fd, Enable_power3);
        sleep(1);
        /*
        while(1)
        {
            printf("power setting...\n");
        }
        */
        sleep(1);
        /*
        while(1)
        {
            printf("power setting...\n");
        }
        */
        //********************************

        RTSERCAN_write(rtsercan_fd, Starting_Torque_mode); //Set Elmo Driver to Torque mode
        sleep(1);
        /*
        while(1)
        {
            printf("power setting...\n");
        }
        */

        trigger = 1;
    }

        while(working == 1)
        {
            if(t==0)
            {
                printf("Target Torque Uploading.... \n");
                t=1;
            }
            TargetTor=50+50*sin(PI*0.1*gt);

            Set_TargetTor.data[4]= (int) TargetTor;
            RTSERCAN_write(rtsercan_fd, Set_TargetTor);
            gt++;
            sleep(1);
            rt_task_set_periodic(NULL, TM_NOW, 1e9);
        }
    RTSERCAN_write(rtsercan_fd, stop_motor);
    sleep(1);
    RTSERCAN_write(rtsercan_fd, Torque0);
    sleep(1);
}

/*******************************************************************************/
void read_task_proc(void *arg)
{

    /****node resetting check***************************************************************/
    /*
    RTSERCAN_read(rtsercan_fd, Rnode_reset);
    if(Rnode_reset.can_id==0x701 && Rnode_reset.data[0]==0x00 && Rnode_reset.data[0]==0x00)
    {
        break;
        printf("Driver reset. \n");
    }
    else
    {
        printf("Reset failed. \n");
        return 0;
    }
    */
    /****Enable power2 check*********************************************************/
    /*
    RTSERCAN_read(rtsercan_fd, REnable_power2);
    if(REnable_power2.can_id==0x181 && REnable_power2.data[0]==0x31 && REnable_power2.data[0]==0x02)
    {
        break;
        printf("Enable_power setting..... \n");
    }
    else
    {
        printf("Disable power. \n");
        return 0;
    }
    */
    /****Enable power3 check1*********************************************************/
    /*
    RTSERCAN_read(rtsercan_fd, REnable_power3);
    if(REnable_power3.can_id==0x181 && REnable_power3.data[0]==0x33 && REnable_power3.data[0]==0x02)
    {
        break;
        printf("Enable_power setting..... \n");
    }
    else
    {
        printf("Disable power. \n");
        return 0;
    }
    */
    /****Enable power3 check2*********************************************************/
    /*
    RTSERCAN_read(rtsercan_fd, REnable_power4);
    if(REnable_power4.can_id==0x181 && REnable_power4.data[0]==0x37 && REnable_power4.data[0]==0x02)
    {
        break;
        printf("Motor Power On \n");
    }
    else
    {
        printf("Disable power. \n");
        return 0;
    }
    */
    /****mode change check1*********************************************************/
    /*
    RTSERCAN_read(rtsercan_fd, RStarting_Torque_mode1);
    if(RStarting_Torque_mode1.can_id==0x581 && RStarting_Torque_mode1.data[0]==0x60 && RStarting_Torque_mode1.data[0]==0x60)
    {
        printf("Elmo Driver is on the Torque mode \n");
    }
    else
    {
        printf("Mode change failed. \n");
        return 0;
    }
    */
    /****mode change check2*********************************************************/

    /*
    RTSERCAN_read(rtsercan_fd, RStarting_Torque_mode2);
    if(RStarting_Torque_mode2.can_id==0x181 && RStarting_Torque_mode2.data[0]==0x37 && RStarting_Torque_mode2.data[0]==0x06)
    {
        printf("Elmo Driver is on the Torque mode \n");
    }
    else
    {
        printf("Mode change failed. \n");
        return 0;
    }
    */

    /*****read Target torque status**********************************************/
    int res;
    CAN_FRAME RxFrame;
    rt_task_set_periodic(NULL, TM_NOW, 1e8);
    while (working)
    {
        res=RTSERCAN_read(rtsercan_fd, &RxFrame);
        if (res==SERCAN_ERR_FREE)
        {
            rt_print_CANFrame(RxFrame);
        }
        gt++;
        rt_task_wait_period(NULL);

    }
}

/*******************************************************************************/
int main(int argc, char* argv[])
{

    signal(SIGTERM, catch_signal);
    signal(SIGINT, catch_signal);

    /* no memory-swapping for this programm */
    mlockall(MCL_CURRENT | MCL_FUTURE);

    // Perform auto-init of rt_print buffers if the task doesn't do so
    rt_print_auto_init(1);

    // open rtsercan*******************
    rtsercan_fd=RTSERCAN_open();
    if (rtsercan_fd < 0) return 1;
    //********************************

    trigger = 0;
    t=0;
    //Motor Control Start-----------------------------------------------
    rt_task_create(&read_task, "read_task", 0, 99, 0);
    rt_task_start(&read_task, &read_task_proc, NULL);


    rt_task_create(&write_task, "write_task", 0, 99, 0);
    rt_task_start(&write_task, &write_thread, NULL);

    //Must pause here
    //pause();
    while (1)
    {



        usleep(1e5);
    }

    //Finalize
    catch_signal(0);

    return 0;

}

위 코드를 확인해보면 알 수 있듯, 본 튜토리얼에서 타겟 토크 제어를 위해 SDO 설정부터 모터 구동까지 CANopen 프로토콜 CANbus 메시지를 전송하는 작업하는 순서 그대로 코드를 통해 보내도록 프로그래밍 되어 있습니다.

다만, 직접 CANbus 메시지를 보낼 때와는 다르게 타겟 토그 값을 실시간으로 갱신하며, 이를 위해 타겟 토크에 아날로그 신호를 입력하도록 되어있습니다. 이렇게 코드로 제어하게 되면, 모터 제어에 아날로그 신호를 사용할 수 있다는 장점이 있습니다.