CNC Router: Controls II


Part 1: CNC Router: Controls I

LinuxCNC Configuration

LinuxCNC has pretty comprehensive documentation. Unfortunately, linuxcnc-ethercat does not. After skimming through the handful of EtherCAT threads on the LinuxCNC forum, and poring over others’ EtherCAT configuration files I was finally able to wrap my head around how they relate together. Even better, managed to put together a configuration to test a single axis.

The initialization file (INI Config – linuxcnc.org) tells LinuxCNC the name and locations of the hardware abstraction layer configuration files (HAL Introduction – linuxcnc.org) and the EtherCAT configuration file. The rest of the parameters that are defined in the initialization file are used to configure the user interface and some are referenced by the hardware abstraction layer files. The EtherCAT configuration file defines the mapping of registers to HAL pins.

Single Axis Testing in LinuxCNC

Single axis configuration files on github.

Initialization File

Since the steppers aren’t connected to anything while testing, key values that have to do with limits, velocities, accelerations, etc. don’t matter at the moment.

# ECT60.ini
[LCEC]
CONFIG = ECT60.xml

[APPLICATIONS]
# delay because some items are done in postgui
# DELAY = 5
# APP = halscope -i dynamic_offsets.halscope

[HAL]
HALUI = halui
HALFILE = ECT60.hal

POSTGUI_HALFILE = postgui.hal

[EMC]
MACHINE = LinuxCNC
VERSION = 1.1

[DISPLAY]
DISPLAY = axis
EDITOR = gedit
POSITION_OFFSET = RELATIVE
POSITION_FEEDBACK = ACTUAL
ARCDIVISION = 64
GRIDS = 10mm 20mm 50mm 100mm 1in 2in 5in 10in
MAX_FEED_OVERRIDE = 1.2
MIN_SPINDLE_OVERRIDE = 0.5
MAX_SPINDLE_OVERRIDE = 1.2
DEFAULT_LINEAR_VELOCITY = 2.50
MIN_LINEAR_VELOCITY = 0
MAX_LINEAR_VELOCITY = 25.00
INTRO_GRAPHIC = linuxcnc.gif
INTRO_TIME = 5
PROGRAM_PREFIX = /home/linuxcnc/linuxcnc/nc_files
INCREMENTS = 5mm 1mm .5mm .1mm .05mm .01mm .005mm

[TASK]
TASK = milltask
CYCLE_TIME = 0.001

[RS274NGC]
# USER_M_PATH = .
PARAMETER_FILE = sim.var
# FEATURES = 8

[EMCIO]
EMCIO = io
CYCLE_TIME = 0.100
# TOOLTABLE = tool.tbl

[EMCMOT]
EMCMOT = motmod
COMM_TIMEOUT = 1.0
BASE_PERIOD = 45000
SERVO_PERIOD = 990000

[MACROS]
MACRO = M300

[TRAJ]
AXES = 3
COORDINATES = XYZ
LINEAR_UNITS = mm
ANGULAR_UNITS = degree
DEFAULT_LINEAR_VELOCITY = 2.50
MAX_LINEAR_VELOCITY = 5.00

[KINS]
JOINTS = 3
KINEMATICS = trivkins coordinates=XYZ

[AXIS_X]
MIN_LIMIT = -1000
MAX_LIMIT = 1000
MAX_VELOCITY = 275
MAX_ACCELERATION = 325

[JOINT_0]
TYPE = LINEAR
HOME = 0.0
MAX_VELOCITY = 275
MAX_ACCELERATION = 325
# FERROR = 1
# MIN_FERROR = .25
MIN_LIMIT = -1000
MAX_LIMIT = 1000

[AXIS_Y]
MIN_LIMIT = -1000
MAX_LIMIT = 1000
MAX_VELOCITY = 275
MAX_ACCELERATION = 325

[JOINT_1]
TYPE = LINEAR
HOME = 0.0
MAX_VELOCITY = 275
MAX_ACCELERATION = 325
# FERROR = 1
# MIN_FERROR = .25
MIN_LIMIT = -1000
MAX_LIMIT = 1000

[AXIS_Z]
MIN_LIMIT = -1000
MAX_LIMIT = 1000
MAX_VELOCITY = 275
MAX_ACCELERATION = 325

[JOINT_2]
TYPE = LINEAR
HOME = 0.0
MAX_VELOCITY = 275
MAX_ACCELERATION = 325
# FERROR = 1
# MIN_FERROR = .25
MIN_LIMIT = -1000
MAX_LIMIT = 1000

