The “BOTH_LIMITS” error can be related to limit switches not being powered with 24V. At PSI, limits are normally fed from 24V outputs, typically an EL2819 terminal. The outputs therefore need to be set to 1 to power the switches. Check the schematics to find which output powers the switches for a given axis, then use one of the following approaches to set it to 1:
Define the output in the axis YAML file:
axis:
id: 1 # Axis id
...
feedSwitchesOutput: ec0.s5.binaryOutput02 # EtherCAT entry for feed switches
...
By using the command Cfg.WriteEcEntryEcPath(ec<master_id>.s<slave_id>.binaryOutput<id>,<value>):
ecmcConfigOrDie "Cfg.WriteEcEntryEcPath(ec0.s5>.binaryOutput02,1)"
A position lag error (following error) can be generated in the following situations:
Before increasing current to the motor, make sure that both motor and drive can handle the higher current. Extra care is needed for vacuum applications.
Check the scaling documentation here. One way to test if the scaling is correct is to set all controller parameters (except Kff) to 0 and then initiate a move. Basically the actual position of the axis should follow the setpoint closely with the same slope. If the slope differs, then the scaling factors are wrong.
If a stepper motor stalls because of excessive velocity, there are a few things that can be done to improve the ability to reach higher velocities:
Before increasing current to the motor, make sure that both motor and drive can handle the higher current. Extra care is needed for vacuum applications.
The velocity setpoint of drives covers a certain velocity range:
If a velocity outside the velocity range is requested, the velocity setpoint will be saturated and the requested velocity will not be reached resulting in a position lag error.
For EL70xx drives the velocity range can be configured to other values than the default +-2000full-steps/s. See el70x1 speed range for setting other velocity range.
First check the dedicated hardware drive panel for diagnostics and errors/warnings. For EL70x1 drive diagnostics, check el70x1.
Possible reasons:
yaml->input.interlock).This procedure is for experts only. You run the risk of destroying expensive devices. Limit switches are not obeyed. YOU HAVE BEEN WARNED!
For this however, the IOC needs to be reconfigured to not link the hardware to an axis!
dbgrep "*s007*"-Drv01-Cmd and -Drv01-Spd-Drv01-Cmd to 1 and check the amplifier did enable, if you don’t know how to check for an enabled amplifier, you should not use this command!-Drv01-Spd. Depending on the scaling, the number might be in the range of 1..1000.For axes with dual limit switches, or where special logic is needed, limit switches can be overridden by the keyword plcOverride:
...
input:
limit:
forward: 'plcOverride' # Overridden, see plc code below
backward: 'plcOverride' # Overridden, see plc code below
...
The limits must then be written from PLC code. Any logic can be applied to set the limits, for example:
...
plc:
enable: true # Enable axis plc
externalCommands: true # Allow axis to inputs from PLC
code: # Sync code (appended after code in plc.file)
- ax${AX_ID=1}.mon.lowlim:=ec_chk_bit(ec0.s$(DRV_SID).binaryInputs01,0) and ec0.s2.analogInput01<1000;
- ax${AX_ID=1}.mon.highlim:=ec_chk_bit(ec0.s$(DRV_SID).binaryInputs01,1) and ec0.s33.binaryInput02;
...
Note that in PLC code, bits must be accessed with the ec_chk_bit() command.
Sometimes two limit switches are needed, but only one can be linked in the YAML configuration. One use case is overlapping axis ranges where a switch is used to prevent collisions.
To configure this, add a PLC where the two limit switches are combined with an and (for normally closed switches) into one bit by using the simulation entries (ec<mid>.s<sid>.ONE or ec<mid>.s<sid>.ZERO).
ec<mid>.s<sid>.ZERO (dummy 32-bit memory area in ecmc initialized to 0). Any slave can be chosen, but it probably makes sense to use the drive slave.Example (use ec0.s2.ZERO.31 as combined limit switch):
# Master 0
# Drive slave 3 (can be any slave)
# Bit 31
# Switch 1: ec0.s5.binaryInput01
# Switch 2: ec0.s5.binaryInput02
ec0.s3.ZERO:=ec_wrt_bit(ec0.s3.ZERO,ec0.s5.binaryInput01 and ec0.s5.binaryInput02,31);
Then use it as a forward or backward bit in YAML:
input:
limit:
forward: ec0.s2.ZERO.31 # In PLC "ec0.s5.binaryInput01 and ec0.s5.binaryInput02"
backward: ....
If you use the default jinja backend, YAML loading depends on a Python venv with certain libraries. The venv is created in /tmp when the first YAML axis/plc file is loaded.
If the ecmc-server is not allowed to install with pip (for example in machine networks), then the error message below is printed in iocsh and axis loading fails:
iocshLoad /gfa/.mounts/sls_ioc/modules/ecmccfg/9.6.8/R7.0.8/loadYamlAxis.cmd, "FILE=cfg/servo-linear.yaml, ID=1, NAME=SERVO1, DESC=test, DRV_SLAVE=9"
#==============================================================================
# loadYamlAxis.cmd
on error halt
# Step 1: Get filename (need to check if filename also contains other macros). Basically run the filename in this iocsh
ecmcFileExist("cfg/servo-linear.yaml",1)
epicsEnvSet(FILE_TEMP_BASE,/tmp/X01DD-CPCL-FEMOT02/EcMaster_2/cfg/servo-linear.yaml)
epicsEnvSet(FILE_TEMP_1,/tmp/X01DD-CPCL-FEMOT02/EcMaster_2/cfg/servo-linear.yaml_1)
system ". /gfa/.mounts/sls_ioc/modules/ecmccfg/9.6.8/R7.0.8/pythonVenv.sh -d /tmp/X01DD-CPCL-FEMOT02/EcMaster_2/; python /gfa/.mounts/sls_ioc/modules/ecmccfg/9.6.8/R7.0.8/ecmcPlcGetFileName.py cfg/servo-linear.yaml /tmp/X01DD-CPCL-FEMOT02/EcMaster_2/cfg/servo-linear.yaml_1"
Collecting wheel
Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='pypi.org', port=443): Read timed out. (read timeout=15)")': /simple/wheel/
Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='pypi.org', port=443): Read timed out. (read timeout=15)")': /simple/wheel/
Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='pypi.org', port=443): Read timed out. (read timeout=15)")': /simple/wheel/
PSI specific: The solution is to use the ecmc_server_cfg repo as described in its README.md. This repo ensures that the correct Python venv is copied after each boot, so installation is not needed at IOC startup.
As an alternative to the Python backend, ecmccfg can use the C++ tool ecb as YAML parser/render backend (ECMC_CFG_TOOL=ecb). See motion_cfg/ecb.