EtherCAT servodrive

Free CoE (CAN over EtherCAT) CiA402 servodrive on STM32. For open motor controllers like ODrive, STMBL, or your next thing.

Similar projects worth following
Free EtherCAT CiA402 servo drive on STM32 (F1, F4). Now including also Arduino example.

EtherCAT is realtime Ethernet protocol for automation. The most common EtherCAT application protocol for servo drives seems to be CANopen (over EtherCAT) CiA402. This project is implementing that. Along the way it is showing how to do EtherCAT device development using free and open source tools where possible.

EtherCAT is realtime Ethernet based protocol for industrial control and automation. It is fast, it can be done using your laptop RJ45 port, it is established standard - it is great. It is especially well adapted for motion control applications. Hard real time features like Distributed Clocks make for guaranteed synchronization in nanosecond precision range. You can get equipment from array of vendors, and open source controllers (IgH, SOEM) for free - there is even LinuxCNC integration available. But so far there was not much open source EtherCAT devices. Particularly I found no open source EtherCAT servodrive. We cannot leave it like that.

  • AX58100 optimizing for speed

    kubabuda08/07/2021 at 11:34 0 comments

    Optimizing for precision and speed


    PDO reads should really be handled by DMA. Let us configure it and see how it goes. It works an then stops, it either randomly disconnects or starts to spew trash values, causing CiA402 state machine errors. Without DMA everything was working and was stable, so it is not power issue. Time to connect logic analyzer to see what is happening. At hand is cheapo FX2 based probe, to make it keep up SPI clock prescaler needs to be bigger, to drop clock frequency from max 41 MHz, to 5.125MHz. At this speed, transmission with DMA is stable back again. What can it be?

    Turns out, simple SPI implementation (sending byte by byte) adds significant breaks between each byte. DMA sends all bytes in one go, back to back. SPI addressing can be done in 2 bytes, or 3 bytes (with wait state byte) - second solution is meant to give ESC enough time to fetch valid data from memory into SPI, but there is minimal cycle time value, Tread for that. According to datashet Tread should be at least 240 ns. Using 3 byte addressing with wait state should solve it, and it does, up to 21 MHz. Unfortunately at SPI1 max speed, 41Mhz, with current setup problem persists. Maybe it is caused by current board layout and it could be fixed on next HW revision? Then again, it looks to be fast enough to work on STMBL, and SPI2 on ODrive tops out on 21 MHz anyway so for now it looks good enough - on to next problems.

    AX58100 moving towards interrupt mode - PDI interrupt and DC synchronization

    It took a bit but now is working too. One needs to adjust settings in TwinCAT: assign Sync Unit to local device


    Result is stable sync signal with very low jitter: about 150 ns even in large EtherCAT networks, according to Beckhoff claims

    [TODO] oscilloscope shot of SYNC0 signals

    Benchmark results

    Despite slower SPI clock speed, cycle time is much better than LAN9252:

    Polling (blocking SPI). SPI1 at 42 MHz

    • Cables connected, ECAT master not connected: [ESC benchmark] 0006 us (0006 top)
    • ECAT master connected, slv in OP: [ESC benchmark] 0015 us (0059 top)
    • ECAT master connected, slv in OP, network startup hiscore reset: [ESC benchmark] 0015 us (0024 top)

    Added CiA402 loopback, SPI1 at 42 MHz:

    • ECAT master connected, slv in OP, network startup hiscore reset: [ESC benchmark] 0017 us (0025 top)

    DMA SPI + CiA402 loopback. Prescaler 2 (42 MHz), SPI reads from ESC are unstable - transmission errors

    • ECAT master connected, slv in OP: [ESC benchmark] 0017 us (0063 top)
    • ECAT master connected, slv in OP, network startup hiscore reset: [ESC benchmark] 0017 us (0025 top)

    DMA SPI + CiA402 loopback. Prescaler 4 (21 MHz: 2x slower clock), 2 us slower

    • Cables connected, ECAT master not connected: [ESC benchmark] 0009 us (0009 top)
    • ECAT master connected, slv in OP: [ESC benchmark] 0019 us (0073 top)
    • ECAT master connected, slv in OP, network startup hiscore reset: [ESC benchmark] 0019 us (0030 top)

    Seems like all that extra work with laying out another HW revision, and switching to new ESC from relatively unknown company, paid out. For now I will continue with AX58100. If anyone feels like stepping up and optimizing LAN9252 driver, PRs are welcome.

  • AX58100

    kubabuda08/07/2021 at 11:33 0 comments

    AX58100 Board design

    LAN9252 indirect register addressing is complex … frankly it feels cumbersome. Building DMA for that is certainly possible (with few state machines and plenty interrupts) but super messy and not that efficient either. The original ESC from Beckhoff, ET1100, was much more straigtforward to work with. To see the difference, just compare SOES HAL files for ET1100 vs LAN9252. Look at line count of respective files should be enough. Unfortunately ET100 costs 2-3 times as much and requires more external elements. Luckily, we can eat the cake and have it too thanks to ASIX, Chinese company I have never heard of before. They got license from Beckhoff and made improved derivative, AX58100. ASIX chips are not really offered via typical western suppliers, but few Aliexpress sellers have it. I risked few dozen of $, and while waiting for shipping I also designed PCB based on LAN9252 second revision. This time STM32F4 Discovery adapter with 3.3V regulator (and separate USB for power) is part of PCB that can be snapped off like ST Link from Nucleo boards.



    IBOM can be found here

    AX58100 board assembly


    Repeating approach that worked with LAN9252, DIG IO ESI was flashed at first, and it was working right off the bat. Board is doing good so far.


    AX581000 with SOES

    This ESC is based on ET1100, and one of HAL setups in SOES source target this chip. As was with LAN9252, lets implement SPI read/write and go to town.


    It is not working. Why? Let us check datasheet and manual for migration from ET1100. To enable SPI PDI, 4K7 pullup resistor to 3v3 is needed on SCS_FUNC. Is it enough? Hardware wise yes, overall no. Some configuration registers are different on AX58100. More head banging against docs ensures. AX58100 datasheet is rather short, what is missing there can be found in ET1100 datasheet. Luckily ASIX has code samples for STM32 Nucleo available on their webpage, and those include ESI files with correct configuration bytes. For SPI setup turns out HIES register (Host Interface Extend Setting and Drive Strength) which is mapped to configuration byte 0x0A, should be set to 0x1a (INT edge pulse length, 8 mA Control + IO 9:0 Drive Select). It is in area covered by checksum, so we need to calculate new one too.


    After all that time and head scratching, new board is reaching OP with SOES application. Radiator was added to mitigate overheating while working on getting right PDI configuration in ESI file. Now that it is correct, feels like it is not probably wont needed will test on next boards.

    Example: CiA 402 application on AX58100 with STM32F4

  • LAN9252-SPI board, second revision

    kubabuda08/06/2021 at 20:21 0 comments

    In the meantime some things to correct were found in first revision of SPI adapter.

    - QFN is annoying to hand solder. TQFP package was selected, there is enough space on PCB

    - changed magjacks to cheaper ones

    - EEPROM  switched from THT in socket to SMD package: less bulky, cheaper. Swapping chip from board bricked by bad config was never needed. No matter how bad was configuration, new one could be upload over EtherCAT every time.



    IBOM can be found here

    Design is ready to order and test, but due to performance benchmark results different approach was selected

  • LAN9252-SPI with SOES

    kubabuda08/05/2021 at 18:56 0 comments

    Luckily SOES has HAL file for LAN9252 with SPI, only SPI config, read and write need to be implemented.

    Example SOES application on LAN9252 with STM32F4

    And example application is running on custom device. Great.

    Speed benchmarking

    We already know PDOs size. RxPDO (command from master to servodrive) will be uint16_t controlword + uint32_t position command, TxPDO (feedback from our servo device) is the same size: uint16_t statusword, uint32_t position actual, so it is 6 bytes in, 6 bytes out. We can set it in EasyCAT and see how long does it take to cycle. Then we can tweak PDOs in SOES project, and test speed the same way.


    Measured is PDI communication cycle time (EASYCAT.MainTask();) from start to return.

    SSC MCU SPI driver SPI speed value [us]
    EasyCAT AtM328P Arduino 8 MHz 196
    EasyCAT STM32F4 Arduino 8 MHz 210
    EasyCAT STM32F4 Arduino 42 MHz 118
    EasyCAT STM32F4 Arduino 42 MHz 107
    EasyCAT STM32F4 SPL 5.25 MHz 123
    EasyCAT STM32F4 SPL 42 MHz 35


    Measured is how long does polled ecat_slv(); take from start to return. No interrupts, should be more deterministic and consistent. STM32F405 at 168 MHz. SPI1 at 42 MHz

    • Cables connected, ECAT master not connected: [ESC benchmark] 0028 us (028 top)
    • ECAT master connected, slv in OP: [ESC benchmark] 0072 us (0280 top)

    Results are… not great for LAN9252 with CoE stack. It was okay with EasyCAT library, but something with SOES setup makes it much slower, and to make things worse timing is not consistent. Considering app notes from Microchip on measuring cycle time (with Slave Stack Code from Beckhoff) this should look way better, and deserves proper investigation.

    SOES as Arduino library

    At this point it is not much work to port SOES as Arduino library.

    Sample project using popular STM32F103 “BluePill” devboard


    CiA402 profile implementation

    First step is to get CiA 402 state machine diagram, for example from datasheet of some servodrive implementing it. Hiwin has it described well . From this one can calculate commandword masks, command codes for each transition, statusword masks and status codes for each state. Here goes resulting transition table:


    Then just retype these codes into .c header, connect it to get state machine code, wire it with object dictionary, set correct ProductCode="#x00020192" (0x192 is 402d, CiA402 profile code)… Oh, and add dummy motion control application: loopback Obj.Position_actual = Obj.Target_position;

    CiA402 dummy on STM32F1

    TwinCAT configuration

    Way to test if node implementation is working is maing it work with TwinCAT. For that one needs to create project, and add point to point motion control with single axis. Connect device, scan for boxes and select new device in axis settings.


    To launch project, one needs to enable configuration. If it is first time, fill captcha in prompt window to generate temporary license key for NC module


    Configuration should be now active and new device should reach OP (Operational state of EtherCAT state machine). Now it is time to set target velocity and enable controller. Go to Online tab to do it. Then reset errors (F8 key or blue button), and activate axis (F5 or green button).


    This is how it should look like. Dummy servo responds to commands, and reports it went exactly where controller requested.


  • LAN9252-SPI adapter assembly and testing

    kubabuda08/04/2021 at 14:15 0 comments


    PCBs arrived from board house


    First one is already assembled. It is dirty from resin-based flux, but looks OK


    Connected to Ethernet port, and powered up. Nothing bad happened. Flashed with DIGIO ESI (EtherCAT Slave Info), restarted, opened Simple EtherCAT Explorer and looks it is working.


    Now to make it work with microcontroller.


    Lets start with EasyCAT Arduino library on ATMega, using platformio

    It is working. How stable is it? Turns out not very much. After random period up, usually few minutes, ESC is either disconnected from master or starts to spew garbage values. What could be wrong? First culprit is power that was supplied from 3V3 regulator on Arduino. Lets add another one, powered from separate USB cable. That worked. For convinience, to have only 1 USB cable connected, 5V line to separate regulator can be pulled from ISCP header


    BTW, turns out that LAN9252 lines are not 5V tolerant. Suprise, ESC is working entire time without issues, but is uncomfortably close to absolute maximum rating. Voltage level shifter fixes that.


    Now on to port that STM32F4 Discovery board. Built quick adapter using SPI1 pinout exposed on STMBL extension header. Problem with power supply repeats. 3V3 from EVB is not good, another USB cable just to power up ESC is needed.


    It is working too. But STMBL is using StdPeriph drivers. Time to ditch Arduino code and port SOES to SPL

    Known issues

    • Problem with OUT port. It is treated as network termination, following EtherCAT devices connected there are not detected by master.
    • Proper separation of chassis ground from device ground with clearance will be needed beyond lab bench stage.
    • All components should be on single side to simplify PCBA.
    • Few silkscreens were messed up.
    • ESC chip in TQFP housing would be easier to hand solder.
    • So far EEPROM replacing was never needed, even at most messy initial stages. EEPROM should be SMD, to shave BOM cost and board size.
    • Cheaper RJ45 magjack connectors were found (HanRun HR911105A)

    TLDR: dont build this version. It worked good enough for my use case (single node development), but if you think of using it for anything practical buy EasyCAT PRO or wait for something better.

    Next step: make CoE stack work on new hardware

  • LAN9252-SPI adapter board design

    kubabuda08/03/2021 at 20:08 0 comments

    Starting point was this open source project. Stripped schematic to bare minimum, based on EVB-LAN9252-SPI. Left only SQI PDI, then minified board area. Two layers, almost all components on single side for easier assembly and embedding into target devices.



    Adapter board, first revision, straight from KiCad.

    IBOM can be found here

    Looks good. Board came out similar to EasyCAT Pro. Breakout header is compatible, additionally alongside it has full SQI exposed. Also EEPROM chip is THT in socket for simple swap if ESI flashing goes wrong and bricks device. Now forward to board house of choice, and wait for PCBs to arrive.

    Spoiler alert: it worked good enough for what I needed, for practical use you better wait for something better or buy EasyCAT PRO

  • EtherCAT compatible servo drives for everyone

    kubabuda08/03/2021 at 20:05 0 comments

    I am building EtherCAT adapter for open motor controllers like ODrive, STMBL, or your next thing.

    Why that matters

    We got a known problem in state of art open source robotics. On one side for years we got things like LinuxCNC: multiple axis, builtin PLC, free, field proven. If its not fit for application, every year progress in development tools (toolchains, code etitors, hardware) makes it easier to roll out custom one that will do the job. On he other side, we got plenty of OSS+OSHW actuators: projects like ODrive, STMBL, VESC and many more. Good to power things from BLDC motor in quadcopter, to benchtop laser ploter, to electric scooter, to industrial machining center. What is missing? Good free way to properly connect one to another. This might not sound like a problem for electric scooter, but starts to be when one tries to build robotic arm, quadruped robot or fast CNC machine, and I will explain why.

    How OSS motion control used to be done

    Legacy way of motion control in open source was to use step-dir over parallel port. It is simple way to control stepper motors working in open loop (without encoders or other sensors), devised back when everyone used PC towers that had LPT. Some modern digital servodrives are still supporting it, but this starts to be problematic for several reasons.

    • This is in principle open loop communication. Lost pulse signal will result in quiet position error, as controller computer will not have a way to see target drive position. It is especially not elegant in using step-dir for servo drives position control. Position value is digital on controller side and on servodriver side, but communication channel makes it drop its digital nature, then pick it up again, then prevents actual position feedback to controller. Uuugly.
    • It is speed bottleneck: speed of software step generation is limited. Exceeding it will result in errors: lost steps. Depending on PC setup, pushing pulse rates above 20 KHz - 100 KHz starts to be ridden with error. Compose it with open loop, and you only see this errors if it accumulates and becomes real problem (e.g. CNC machine plunges into workpiece few hours in the job).
    • Additional I/O (homing, touchprobes, interlocks, signal lights) is limited. Parallel port lines can also be used for IO but they are fixed: both in number (there is only 16 lines total, les than half can be used as inputs), and position (some lines cannot be uset as inputs).
    • Self diagnostics is limited: servo drive might detect and identify error state, but has no way to sent its code to controller.

    How it is done now (in open source and entry level motion controllers)


    • Linux CNC with LPT still is viable solution for machines with few stepper motors and limited IO. All drawbacks described above apply, but for CNC router this often is enough
    • Linux CNC with Mesa cards: Mesa is company that offers line of extension cards with FPGA, targeting LinuxCNC. Bitfiles source code is open, hardware is proprietary but not expesive. There are multiple connectivity configurations for each card. First is using hardware step signal generation to overcome software stepgen limits. Much more reliable, works all right with servo drives supporting pulse-dir signals. Some cards got analog inputs and outputs and can be used to control older, voltage controlled servo amplifiers but this is really legacy solution for retrofits.
    • There is also smart serial (sserial), Mesa specific protocol for modular extensions. It uses RS422 differential transmission for fast, noise resistant communication. If you want to use STMBL servo drives to build CNC machine, this seems to be the preffered way. Problem is STMBLs are hard to buy, and those (and some Mesa servo drives) are the only devices using sserial protocol (that I know of).
    • LinuxCNC with proprietary extension cards, from vendors like These are adding support for proprietary protocols like SSCNET, MELDAS, Mechatrolink. Cards themselves are not open source, pricing...
    Read more »

