Skip to content

Instantly share code, notes, and snippets.

@andramalech
Forked from Bouni/LinuxCNC-Ethercat.md
Created April 30, 2023 21:31
Show Gist options
  • Save andramalech/1d48f29e1460ddc71497613c0207739c to your computer and use it in GitHub Desktop.
Save andramalech/1d48f29e1460ddc71497613c0207739c to your computer and use it in GitHub Desktop.
Linux CNC + EtherCat + RPi 4 Setup

The folowing is a writup from Hakans forum post!

RPi Setup

  1. Download & Write image to SD card: www.linuxcnc.org/iso/linuxcnc-2.8.1-pi4.zip
  2. Configure Wifi via wpa_supplicant.conf
  3. Put SD card into RPi and verify that RT-PREEMT Kernel is running: uname -a
  4. Update everything and reboot: sudo apt update && sudo apt upgrade && sudo reboot

VNC In Order to start linuxcnc you need to establish a VNC session or start it headless via DISPLAY=:0 linuxcnc <yourinitfile>.ini. I had to start the pi once with a display connected to get VNC working for some reason, despite having enabled VNC via raspi-config.

Prepare for EtherCat Setup

  1. Check installed Kernel version uname -r
  2. Install linux-headers that match installed kernel sudo apt install linux-headers-4.19.71-rt24-v7l
  3. Install toolchain sudo apt install mercurial build-essential automake tree dkms bison flex

Install etherlab master

git clone https://github.com/icshwi/etherlabmaster
cd etherlabmaster
make init
echo "ENABLE_CYCLES = NO" > configure/CONFIG_OPTIONS.local
make build
make install
echo "ETHERCAT_MASTER0=eth0" > ethercatmaster.local
make dkms_add
make dkms_build
make dkms_install
make setup

Necessary dirty hack to get things working

