Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
5946563372 | |||
da96b4b973 | |||
61087d2e44 | |||
26754e608d |
@ -75,7 +75,8 @@ dbLoadTemplate("$(TOP)/mcu1.substitutions", "INSTR=$(INSTR)$(NAME):,CONTROLLER=$
|
|||||||
|
|
||||||
### Substitution file
|
### Substitution file
|
||||||
|
|
||||||
The substitution file is a table containing axis-specific information which is used to create the axis-specific PVs. To work with sinqMotor, "mcu1.substitutions" needs to look like this:
|
The substitution file is a table containing axis-specific information which is used to create the axis-specific PVs.
|
||||||
|
To work with sinqMotor, "mcu1.substitutions" needs to look like this (the order of columns does not matter):
|
||||||
```
|
```
|
||||||
file "$(SINQDBPATH)"
|
file "$(SINQDBPATH)"
|
||||||
{
|
{
|
||||||
@ -93,13 +94,13 @@ The variable `SINQDBPATH` has been set in "mcu1.cmd" before calling `dbLoadTempl
|
|||||||
|
|
||||||
- `AXIS`: Index of the axis, corresponds to the physical connection of the axis to the MCU.
|
- `AXIS`: Index of the axis, corresponds to the physical connection of the axis to the MCU.
|
||||||
- `M`: The full PV name is created by concatenating the variables INSTR, NAME and M. For example, the PV of the first axis would be "SQ:SINQTEST:mcu1:lin1".
|
- `M`: The full PV name is created by concatenating the variables INSTR, NAME and M. For example, the PV of the first axis would be "SQ:SINQTEST:mcu1:lin1".
|
||||||
- `DESC`: Description of the motor. This field is just for documentation and is not needed for operating a motor.
|
|
||||||
- `EGU`: Engineering units. For a linear motor, this is mm, for a rotaty motor, this is degree.
|
- `EGU`: Engineering units. For a linear motor, this is mm, for a rotaty motor, this is degree.
|
||||||
- `DIR`: If set to "Neg", the axis direction is inverted.
|
- `DIR`: If set to "Neg", the axis direction is inverted.
|
||||||
- `MRES`: This is a scaling factor determining the resolution of the position readback value. For example, 0.001 means a precision of 1 um. A detailed description can be found in section [Motor record resolution MRES](#motor-record-resolution-mres).
|
- `MRES`: This is a scaling factor determining the resolution of the position readback value. For example, 0.001 means a precision of 1 um. A detailed description can be found in section [Motor record resolution MRES](#motor-record-resolution-mres).
|
||||||
|
|
||||||
#### Optional parameters
|
#### Optional parameters
|
||||||
The default values for those parameters are given for the individual records in db/sinqMotor.db
|
The default values for those parameters are given for the individual records in db/sinqMotor.db
|
||||||
|
- `DESC`: Description of the motor. This field is just for documentation and is not needed for operating a motor.
|
||||||
- `MSGTEXTSIZE`: Buffer size for the motor message record in characters
|
- `MSGTEXTSIZE`: Buffer size for the motor message record in characters
|
||||||
- `ENABLEMOVWATCHDOG`: Sets `setWatchdogEnabled` during IOC startup to the given value.
|
- `ENABLEMOVWATCHDOG`: Sets `setWatchdogEnabled` during IOC startup to the given value.
|
||||||
- `LIMITSOFFSET`: If the motor limits are read out from the controller, they can
|
- `LIMITSOFFSET`: If the motor limits are read out from the controller, they can
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
# The main asyn motor record. Some fields are populated from the substitution
|
# The main asyn motor record. Some fields are populated from the substitution
|
||||||
# files via macros:
|
# files via macros:
|
||||||
# - $(INSTR): Name of the instrument, e.g. "SQ:SINQTEST:"
|
# - INSTR: Name of the instrument, e.g. "SQ:SINQTEST:"
|
||||||
# - $(M): Name of the motor in EPICS, e.g. "lin1"
|
# - M: Name of the motor in EPICS, e.g. "lin1"
|
||||||
# - $(DESC): Short description of the motor
|
# - DESC: Short description of the motor. If not given, this is equal to M
|
||||||
# - $(DIR): This value is usually set to "Pos". If the motor axis direction
|
# - DIR: This value is usually set to "Pos". If the motor axis direction
|
||||||
# should be inverted, this value can be set to "Neg"
|
# should be inverted, this value can be set to "Neg"
|
||||||
# - $(CONTROLLER): Name of the motor controller, e.g. "mcu1"
|
# - CONTROLLER: Name of the motor controller, e.g. "mcu1"
|
||||||
# - $(AXIS): Number of the axis, e.g. "1"
|
# - AXIS: Number of the axis, e.g. "1"
|
||||||
# - $(MRES): Motor record resolution. See the README.md for a detailed discussion
|
# - MRES: Motor record resolution. See the README.md for a detailed discussion
|
||||||
# - $(EGU): Engineering units. In case of a rotary axis, this is "degree", in
|
# - EGU: Engineering units. In case of a rotary axis, this is "degree", in
|
||||||
# case of a linear axis this is "mm".
|
# case of a linear axis this is "mm".
|
||||||
record(motor,"$(INSTR)$(M)")
|
record(motor,"$(INSTR)$(M)")
|
||||||
{
|
{
|
||||||
field(DESC,"$(DESC)")
|
field(DESC,"$(DESC=$(M))")
|
||||||
field(DTYP,"asynMotor")
|
field(DTYP,"asynMotor")
|
||||||
field(DIR,"$(DIR=Pos)")
|
field(DIR,"$(DIR=Pos)")
|
||||||
field(OUT,"@asyn($(CONTROLLER),$(AXIS))")
|
field(OUT,"@asyn($(CONTROLLER),$(AXIS))")
|
||||||
|
@ -100,36 +100,48 @@ asynStatus sinqAxis::poll(bool *moving) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
At the beginning of the poll, it is assumed that the axis has no status
|
||||||
|
problems and therefore all error indicators are reset. This does not affect
|
||||||
|
the PVs until callParamCallbacks has been called!
|
||||||
|
|
||||||
|
The motorStatusProblem_ field changes the motor record fields SEVR and STAT.
|
||||||
|
*/
|
||||||
|
pl_status = setIntegerParam(pC_->motorStatusProblem_, false);
|
||||||
|
if (pl_status != asynSuccess) {
|
||||||
|
pC_->paramLibAccessFailed(pl_status, "motorStatusProblem_",
|
||||||
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
|
}
|
||||||
|
pl_status = setIntegerParam(pC_->motorStatusCommsError_, false);
|
||||||
|
if (pl_status != asynSuccess) {
|
||||||
|
pC_->paramLibAccessFailed(pl_status, "motorStatusCommsError_",
|
||||||
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
|
}
|
||||||
|
pl_status = setStringParam(pC_->motorMessageText_, "");
|
||||||
|
if (pl_status != asynSuccess) {
|
||||||
|
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
||||||
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
// The poll function is just a wrapper around doPoll and
|
// The poll function is just a wrapper around doPoll and
|
||||||
// handles mainly the callParamCallbacks() function. This wrapper is used
|
// handles mainly the callParamCallbacks() function. This wrapper is used
|
||||||
// to make sure callParamCallbacks() is called in case of a premature
|
// to make sure callParamCallbacks() is called in case of a premature
|
||||||
// return.
|
// return.
|
||||||
poll_status = doPoll(moving);
|
poll_status = doPoll(moving);
|
||||||
|
|
||||||
// Check and update the watchdog
|
// The poll did not succeed: Something went wrong and the motor has a status
|
||||||
if (checkMovTimeoutWatchdog(*moving) != asynSuccess) {
|
// problem.
|
||||||
return asynError;
|
if (poll_status != asynSuccess) {
|
||||||
}
|
pl_status = setIntegerParam(pC_->motorStatusProblem_, true);
|
||||||
|
|
||||||
// If the poll status is ok, reset the error indicators in the parameter
|
|
||||||
// library
|
|
||||||
if (poll_status == asynSuccess) {
|
|
||||||
pl_status = setIntegerParam(pC_->motorStatusProblem_, false);
|
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
pC_->paramLibAccessFailed(pl_status, "motorStatusProblem_",
|
pC_->paramLibAccessFailed(pl_status, "motorStatusProblem_",
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
pl_status = setIntegerParam(pC_->motorStatusCommsError_, false);
|
}
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
pC_->paramLibAccessFailed(pl_status, "motorStatusCommsError_",
|
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText_, "");
|
// Check and update the watchdog
|
||||||
if (pl_status != asynSuccess) {
|
if (checkMovTimeoutWatchdog(*moving) != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
return asynError;
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
@ -490,8 +502,9 @@ asynStatus sinqAxis::checkMovTimeoutWatchdog(bool moving) {
|
|||||||
// Check the watchdog
|
// Check the watchdog
|
||||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
"%s => line %d:\nAxis %d exceeded the expected arrival time "
|
"%s => line %d:\nAxis %d exceeded the expected arrival time "
|
||||||
"(%ld).\n",
|
"%ld (current time is %ld).\n",
|
||||||
__PRETTY_FUNCTION__, __LINE__, axisNo_, expectedArrivalTime_);
|
__PRETTY_FUNCTION__, __LINE__, axisNo_, expectedArrivalTime_,
|
||||||
|
time(NULL));
|
||||||
|
|
||||||
pl_status = setStringParam(
|
pl_status = setStringParam(
|
||||||
pC_->motorMessageText_,
|
pC_->motorMessageText_,
|
||||||
|
@ -10,8 +10,9 @@ Stefan Mathis, November 2024
|
|||||||
|
|
||||||
#define motorMessageIsFromDriverString "MOTOR_MESSAGE_DRIVER"
|
#define motorMessageIsFromDriverString "MOTOR_MESSAGE_DRIVER"
|
||||||
#define motorMessageTextString "MOTOR_MESSAGE_TEXT"
|
#define motorMessageTextString "MOTOR_MESSAGE_TEXT"
|
||||||
#define IncrementalEncoder "Incremental encoder"
|
#define IncrementalEncoder "incremental"
|
||||||
#define AbsoluteEncoder "Absolute encoder"
|
#define AbsoluteEncoder "absolute"
|
||||||
|
#define NoEncoder "none"
|
||||||
|
|
||||||
class epicsShareClass sinqController : public asynMotorController {
|
class epicsShareClass sinqController : public asynMotorController {
|
||||||
public:
|
public:
|
||||||
|
Reference in New Issue
Block a user