View all 7 project logs

Enjoy this project?



Sebastian Amann wrote 01/13/2022 at 16:52 point

Hey kubabuda,
I'm currently developing/adding EtherCAT-functionality to an existing PCB based on an STM32F207IG. 

You wrote "Luckily SOES has HAL file for LAN9252 with SPI, only SPI config, read and write need to be implemented.".

But I'm unable to find the corresponding file for the STM32 in the SOES github-repo ( 

Am I missing something or did they remove it? 

Or did you modify one of the available HALs and modified it to fit the STM32? If this is the case,  which of the HALs in SOES did You modify?

Have a nice day!

edit: after a bit of comparison I think that the "rt-kernel-lan9252" is the base of your "stm32-lan9252"?

  Are you sure? yes | no

kubabuda wrote 01/29/2022 at 11:05 point


Official SOES examples include no STM sample, but SPI interface needs to do the same thing whether it is implemented as Linux driver or STM32 firmware. You only need to swap periph driver calls.

  Are you sure? yes | no

arbee wrote 09/14/2021 at 18:29 point

@ Kubaduba,. Are your KiCad pcb files or schematics available?

  Are you sure? yes | no

kubabuda wrote 01/29/2022 at 11:08 point

How many boards do you need? I got a few blank PCBs for AX, and I might be purchasing some preassembled boards soon.

  Are you sure? yes | no