sudo mkdir -p /usr/include/linuxcnc
sudo ln -s /opt/etherlab/include/*.h /usr/include/linuxcnc/
sudo ln -s /opt/etherlab/lib/lib* /usr/lib/

Reboot and verify that Ethercat is running

pi@linuxcnc:~ $ ethercat master
Master0
Phase: Idle
Active: no
Slaves: 3
Ethernet devices:
Main: dc:a6:32:05:7e:65 (attached)
Link: UP
Tx frames: 3990
Tx bytes: 239560
Rx frames: 3989
Rx bytes: 239500
Tx errors: 0
Tx frame rate [1/s]: 48 51 41
Tx rate [KByte/s]: 2.8 3.0 2.4
Rx frame rate [1/s]: 48 51 41
Rx rate [KByte/s]: 2.8 3.0 2.4
Common:
Tx frames: 3990
Tx bytes: 239560
Rx frames: 3989
Rx bytes: 239500
Lost frames: 0
Tx frame rate [1/s]: 48 51 41
Tx rate [KByte/s]: 2.8 3.0 2.4
Rx frame rate [1/s]: 48 51 41
Rx rate [KByte/s]: 2.8 3.0 2.4
Loss rate [1/s]: 0 0 0
Frame loss [%]: 0.0 0.0 0.0
Distributed clocks:
Reference clock: Slave 0
DC reference time: 0
Application time: 0
2000-01-01 00:00:00.000000000
pi@linuxcnc:~ $ ethercat slave
0 0:0 PREOP + EK1100 EtherCAT-Koppler (2A E-Bus)
1 0:1 PREOP + EL1008 8K. Dig. Eingang 24V, 3ms
2 0:2 PREOP + EL2008 8K. Dig. Ausgang 24V, 0.5A

Install linuxcnc-ethercat

  1. Install linuxcnc dev version sudo apt install linuxcnc-uspace-dev
  2. Download, build and install linuxcnc-ethercat
git clone https://github.com/sittner/linuxcnc-ethercat
cd linuxcnc-ethercat
make configure
make
sudo make install

Test linuxcnc with Ethercat

  1. Run linuxcnc
  2. Select sim→axis→axis, copy the files. Axis should start. Exit axis.
  3. go to the config folder cd linuxcnc/configs/sim.axis
  4. Edit an ini file of your choice and add to the [HAL] section HALFILE = ethercat.hal
  5. Create an ethercat.hal with this content
loadusr -W lcec_conf ethercat-conf.xml
loadrt lcec
addf lcec.read-all servo-thread
addf lcec.write-all servo-thread
  1. Create an ethercat-conf.xml with this content
<masters>
<master idx="0" appTimePeriod="1000000" refClockSyncCycles="5">
</master>
</masters>
  1. Start linux cnc and load the ini file you've just edited linuxcnc <yourinifile>.ini
  2. Test if an output for examle, works as expected
halcmd setp lcec.0.2.dout-7 1
# This will switch on the output 8 on the module No. 2, EL2008 in this example. 
halcmd setp lcec.0.<module-no>.dout-<output-no> <state>
# The physical hardware is needed for this, of course.

cia402

Hakan adapted the hal-cia402 files from @dbraun1981 https://github.com/dbraun1981/hal-cia402

  1. clone the repo git clone https://github.com/dbraun1981/hal-cia402.git
  2. cd into the repo cd hal-cia402
  3. Compile and install it: sudo halcompile --install cia402.comp

Servo drives

His lathe2-nopid.hal

# Generated by PNCconf at Sat Sep 10 10:10:56 2016
# If you make changes to this file, they will be
# overwritten when you run PNCconf again

loadrt [KINS]KINEMATICS
#autoconverted  trivkins
loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
loadusr -W lcec_conf ethercat-conf.xml
loadrt lcec
loadrt cia402 count=2

addf lcec.read-all            servo-thread
addf cia402.0.read-all        servo-thread
addf cia402.1.read-all        servo-thread
addf motion-command-handler   servo-thread
addf motion-controller        servo-thread
addf cia402.0.write-all       servo-thread
addf cia402.1.write-all       servo-thread
addf lcec.write-all           servo-thread

#*******************
#  AXIS X
#*******************

# --- joint signals for motion

net x-pos-cmd    <= joint.0.motor-pos-cmd
net x-vel-cmd    <= joint.0.vel-cmd
net x-pos-fb     <= joint.0.motor-pos-fb
net x-enable     <= joint.0.amp-enable-out

# --- connect stepper driver to joint

net x-pos-cmd    => cia402.0.pos-cmd
net x-pos-fb     => cia402.0.pos-fb
net x-enable     => cia402.0.enable

# --- ect60 settings

setp cia402.0.csp-mode 1
setp cia402.0.pos-scale 4000

# --- from stepper(ethercat) to cia402

net x-statusword      lcec.0.4.cia-statusword  => cia402.0.statusword
net x-opmode-display  lcec.0.4.opmode-display  => cia402.0.opmode-display
net x-drv-act-pos     lcec.0.4.actual-position => cia402.0.drv-actual-position
net x-drv-act-velo    lcec.0.4.actual-velocity => cia402.0.drv-actual-velocity

# --- from cia402 to stepper(ethercat) 

net x-controlword         cia402.0.controlword         => lcec.0.4.cia-controlword
net x-modes-of-operation  cia402.0.opmode              => lcec.0.4.opmode
net x-drv-target-pos      cia402.0.drv-target-position => lcec.0.4.target-position
net x-drv-target-velo     cia402.0.drv-target-velocity => lcec.0.4.target-velocity

#*******************
#  AXIS Z
#*******************

# --- joint signals for motion

net z-pos-cmd    <= joint.1.motor-pos-cmd
net z-vel-cmd    <= joint.1.vel-cmd
net z-pos-fb     <= joint.1.motor-pos-fb
net z-enable     <= joint.1.amp-enable-out

# --- connect stepper driver to the joint

net z-pos-cmd    => cia402.1.pos-cmd
net z-pos-fb     => cia402.1.pos-fb
net z-enable     => cia402.1.enable

# --- ect60 settings

setp cia402.1.csp-mode 1
setp cia402.1.pos-scale 10000

# --- from servo(ethercat) to cia402

net z-statusword      lcec.0.5.cia-statusword  => cia402.1.statusword
net z-opmode-display  lcec.0.5.opmode-display  => cia402.1.opmode-display
net z-drv-act-pos     lcec.0.5.actual-position => cia402.1.drv-actual-position
net z-drv-act-velo    lcec.0.5.actual-velocity => cia402.1.drv-actual-velocity

# --- from cia402 to servo(ethercat) 

net z-controlword         cia402.1.controlword         => lcec.0.5.cia-controlword
net z-modes-of-operation  cia402.1.opmode              => lcec.0.5.opmode
net z-drv-target-pos      cia402.1.drv-target-position => lcec.0.5.target-position
net z-drv-target-velo     cia402.1.drv-target-velocity => lcec.0.5.target-velocity

#*********************
#   E-STOP
#*********************

setp iocontrol.0.emc-enable-in 1

His ethercat-conf.xml



<?xml version="1.0" encoding="UTF-8"?>
<masters>
   <master idx="0" appTimePeriod="1000000" refClockSyncCycles="5">
      <slave idx="0" type="EK1100" />
      <slave idx="1" type="EL1008" />
      <slave idx="2" type="EL2008" />
      <slave idx="3" type="EL5101" />
      <slave idx="4" type="generic" vid="00000a88" pid="0A880002" configPdos="true">
         <dcConf assignActivate="300" sync0Cycle="*1" sync0Shift="0" />
         <sdoConfig idx="2000" subIdx="0">
            <sdoDataRaw data="70 17" />
         </sdoConfig>
         <!-- Max motor current (6.0) -->
         <sdoConfig idx="2011" subIdx="0">
            <sdoDataRaw data="01 00" />
         </sdoConfig>
         <!-- Closed loop -->
         <syncManager idx="2" dir="out">
            <pdo idx="1600">
               <pdoEntry idx="6040" subIdx="00" bitLen="16" halPin="cia-controlword" halType="u32" />
               <pdoEntry idx="6060" subIdx="00" bitLen="8" halPin="opmode" halType="s32" />
               <pdoEntry idx="607A" subIdx="00" bitLen="32" halPin="target-position" halType="s32" />
               <pdoEntry idx="60FF" subIdx="00" bitLen="32" halPin="target-velocity" halType="s32" />
            </pdo>
         </syncManager>
         <syncManager idx="3" dir="in">
            <pdo idx="1a00">
               <pdoEntry idx="6041" subIdx="00" bitLen="16" halPin="cia-statusword" halType="u32" />
               <pdoEntry idx="6061" subIdx="00" bitLen="8" halPin="opmode-display" halType="s32" />
               <pdoEntry idx="6064" subIdx="00" bitLen="32" halPin="actual-position" halType="s32" />
               <pdoEntry idx="606C" subIdx="00" bitLen="32" halPin="actual-velocity" halType="s32" />
               <pdoEntry idx="6077" subIdx="00" bitLen="32" halPin="actual-torque" halType="s32" />
            </pdo>
         </syncManager>
      </slave>
      <slave idx="5" type="generic" vid="00000a88" pid="0A880002" configPdos="true">
         <dcConf assignActivate="300" sync0Cycle="*1" sync0Shift="0" />
         <sdoConfig idx="2000" subIdx="0">
            <sdoDataRaw data="DC 05" />
         </sdoConfig>
         <!-- Max motor current (1.5) -->
         <sdoConfig idx="2011" subIdx="0">
            <sdoDataRaw data="00 00" />
         </sdoConfig>
         <!-- Open loop -->
         <syncManager idx="2" dir="out">
            <pdo idx="1600">
               <pdoEntry idx="6040" subIdx="00" bitLen="16" halPin="cia-controlword" halType="u32" />
               <pdoEntry idx="6060" subIdx="00" bitLen="8" halPin="opmode" halType="s32" />
               <pdoEntry idx="607A" subIdx="00" bitLen="32" halPin="target-position" halType="s32" />
               <pdoEntry idx="60FF" subIdx="00" bitLen="32" halPin="target-velocity" halType="s32" />
            </pdo>
         </syncManager>
         <syncManager idx="3" dir="in">
            <pdo idx="1a00">
               <pdoEntry idx="6041" subIdx="00" bitLen="16" halPin="cia-statusword" halType="u32" />
               <pdoEntry idx="6061" subIdx="00" bitLen="8" halPin="opmode-display" halType="s32" />
               <pdoEntry idx="6064" subIdx="00" bitLen="32" halPin="actual-position" halType="s32" />
               <pdoEntry idx="606C" subIdx="00" bitLen="32" halPin="actual-velocity" halType="s32" />
               <pdoEntry idx="6077" subIdx="00" bitLen="32" halPin="actual-torque" halType="s32" />
            </pdo>
         </syncManager>
      </slave>
   </master>
</masters>

and his lathe.ini

[EMC]
VERSION = 1.1
MACHINE = LinuxCNC-HAL-SIM-LATHE
  DEBUG = 0

[DISPLAY]
             DISPLAY = axis
               LATHE = 1
     BACK_TOOL_LATHE = 1
          CYCLE_TIME = 0.100
     POSITION_OFFSET = RELATIVE
   POSITION_FEEDBACK = ACTUAL
   MAX_FEED_OVERRIDE = 1.2
MAX_SPINDLE_OVERRIDE = 1.0
      PROGRAM_PREFIX = ../../nc_files/
       INTRO_GRAPHIC = linuxcnc.gif
          INTRO_TIME = 1
          INCREMENTS = 5mm 1mm .5mm .1mm .05mm .01mm .005mm

[FILTER]
PROGRAM_EXTENSION = .png,.gif,.jpg Grayscale Depth Image
PROGRAM_EXTENSION = .py Python Script
              png = image-to-gcode
              gif = image-to-gcode
              jpg = image-to-gcode
               py = python

[RS274NGC]
PARAMETER_FILE = ethercat-lathe.var

[EMCMOT]
      EMCMOT = motmod
COMM_TIMEOUT = 1.0
 BASE_PERIOD = 50000
SERVO_PERIOD = 1000000

[TASK]
      TASK = milltask
CYCLE_TIME = 0.001

[HAL]
          HALUI = halui
        HALFILE = lathe2-nopid.hal

[TRAJ]
         COORDINATES = XZ
        LINEAR_UNITS = mm
       ANGULAR_UNITS = degree
DEFAULT_LINEAR_VELOCITY = 100
MAX_LINEAR_VELOCITY = 12.0
DEFAULT_LINEAR_ACCELERATION = 20.0
MAX_LINEAR_ACCELERATION = 500.0

[EMCIO]
                      EMCIO = io
                 CYCLE_TIME = 0.100
                 TOOL_TABLE = lathe.tbl
       TOOL_CHANGE_POSITION = 2 0 1
TOOL_CHANGE_WITH_SPINDLE_ON = 1

[KINS]
        KINEMATICS = trivkins coordinates=xz
            JOINTS = 2

[AXIS_X]
         MIN_LIMIT = -1000.0
         MAX_LIMIT = 1000.0
      MAX_VELOCITY = 12
  MAX_ACCELERATION = 500.0

[JOINT_0]
              TYPE = LINEAR
            FERROR = 1.0
        MIN_FERROR = 0.9
      MAX_VELOCITY = 12.0
  MAX_ACCELERATION = 500.0
         MIN_LIMIT = -1000.0
         MAX_LIMIT = 1000.0
   HOME_SEARCH_VEL = 0.0
    HOME_LATCH_VEL = 0.0
     HOME_SEQUENCE = 0
    HOME_USE_INDEX = NO

[AXIS_Z]
       MIN_LIMIT = -1000.0
       MAX_LIMIT = 1000.0
    MAX_VELOCITY = 12
MAX_ACCELERATION = 500.0

[JOINT_1]
              TYPE = LINEAR
            FERROR = 1.0
        MIN_FERROR = 0.9
      MAX_VELOCITY = 12.0
  MAX_ACCELERATION = 500.0
         MIN_LIMIT = -1000.0
         MAX_LIMIT = 1000.0
   HOME_SEARCH_VEL = 0.0
    HOME_LATCH_VEL = 0.0
     HOME_SEQUENCE = 0
    HOME_USE_INDEX = NO

Notes

Roshi's Tutorial on how to setup the ethercat-conf.xml: https://docs.google.com/document/d/1GiB065ZIAaoMHPtVfTg9JV1Kn-19xGQl2X9DM9-THNM/edit#heading=h.37frqspzljja

thehade's post with a complete slave xml description

https://forum.linuxcnc.org/24-hal-components/22346-ethercat-hal-driver?start=920#170228

Nico2017 post on how to install Linuxcnc + Ethercat on a plain debian

https://forum.linuxcnc.org/27-driver-boards/35591-beckhoff-ethercat-64-with-bit-linuxcnc-how-to-install?start=30#135811

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment