Hello
In my most recent project, I'm having trouble getting my ethercat joints to work.
Not exactly the rarest of problems, I know, but bear with me.
To illustrate the problem, lets look at the contents of the control and status registers, and then compare with the hal values driving/driven by them. You can see that:
lcec.0.hip.control* pins are non-zero, but the control register is zero.
Conversely, status register is non-zero, but lcec.0.hip.status* are zero.
This can't be right.
Code:
reid@charles1:~/linuxcnc-dev/configs/b3pr$ ethercat -p0 -t uint16 upload 0x6040 0 # control register
0x0000 0
reid@charles1:~/linuxcnc-dev/configs/b3pr$ ethercat -p0 -t uint16 upload 0x6041 0 # status register
0x0650 1616
reid@charles1:~/linuxcnc-dev/configs/b3pr$ halcmd show pin lcec
Component Pins:
Owner Type Dir Value Name
43 bit OUT FALSE lcec.0.all-op
43 bit IN TRUE lcec.0.hip.control-0 <== lcec.j1.control.switch-on
43 bit IN TRUE lcec.0.hip.control-1 <== lcec.j1.control.enable-voltage
43 bit IN FALSE lcec.0.hip.control-10
43 bit IN FALSE lcec.0.hip.control-11
43 bit IN FALSE lcec.0.hip.control-12
43 bit IN FALSE lcec.0.hip.control-13
43 bit IN FALSE lcec.0.hip.control-14
43 bit IN FALSE lcec.0.hip.control-15
43 bit IN TRUE lcec.0.hip.control-2 <== lcec.j1.control.quick-stop
43 bit IN FALSE lcec.0.hip.control-3 <== motion-enable
43 bit IN FALSE lcec.0.hip.control-4
43 bit IN FALSE lcec.0.hip.control-5
43 bit IN FALSE lcec.0.hip.control-6
43 bit IN FALSE lcec.0.hip.control-7 <== lcec.j1.control.fault-reset
43 bit IN FALSE lcec.0.hip.control-8
43 bit IN FALSE lcec.0.hip.control-9
43 s32 OUT 0 lcec.0.hip.pos-act ==> pos-fb-s32.j1
43 s32 IN 0 lcec.0.hip.pos-cmd <== pos-cmd-s32.j1
43 bit OUT FALSE lcec.0.hip.slave-online
43 bit OUT FALSE lcec.0.hip.slave-oper
43 bit OUT FALSE lcec.0.hip.slave-state-init
43 bit OUT FALSE lcec.0.hip.slave-state-op
43 bit OUT FALSE lcec.0.hip.slave-state-preop
43 bit OUT FALSE lcec.0.hip.slave-state-safeop
43 bit OUT FALSE lcec.0.hip.status-0
43 bit OUT FALSE lcec.0.hip.status-1
43 bit OUT FALSE lcec.0.hip.status-10
43 bit OUT FALSE lcec.0.hip.status-11
43 bit OUT FALSE lcec.0.hip.status-12
43 bit OUT FALSE lcec.0.hip.status-13
43 bit OUT FALSE lcec.0.hip.status-14
43 bit OUT FALSE lcec.0.hip.status-15
43 bit OUT FALSE lcec.0.hip.status-2
43 bit OUT FALSE lcec.0.hip.status-3
43 bit OUT FALSE lcec.0.hip.status-4
43 bit OUT FALSE lcec.0.hip.status-5
43 bit OUT FALSE lcec.0.hip.status-6
43 bit OUT FALSE lcec.0.hip.status-7
43 bit OUT FALSE lcec.0.hip.status-8
43 bit OUT FALSE lcec.0.hip.status-9
43 s32 OUT 0 lcec.0.hip.torq-act
43 s32 IN 0 lcec.0.hip.torq-offset
43 bit OUT TRUE lcec.0.link-up
43 s32 OUT 0 lcec.0.read.time
43 u32 OUT 0x00000001 lcec.0.slaves-responding
43 bit OUT FALSE lcec.0.state-init
43 bit OUT FALSE lcec.0.state-op
43 bit OUT TRUE lcec.0.state-preop
43 bit OUT FALSE lcec.0.state-safeop
43 s32 OUT 0 lcec.0.write.time
43 bit OUT FALSE lcec.all-op
40 u32 OUT 0x00000001 lcec.conf.master-count
40 u32 OUT 0x00000001 lcec.conf.slave-count
43 bit OUT TRUE lcec.link-up
43 s32 OUT 17506 lcec.read-all.time
43 u32 OUT 0x00000001 lcec.slaves-responding
43 bit OUT FALSE lcec.state-init
43 bit OUT FALSE lcec.state-op
43 bit OUT TRUE lcec.state-preop
43 bit OUT FALSE lcec.state-safeop
43 s32 OUT 29960 lcec.write-all.time
reid@charles1:~/linuxcnc-dev/configs/b3pr$ ethercat slaves
0 0:0 PREOP E ESTUN ProNet
Let me back up.
My OS is from the 2.8.4 iso. My latency and jitter are good.
I compile linuxcnc from source.
uname -a gives:
Linux charles1 4.19.0-24-rt-amd64 #1 SMP PREEMPT RT Debian 4.19.282-1 (2023-04-29) x86_64 GNU/Linux
My Estun Pronet 04AEA-EC drives worked well in a previous lcec project, using the same hardware (WS, dedicated ethernet card, mesa card, etc) as I use now.
At that time, I built the etherCat master from source, and wrote a custom driver for my Estun servos.
This time around, I installed the Master from packages, using rodw's step-by-step on this forum, but I'm trying to use the generic driver, because I lost my old driver code in a catastrophe.
My cabling seems to be OK. Using the front-panel controls, I can jog the motors.
I can also use the ethercat command to apply a sequence of values to the control register, traversing the state machine into the enabled state, with the motor 'locked' on or off.
Here is a fragment of my hal file:
Code:
loadrt [KINS]KINEMATICS
loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
loadusr -W lcec_conf b3pr_ethercat.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
Here is my xml:
Code:
<masters>
<master idx="0" appTimePeriod="1000000" refClockSyncCycles="1000">
<slave idx="0" type="generic" vid="1546" configPdos="true" name="hip">
<dcConf assignActivate="300" sync0Cycle="*1" sync0Shift="0"/>
<syncManager idx="0" dir="out"/>
<syncManager idx="1" dir="in"/>
<syncManager idx="2" dir="out">
<pdo idx="1602">
<pdoEntry idx="6040" subIdx="00" bitLen="16" halPin="control" halType="bit"/>
<pdoEntry idx="607A" subIdx="00" bitLen="32" halPin="pos-cmd" halType="s32"/>
<pdoEntry idx="60B2" subIdx="00" bitLen="16" halPin="torq-offset" halType="s32"/>
</pdo>
</syncManager>
<syncManager idx="3" dir="in">
<pdo idx="1A02">
<pdoEntry idx="6041" subIdx="00" bitLen="16" halPin="status" halType="bit"/>
<pdoEntry idx="6064" subIdx="00" bitLen="32" halPin="pos-act" halType="S32"/>
<pdoEntry idx="6077" subIdx="00" bitLen="16" halPin="torq-act" halType="S32"/>
</pdo>
</syncManager>
</slave>
</master>
</masters>
I use shell commands to configure my drive's PDOs before starting linuxcnc:
Code:
#!/bin/bash
# this script configures PDO mapping for a Pronet drive using ethercat commands.
# Based on akd_free_pdo.sh from Sebastien BLANCHET on the linuxcnc ethercat forum. Should be in ~/Downloads.
# See "PDO mapping process" on p12 of Estun ethercat manual.
POS=-p0 # joint 1 'hip'
# clear RxPDO
ethercat $POS --type uint8 download 0x1C12 0 0 # clear RxPDO counter
ethercat $POS --type uint8 download 0x1600 0 0 # clear RxPDO0
ethercat $POS --type uint8 download 0x1601 0 0 # clear RxPDO1
ethercat $POS --type uint8 download 0x1602 0 0 # clear RxPDO2
ethercat $POS --type uint8 download 0x1603 0 0 # clear RxPDO3
# define RxPdo
ethercat $POS --type uint32 download 0x1602 1 0x60400010 # control word (index+subindex+bitlength)
ethercat $POS --type uint32 download 0x1602 2 0x607A0020 # pos-cmd
ethercat $POS --type uint32 download 0x1602 3 0x60B20010 # torque-offset
ethercat $POS --type uint8 download 0x1602 0 3 # number of var in this PDO
ethercat $POS --type uint16 download 0x1C12 1 0x1602 # list RxPdo
ethercat $POS --type uint8 download 0x1C12 0 1 # number of RxPdo
#---------------------------------------
# clear TxPdo
ethercat $POS --type uint8 download 0x1C13 0 0 # clear TxPDO counter
ethercat $POS --type uint8 download 0x1A00 0 0 # clear TxPDO0
ethercat $POS --type uint8 download 0x1A01 0 0 # clear TxPDO1
ethercat $POS --type uint8 download 0x1A02 0 0 # clear TxPDO2
ethercat $POS --type uint8 download 0x1A03 0 0 # clear TxPDO3
# define TxPdo
ethercat $POS --type uint32 download 0x1A02 1 0x60410010 # status word (index+subindex+bitlength)
ethercat $POS --type uint32 download 0x1A02 2 0x60640020 # pos-act
ethercat $POS --type uint32 download 0x1A02 3 0x60770010 # torque-actual
ethercat $POS --type uint8 download 0x1A02 0 3 # number of var in this PDO
ethercat $POS --type uint16 download 0x1C13 1 0x1A02 # list TxPdo
ethercat $POS --type uint8 download 0x1C13 0 1 # number of TxPdo
ethercat rescan
sleep 5
ethercat cstruct $POS
#---------------------------------------
# reset fault
ethercat $POS -t uint16 download 0x6040 0 0x0080 # rising edge
ethercat $POS -t uint16 download 0x6040 0 0x0000
# mode-of-operation 8=CSV
ethercat $POS --type uint8 download 0x6060 0 8
# velocity-offset = 0
ethercat $POS --type int32 download 0x60B1 0 0
# quick-stop-option-code = 0: motor stops freely
ethercat $POS --type uint16 download 0x605A 0 0
echo " STATUS word: `ethercat $POS -t uint16 upload 0x6041 0 `"
After configuring my drive, my slave 'looks right' to me:
Code:
reid@charles1:~/linuxcnc-dev/configs/b3pr$ ethercat slaves
0 0:0 PREOP + ESTUN ProNet
reid@charles1:~/linuxcnc-dev/configs/b3pr$ ethercat cstruct
/* Master 0, Slave 0, "ESTUN ProNet"
* Vendor ID: 0x0000060a
* Product code: 0x00000001
* Revision number: 0x00000001
*/
ec_pdo_entry_info_t slave_0_pdo_entries[] = {
{0x6040, 0x00, 16},
{0x607a, 0x00, 32},
{0x60b2, 0x00, 16},
{0x6041, 0x00, 16},
{0x6064, 0x00, 32},
{0x6077, 0x00, 16},
};
ec_pdo_info_t slave_0_pdos[] = {
{0x1602, 3, slave_0_pdo_entries + 0},
{0x1a02, 3, slave_0_pdo_entries + 3},
};
ec_sync_info_t slave_0_syncs[] = {
{0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},
{1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},
{2, EC_DIR_OUTPUT, 1, slave_0_pdos + 0, EC_WD_ENABLE},
{3, EC_DIR_INPUT, 1, slave_0_pdos + 1, EC_WD_DISABLE},
{0xff}
};
reid@charles1:~/linuxcnc-dev/configs/b3pr$ ethercat pdos
SM0: PhysAddr 0x1000, DefaultSize 128, ControlRegister 0x36, Enable 1
SM1: PhysAddr 0x1080, DefaultSize 128, ControlRegister 0x32, Enable 1
SM2: PhysAddr 0x1100, DefaultSize 6, ControlRegister 0x74, Enable 1
RxPDO 0x1602 ""
PDO entry 0x6040:00, 16 bit, ""
PDO entry 0x607a:00, 32 bit, ""
PDO entry 0x60b2:00, 16 bit, ""
SM3: PhysAddr 0x1d00, DefaultSize 6, ControlRegister 0x30, Enable 1
TxPDO 0x1a02 ""
PDO entry 0x6041:00, 16 bit, ""
PDO entry 0x6064:00, 32 bit, ""
PDO entry 0x6077:00, 16 bit, ""
There are some messages in dmesg which may be of interest:
Code:
# when I boot (and the ethercat master is started):
# (I've pared this listing way back)
# I think this stuff might be normal ?
reid@charles1:~/linuxcnc-dev/configs/b3pr$ sudo dmesg
[ 14.683973] ec_master: loading out-of-tree module taints kernel.
[ 14.684280] ec_master: module verification failed: signature and/or required key missing - tainting kernel
[ 14.693550] EtherCAT: Master driver 1.5.2 unknown
[ 14.693640] EtherCAT: 1 master waiting for devices.
[ 14.715881] ec_generic: EtherCAT master generic Ethernet device module 1.5.2 unknown
[ 14.715902] EtherCAT: Accepting 68:05:CA:8A:B4:79 as main device for master 0.
[ 14.715931] ec_generic: Binding socket to interface 3 (enp11s2).
[ 14.748730] EtherCAT 0: Starting EtherCAT-IDLE thread.
# when I power up my servo drive:
# (I think these errors are because the drive powers up un-configured ?)
reid@charles1:~/linuxcnc-dev/configs/b3pr$ sudo dmesg
[347388.517587] e1000: enp11s2 NIC Link is Up 100 Mbps Full Duplex, Flow Control: RX
[347388.525123] EtherCAT 0: Link state of ecm0 changed to UP.
[347388.533112] EtherCAT 0: 1 slave(s) responding on main device.
[347388.533115] EtherCAT 0: Slave states on main device: INIT.
[347388.533487] EtherCAT 0: Scanning bus.
[347388.588712] EtherCAT ERROR 0-0: SDO upload 0x0000:00 aborted.
[347388.588715] EtherCAT ERROR 0-0: SDO abort message 0x06020000: "This object does not exist in the object directory".
[347388.588716] EtherCAT ERROR 0-0: Failed to read number of mapped PDO entries.
[347388.588717] EtherCAT ERROR 0-0: Failed to read mapped PDO entries for PDO 0x0000.
[347388.607462] EtherCAT ERROR 0-0: SDO upload 0x0000:00 aborted.
[347388.607464] EtherCAT ERROR 0-0: SDO abort message 0x06020000: "This object does not exist in the object directory".
[347388.607465] EtherCAT ERROR 0-0: Failed to read number of mapped PDO entries.
[347388.607466] EtherCAT ERROR 0-0: Failed to read mapped PDO entries for PDO 0x0000.
[347388.607468] EtherCAT 0: Bus scanning completed in 72 ms.
[347388.607469] EtherCAT 0: Using slave 0 as DC reference clock.
[347388.613165] EtherCAT 0: Slave states on main device: PREOP.
# when I configure my drive using the script above:
reid@charles1:~/linuxcnc-dev/configs/b3pr$ sudo dmesg
[347555.253993] EtherCAT 0: Scanning bus.
[347555.303228] EtherCAT 0: Bus scanning completed in 48 ms.
[347555.303229] EtherCAT 0: Using slave 0 as DC reference clock.
# now that the drive is powered on and configured, I start linuxcnc:
reid@charles1:~/linuxcnc-dev/configs/b3pr$ sudo dmesg
[347619.191020] EtherCAT: Requesting master 0...
[347619.191023] EtherCAT: Successfully requested master 0.
[347619.191429] EtherCAT 0: Domain0: Logical address 0x00000000, 16 byte, expected working counter 3.
[347619.191431] EtherCAT 0: Datagram domain0-0-main: Logical offset 0x00000000, 16 byte, type LRW.
[347619.191439] EtherCAT 0: Master thread exited.
[347619.191441] EtherCAT 0: Starting EtherCAT-OP thread.
[347619.191475] EtherCAT WARNING 0: 112 datagrams TIMED OUT!
[347622.741162] EtherCAT ERROR 0-0: Failed to set SAFEOP state, slave refused state change (PREOP + ERROR).
[347622.742159] EtherCAT ERROR 0-0: AL status message 0x001E: "Invalid input configuration".
[347622.744157] EtherCAT 0-0: Acknowledged state PREOP.
I sure would like to get these motors working.
Can anyone help?
Thanks,
Reid