nico_michiels wrote 08/26/2021 at 20:52 point

@kubabuda do you have any spare board for sale or any idea of a price to build it myself? I would like to test one to see how far I can get it working with my new version of RepRap Firmware for a 3D printer

  Are you sure? yes | no

kubabuda wrote 08/27/2021 at 17:19 point

At the moment I do not have spare boards for sale. You can buy EasyCAT Pro for 50 EUR.  If you want to build boards yourself, make sure you can get ESC chip first. Those used to be 10$ and now they got unavailable form usual sources due to chip shortage. Other then that, 2x magjack + I2C EEPROM + misc resistors, caps, regulators, PCB itself - should not be over 10 USD per board (excluding ESC itself)

What is your use case for EtherCAT in 3D printer? CiA402 device per axis (what I\m doing here) feels like overkill for typical benchtop device

  Are you sure? yes | no

Roiki11 wrote 08/19/2021 at 12:20 point

Have you thought about testing the newer lan9253/4 slave chips? They're supposed to be improved over the 9252 and support direct addressing.

  Are you sure? yes | no

kubabuda wrote 08/23/2021 at 21:33 point

I have not, because I did not notice that in their datasheet. That is neat and good to know, I will purchase a few to have a look when they are back. Probably 22-Aug-2022 according to Microchip page

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates