I have access to a lot of EtherCat components, among them the brand new OMRON 1S series servo drives. Obviously I wanted to get them working in LinuxCNC but there were no drivers for them.
There were drivers for the OMRON G5 series drives however. So I compared the PDOs used in that driver with the PDOs of the 1S series.
Turns out they are identical 🤓
I cloned the git repo of linuxcnc-ethercat and began to tinker around.
I created a copy of the driver, named it omr1s.c
. Then I replaced all the omrg5
stuff with omr1s
and set the correct encoder resolution at the top of the file.
Also all the
drive models and their PID
had to be correct, but that was an easy task with the help of the
esi-data
website, also created by
@scottlaird
who is the driving force behind linuxcnc-ethercat.
A simple sudo make install
was enough to have the modified version in place.
I also had to create a correct ethercat-conf.xml
:
1<masters>
2 <master idx="0" appTimePeriod="1000000" refClockSyncCycles="-1" name="master0">
3 <slave idx="0" type="EK1110" />
4 <slave idx="1" type="R88D-1SN01H-ECT" name="x-servo">
5 <dcConf assignActivate="300" sync0Cycle="*1" sync0Shift="0"/>
6 <watchdog divider="2498" intervals="1000"/>
7 </slave>
8 <slave idx="2" type="R88D-1SN01H-ECT" name="y-servo">
9 <dcConf assignActivate="300" sync0Cycle="*1" sync0Shift="0"/>
10 <watchdog divider="2498" intervals="1000"/>
11 </slave>
12 <slave idx="3" type="R88D-1SN01H-ECT" name="z-servo">
13 <dcConf assignActivate="300" sync0Cycle="*1" sync0Shift="0"/>
14 <watchdog divider="2498" intervals="1000"/>
15 </slave>
16 </master>
17 </masters>
Along with a ethercat.hal file
# vi: ft=linuxcnc-hal
loadrt [KINS]KINEMATICS
loadrt [EMCMOT]EMCMOT servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
loadusr -W lcec_conf ethercat-conf.xml
loadrt lcec
addf lcec.read-all servo-thread
addf motion-command-handler servo-thread
addf motion-controller servo-thread
addf lcec.write-all servo-thread
net emc-enable => iocontrol.0.emc-enable-in
sets emc-enable 1
##*******************
## AXIS X
##*******************
net x-enable <= joint.0.amp-enable-out => lcec.master0.x-servo.enable
net x-amp-fault => joint.0.amp-fault-in <= lcec.master0.x-servo.fault
net x-pos-cmd <= joint.0.motor-pos-cmd => lcec.master0.x-servo.pos-cmd
net x-pos-fb => joint.0.motor-pos-fb <= lcec.master0.x-servo.pos-fb
##*******************
## AXIS Y
##*******************
net y-enable <= joint.1.amp-enable-out => lcec.master0.y-servo.enable
net y-amp-fault => joint.1.amp-fault-in <= lcec.master0.y-servo.fault
net y-pos-cmd <= joint.1.motor-pos-cmd => lcec.master0.y-servo.pos-cmd
net y-pos-fb => joint.1.motor-pos-fb <= lcec.master0.y-servo.pos-fb
##*******************
## AXIS Z
##*******************
net z-enable <= joint.2.amp-enable-out => lcec.master0.z-servo.enable
net z-amp-fault => joint.2.amp-fault-in <= lcec.master0.z-servo.fault
net z-pos-cmd <= joint.2.motor-pos-cmd => lcec.master0.z-servo.pos-cmd
net z-pos-fb => joint.2.motor-pos-fb <= lcec.master0.z-servo.pos-fb
Finally the .ini file
1[EMC]
2VERSION = 1.0
3MACHINE = Omron 1S test setup
4DEBUG = 0
5
6[DISPLAY]
7DISPLAY = axis
8CYCLE_TIME = 0.100
9HELP_FILE = doc/help.txt
10POSITION_OFFSET = RELATIVE
11POSITION_FEEDBACK = ACTUAL
12MAX_FEED_OVERRIDE = 1.2
13MAX_SPINDLE_OVERRIDE = 1.0
14MAX_LINEAR_VELOCITY = 25
15DEFAULT_LINEAR_VELOCITY = 1
16DEFAULT_SPINDLE_SPEED = 200
17PROGRAM_PREFIX = /home/user/linuxcnc/nc_files
18
19[FILTER]
20PROGRAM_EXTENSION = .png,.gif,.jpg Grayscale Depth Image
21PROGRAM_EXTENSION = .py Python Script
22
23png = image-to-gcode
24gif = image-to-gcode
25jpg = image-to-gcode
26py = python3
27
28[TASK]
29TASK = milltask
30CYCLE_TIME = 0.001
31
32[RS274NGC]
33PARAMETER_FILE = sim.var
34
35[EMCMOT]
36EMCMOT = motmod
37COMM_TIMEOUT = 1.0
38BASE_PERIOD = 0
39SERVO_PERIOD = 1000000
40
41[EMCIO]
42EMCIO = io
43CYCLE_TIME = 0.100
44TOOL_TABLE = sim.tbl
45TOOL_CHANGE_POSITION = 0 0 0
46TOOL_CHANGE_QUILL_UP = 1
47
48[HAL]
49HALFILE = ethercat.hal
50HALUI = halui
51
52[TRAJ]
53COORDINATES = X Y Z
54LINEAR_UNITS = mm
55ANGULAR_UNITS = degree
56MAX_LINEAR_VELOCITY = 4
57POSITION_FILE = position.txt
58NO_FORCE_HOMING = 1
59
60[KINS]
61KINEMATICS = trivkins
62JOINTS = 3
63
64[AXIS_X]
65MAX_VELOCITY = 1000
66MAX_ACCELERATION = 10000.0
67
68[AXIS_Y]
69MAX_VELOCITY = 1000
70MAX_ACCELERATION = 10000.0
71
72[AXIS_Z]
73MAX_VELOCITY = 1000
74MAX_ACCELERATION = 10000.0
75
76[JOINT_0]
77TYPE = LINEAR
78MAX_VELOCITY = 1000
79MAX_ACCELERATION = 10000.0
80SCALE = 8388608
81HOME_ABSOLUTE_ENCODER = 2
82
83[JOINT_1]
84TYPE = LINEAR
85MAX_VELOCITY = 1000
86MAX_ACCELERATION = 10000.0
87SCALE = 8388608
88HOME_ABSOLUTE_ENCODER = 2
89
90[JOINT_2]
91TYPE = LINEAR
92MAX_VELOCITY = 1000
93MAX_ACCELERATION = 10000.0
94SCALE = 8388608
95HOME_ABSOLUTE_ENCODER = 2
This config, especially the .ini file is far from production ready, but it allows me to move all 3 axis.
I opened a pull-request and Scott quickly merged it. It is not yet release but will be in the next release.
I’m still in the process of experimenting with the absolute encoders that don’t require a battery, which is a absolutely cool feature.
Here is a short video showing the drives in actions: