---
title: "EtherCAT Motor Control Example on Raspberry Pi 4 (SOEM + SPI-W5500)"
url: "https://maker.wiznet.io/josephsr/projects/ethercatmotorexample/"
markdown_url: "https://maker.wiznet.io/josephsr/projects/ethercatmotorexample/md"
type: "UCC: User Created Content"
author: "Paul Hutchinson"
author_url: "https://github.com/TheBeef/EthercatMotorExample"
editor: "WIZnet"
editor_url: "https://maker.wiznet.io/"
original_author: "Paul Hutchinson"
original_url: "https://github.com/TheBeef/EthercatMotorExample"
published: "2026-03-04"
language: "en"
likes: 0
views: 551
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# EtherCAT Motor Control Example on Raspberry Pi 4 (SOEM + SPI-W5500)

> A minimal EtherCAT master example that drives a single motor in CiA 402 Profile Position Mode using SOEM on a Raspberry Pi 4 with a WIZnet W5500 SPI Ethernet.

Original author: Paul Hutchinson (source: https://github.com/TheBeef/EthercatMotorExample)

## Article

### Overview

This repository focuses on one practical goal: get an EtherCAT motor moving from a Raspberry Pi using SOEM, without building a full multi-axis real-time motion controller. The example issues position targets (in degrees) and lets the drive execute the motion profile internally, then polls until the move completes.

### Main Content

- **What it demonstrates**
  - **Bringing an EtherCAT network to OP state** via SOEM initialization, slave discovery, IO map setup, and state transitions to SAFE_OP and OP.
  - **Drive control through CoE SDO writes/reads** using CiA 402-style objects (e.g., controlword/statusword, mode of operation, target position).
  - **Profile Position Mode command pattern**: set mode, reset/enable sequence, configure profile accel/decel/velocity, write target position, trigger a new setpoint, then wait for completion by reading status/position.

- **What it deliberately does not try to be**
  - Not a synchronized multi-axis motion loop.
  - Not an example of cyclic synchronous position/velocity/torque with strict deterministic cycle timing.
  - Not a generic “works for every drive” template (tested on a single motor per the repository notes).

### System Context

**Role in a broader automation stack**

The Pi acts as an **EtherCAT master** that performs configuration and issues motion targets.

The drive remains the **primary motion executor** (trajectory generation happens inside the motor drive in Profile Position Mode). This makes the master a coordination/command layer rather than the hard real-time servo controller.

**Ethernet interface choice (WIZnet requirement)**

The setup assumes a **WIZnet W5500 (SPI) Ethernet interface** connected to a Raspberry Pi 4, and the SOEM init path is configured to use the “wiznet” interface.

In this system, the W5500 is not a “generic Ethernet mention,” it is the concrete NIC path that the example code configures before `ec_init("wiznet")`.

### Architecture / Design Considerations

**Design flow (why it’s structured this way)**

- **Hardware/OS baseline**: Raspberry Pi OS 32-bit is required by the provided setup notes.

- **Kernel/tooling alignment**: the instructions point to a kernel change intended to make SOEM + W5500 workable in this environment (prebuilt deployment steps).

- **EtherCAT stack initialization**: configure W5500 SPI parameters, initialize the SOEM “wiznet” NIC, scan/configure slaves, map process data, and drive the network to OP.

- **Control by SDOs**: implement small helpers for 8/16/32-bit SDO access and build a Profile Position Mode sequence on top.

- **Completion detection**: poll position and statusword until the target is reached (or the relevant “busy” bit clears).

**High-cost failure points**

- **Network not reaching OP state**: if slaves do not transition to OP, nothing else matters. The example prints per-slave state and AL status codes, reflecting that this is the first “make-or-break” gate.

- **Drive state machine sequencing**: Profile Position Mode depends on correct controlword transitions and setpoint triggering. A wrong sequence can leave the drive disabled or ignoring targets.

- **Assuming portability across motors**: the repo itself warns it was only tested on one motor and that the motor had design issues, which increases integration risk when applied elsewhere.

**Component removal and how it changes the system**

- Remove **W5500 / “wiznet” path**: the project no longer has its configured EtherCAT NIC and will require a different SOEM NIC driver and interface name, changing both wiring and software integration.

- Remove the **kernel/tooling assumptions** from the setup notes: the environment described by the repo is no longer matched, increasing the chance that SOEM + SPI NIC behavior diverges from the example’s expectations.

- Remove **Profile Position Mode** as the control strategy: you shift from “drive executes motion internally” to designs that may require cyclic real-time command streaming, which changes timing requirements and the overall control architecture.

### Possible Implications

As a learning scaffold, this is useful for engineers who need a concrete reference for **(a) getting OP, (b) doing basic CiA 402 positioning via SDOs**, and (c) validating that the EtherCAT link is functioning.

For production multi-axis motion, the “profile position + polling” structure will likely become an auxiliary layer (setup, homing triggers, coarse moves, diagnostics), while the core motion loop may migrate to a more deterministic cyclic scheme or dedicated motion controller.

### Conclusion

This repository is best read as a pragmatic “first successful motion” reference: it shows the end-to-end plumbing from SPI-W5500 NIC configuration to EtherCAT OP state and a minimal CiA 402 Profile Position command sequence. Its boundaries are explicit: single-motor testing, non-synchronized motion strategy, and environment-specific setup steps.

---

### 전체 개요

이 저장소는 “라즈베리파이에서 EtherCAT 모터를 **일단 움직이게 만드는**” 것을 목표로 한, 매우 실무 지향의 예제입니다. 핵심은 SOEM 기반 EtherCAT 마스터 초기화(OP 상태 진입)와, CiA 402 계열의 Profile Position Mode로 목표 위치를 쓰고 완료를 확인하는 흐름입니다.

### 문제의식과 기술적 맥락 재구성

현장에서 EtherCAT 모터 제어를 시도할 때 첫 번째 벽은 보통 두 가지입니다.

- **EtherCAT 네트워크가 OP(Operational)까지 올라가지 않는다**

- OP는 됐는데 **드라이브(CiA 402) 상태머신/모드 설정이 맞지 않아 모터가 반응하지 않는다**

이 예제는 위 두 벽을 넘는 데 필요한 “최소한의 골격”을 보여줍니다. 다만, 멀티축 동기 제어나 초정밀 주기 제어를 목표로 한 구조는 아닙니다(아래에 설명드리겠습니다).

### 기술 흐름 설명 (신호 / 데이터 / 동작 순서 중심)

#### 1) 하드웨어/드라이버 경로 고정: SPI-W5500 기반 NIC

README에서 **Raspberry Pi 4 + SPI W5500** 연결을 전제로 합니다.

코드에서도 `wiznet_hw_config(...)` 후 `ec_init("wiznet")`로 들어가며, “wiznet” NIC 경로가 이 예제의 출발점입니다.

즉, “EtherCAT은 Ethernet 물리층을 쓰지만 아무 NIC나 되겠지”가 아니라, **이 프로젝트는 W5500(SPI)라는 매우 구체적인 경로에 묶여** 있습니다.

#### 2) EtherCAT 마스터 기동: OP 상태까지 올리는 절차

코드 상 흐름은 전형적인 SOEM 절차를 따릅니다.

`ec_init("wiznet")`

`ec_config_init(false)`로 슬레이브 스캔/자동 설정

`ec_config_map(&IOmap)`로 프로세스 데이터 맵 구성

SAFE_OP 상태 확인 후 OP 요청 및 확인 (`ec_statecheck`, `ec_writestate`)

OP 실패 시 슬레이브별 상태/AL status code를 출력하여 어디서 막혔는지 드러냅니다.

여기서 **OP 진입이 사실상 1차 관문**입니다. OP가 되지 않으면 뒤의 “모터 제어”는 의미가 없습니다.

#### 3) 모터 제어 전략: Profile Position Mode + SDO 기반 설정/트리거

이 예제는 “동기 제어”가 아니라, 드라이브 내부 프로파일러에 맡기는 **Profile Position Mode**를 사용합니다. README에서도 “다른 모터와 동기화되지 않는다”고 명시되어 있습니다.

`GotoPos(pos)` 내부에서 중요한 순서는 아래처럼 정리됩니다.

- Mode of Operation(0x6060) 설정

- Controlword(0x6040)로 “shutdown → switch on → enable” 유사 시퀀스

- Profile accel/decel/velocity(0x6083/0x6084/0x6081) 설정

- Target position(0x607A) 설정 (각도→펄스 변환)

- Controlword로 새 setpoint 트리거(절대 위치)

- 완료 대기: position actual value(0x6064)와 statusword(0x6041)를 반복 읽기

이 흐름의 특징은 “마스터가 매 주기마다 위치/속도를 밀어넣는 구조”가 아니라, **한 번 목표를 던지고 드라이브가 알아서 움직인 뒤 완료를 확인**한다는 점입니다.

### 왜 이런 구조가 나왔는지에 대한 해설

#### 기존 접근 대비 핵심 차이

흔히 기대하는 EtherCAT 모션 제어는 “주기적으로 PDO를 교환하면서 동기 제어(예: CSP/CSV/CST)” 쪽으로 상상하기 쉽습니다.

그런데 이 예제는 반대로 **‘드라이브 내부의 모션 기능(Profile Position)’을 적극 활용**해서, 마스터의 역할을 “명령/확인” 수준으로 낮춥니다.

즉, EtherCAT을 “초정밀 동기 제어 버스”로만 쓰지 않고, **현장에서 ‘일단 움직이게 만들기’에 유리한 방식으로 절충**한 구조입니다.

#### 왜 보조 수단으로 위치하는지

이 구조에서 **주 제어 루프(trajectory/servo loop)는 드라이브 내부**에 있고, 라즈베리파이+SOEM은 “목표/파라미터 세팅 및 상태 확인”에 가깝습니다.
그래서 시스템 관점에서 이 예제는 다음 같은 “보조 수단” 역할에 더 가깝습니다.

- 초기 구동/통신 검증

- 단발성 이동(홈 포지션, 기본 각도 이동)

- 상태 모니터링 및 장애 포착

- **추론임:** 멀티축 동기 제어, 고정 주기 서보 제어가 목표라면 이 구조를 그대로 확장하기보다, PDO 기반의 cyclic control 구조로 재설계가 필요할 가능성이 높습니다(특히 타이밍/지터 요구가 올라가는 경우).

### 설계 선택의 배경, 제약 조건, 대안 가능성

#### (1) W5500(SPI) 선택

이 저장소는 W5500을 “있으면 좋음” 정도가 아니라, 아예 **예제의 NIC 경로로 박아넣은 형태**입니다(`ec_init("wiznet")`).

README에서도 하드웨어 전제로 명시합니다.

대안은 크게 두 갈래입니다.

- 라즈베리파이의 기본 Ethernet 포트(또는 USB Ethernet)로 SOEM을 붙이는 방향

- EtherCAT 마스터 역할을 라즈베리파이 밖(산업용 PC/전용 마스터)으로 옮기는 방향

다만, 저장소 토론에서는 “노트북 Ethernet 포트로 하려면 작업이 꽤 필요하다”는 취지의 언급이 있습니다.

#### (2) 커널/OS 제약

README에 따르면 Raspberry Pi OS는 32-bit를 요구하고, 커널을 교체하는 절차를 안내합니다.
여기서 중요한 포인트는 “단순 빌드”가 아니라, **환경 자체를 예제에 맞추는 과정이 포함**된다는 점입니다.

**추론임:** 이런 커널/환경 고정은 EtherCAT의 타이밍 민감도 및 SPI NIC 경로의 동작 안정성과 연관될 수 있습니다. 따라서 이 부분을 건너뛰면 “빌드는 되는데 OP가 안 올라가거나, 올라가도 통신이 불안정한” 류의 실패가 날 수 있습니다.

### 실패 비용이 가장 큰 판단 지점

이 프로젝트 관점에서 “여기서 틀리면 시간을 크게 잃는 구간”은 보통 아래 두 군데입니다.

- **OP 상태 진입 실패**
  - 슬레이브 스캔, 상태 천이에서 막히면 이후 단계가 전부 무의미해집니다. 코드도 OP 실패 시 슬레이브 상태와 AL status code를 찍어 원인 추적을 유도합니다.

- **드라이브 상태머신/모드/세트포인트 트리거 실수**
  - Profile Position은 “목표만 쓰면 움직이겠지”가 아니라, controlword 시퀀스와 setpoint 트리거가 맞아야 합니다. 이 부분이 어긋나면 조용히 아무 일도 안 일어나는 경우가 흔합니다.

### 특정 구성요소 제거 시 시스템 성격 변화

- **W5500 제거 시:** 이 예제의 “wiznet NIC” 전제가 깨져서, EtherCAT 통신 경로 자체를 다시 설계해야 합니다(다른 NIC 드라이버/인터페이스로 SOEM 초기화부터 변경).

- **Profile Position 제거 시:** 드라이브 내부 모션에 맡기던 구조가 무너지고, 마스터가 더 촘촘한 주기 제어를 떠안게 될 가능성이 커집니다. 즉, 시스템이 “명령/확인”에서 “실시간 제어” 쪽으로 성격이 바뀝니다.

- **README의 커널/OS 절차 제거 시:** 예제가 가정한 실행 환경과 달라져, “OP 불가/불안정” 같은 형태로 실패가 터질 수 있습니다. (이 부분은 README가 환경 고정을 강하게 요구한다는 점까지만 ‘사실’이고, 실패 양상은 **추론임**입니다.)

---

## FAQ

1. **기존 EtherCAT 모션 예제들과 비교했을 때 가장 큰 차이는 무엇인가요?**
   Profile Position Mode를 사용해서 드라이브 내부 프로파일러에 움직임을 맡기고, 마스터는 목표 설정과 완료 확인에 집중합니다. 그래서 “주기적 동기 제어”보다는 “일단 구동 성공”에 초점이 맞춰져 있습니다.

2. **왜 W5500(SPI) 같은 구성이 선택되었나요?**
   이 저장소는 W5500을 단순 참고가 아니라, 코드 레벨에서 `ec_init("wiznet")`로 고정된 NIC 경로로 사용합니다. 즉, 예제의 재현성을 위해 통신 경로를 명확히 하나로 고정한 선택으로 해석할 수 있습니다. (후반 문장은 **추론임**입니다.)

3. **핵심 신호/데이터 흐름을 한 줄로 요약하면 무엇인가요?**
   “OP 상태 진입 → SDO로 모드/파라미터/목표 위치 설정 → controlword로 setpoint 트리거 → statusword/position을 읽으며 완료 대기”입니다.

4. **실패 비용이 가장 큰 판단 지점은 어디인가요?**
   첫째는 슬레이브가 OP에 올라오느냐이고, 둘째는 CiA 402 제어 시퀀스가 맞느냐입니다. 이 둘이 틀리면 나머지 디버깅은 대부분 “의미 없는 로그”만 쌓이기 쉽습니다. (마지막 문장은 **추론임**입니다.)

5. **W5500을 빼고 라즈베리파이 기본 Ethernet으로 하면 그대로 쓸 수 있나요?**
   그대로는 어렵고, 최소한 SOEM 초기화 인터페이스와 NIC 드라이버 경로를 바꿔야 합니다. 저장소 토론에서도 다른 환경(노트북 포트 등)으로 가는 경우 작업이 필요하다는 취지의 언급이 있습니다.

6. **이 예제가 ‘보조 수단’으로 위치한다고 말하는 근거는 무엇인가요?**
   Profile Position Mode에서는 실제 궤적 생성과 구동이 드라이브 내부에서 이뤄지고, 마스터는 목표와 트리거, 확인에 집중합니다. 그래서 시스템 전체에서 마스터가 “서보 루프의 중심”이라기보다, “명령/검증 레이어”로 배치되기 쉽습니다. (두 번째 문장은 **추론임**입니다.)

---

## 저자 정보 (Author Information)

- Paul Hutchinson

- 공개된 정보가 제한적임

- (추론임) GitHub 프로필 자기소개 기준, 임베디드 C 중심 개발 배경으로 보임

---

Source: https://maker.wiznet.io/josephsr/projects/ethercatmotorexample/