Hardware Abstraction Layer File

# ECT60.hal
loadusr -W lcec_conf [LCEC]CONFIG
loadrt lcec

loadrt [KINS]KINEMATICS
loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS 

loadrt scale
loadrt conv_s32_float
loadrt conv_float_s32

addf lcec.read-all servo-thread
addf lcec.write-all servo-thread

addf motion-command-handler servo-thread
addf motion-controller servo-thread   

# X-AXIS #######################################################
# write d8 to h6060 to use CSP mode
setp lcec.0.0.opmode-3 true

# Enable operation
setp lcec.0.0.X-cmd-SwitchOn 1
setp lcec.0.0.X-cmd-EnableVoltage 1
setp lcec.0.0.X-cmd-QuickStop 1
setp lcec.0.0.X-cmd-EnableOperation 1

net Xaxis_fb lcec.0.0.actpos => joint.0.motor-pos-fb
net Xaxis_cmd joint.0.motor-pos-cmd => lcec.0.0.poscmd

# simulate y&z
net Yaxis_cmd joint.1.motor-pos-cmd => joint.1.motor-pos-fb
net Zaxis_cmd joint.2.motor-pos-cmd => joint.2.motor-pos-fb

# estop loopback
net estop-loop iocontrol.0.user-enable-out iocontrol.0.emc-enable-in

Post GUI HAL File

# postgui.hal
# setp lcec.0.0.X-cmd-OPmodeRel1 1
setp joint.0.jog-enable 1

Ethercat Configuration File

<masters>
  <master idx="0" appTimePeriod="990000" refClockSyncCycles="1000">
    <slave idx="0" type="generic" vid="00000A88" pid="0a880002" configPdos="true">
      <dcConf assignActivate="300" sync0Cycle="*1" sync0Shift="0"/>
      <syncManager idx="0" dir="out">
      </syncManager>
      <syncManager idx="1" dir="in">
      </syncManager>
      <syncManager idx="2" dir="out">
        <pdo idx="1600">
          <pdoEntry idx="6040" subIdx="00" bitLen="16" halType="complex">
            <complexEntry bitLen="1" halPin="X-cmd-SwitchOn" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-cmd-EnableVoltage" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-cmd-QuickStop" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-cmd-EnableOperation" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-cmd-OPmodeRel1" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-cmd-OPmodeRel2" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-cmd-OPmodeRel3" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-cmd-FaultReset" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-TimeOut" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-cmd-OPmodeRel4" halType="bit"/>
	    <complexEntry bitLen="6"/>
          </pdoEntry>
          <pdoEntry idx="6060" subIdx="00" bitLen="8" halPin="opmode" halType="bit"/>
          <pdoEntry idx="607A" subIdx="00" bitLen="32" halPin="poscmd" halType="float" scale="1000"/>
        </pdo>
      </syncManager>
      <syncManager idx="3" dir="in">
        <pdo idx="1a00">
          <pdoEntry idx="6041" subIdx="00" bitLen="16" halType="complex">
            <complexEntry bitLen="1" halPin="X-stat-ReadyToSwitchOn" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-stat-SwitchOn" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-stat-OperationEnable" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-stat-Fault" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-stat-VoltageEnabled" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-stat-QuickStop" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-stat-SwitchOnDisable" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-stat-Warning" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-stat-Keep" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-stat-Remote" halType="bit"/>
            <complexEntry bitLen="1" halPin="X-stat-TargetIsReached" halType="bit"/>
	    <complexEntry bitLen="5"/>
          </pdoEntry>  
          <pdoEntry idx="6061" subIdx="00" bitLen="8" halPin="opmode_fb" halType="bit"/>
          <pdoEntry idx="6064" subIdx="00" bitLen="32" halPin="actpos" halType="float" scale="0.001"/>
          <pdoEntry idx="60FD" subIdx="00" bitLen="32" halPin="digital_inputs" halType="bit"/>
        </pdo>
      </syncManager>
    </slave>
  </master>
</masters>
Keep your eye on the right stepper motor’s motion.

All Axes Testing in LinuxCNC

Moving from single axis testing to multiple axis testing was straightforward with a few tweaks to each configuration file. github

The first stepper on the left is the Z axis, the second is the Y axis and the two on the far right are the X axis. The test configurations on github have been changed to the more common XYYZ setup.