Moved error handling out of error read condition.
Previously, error messaging was only done after the error has been read. This means that cached errors were simply ignored, if e.g. the motor was moving. This commit now messages an error as long as it exists in the cache "masterMacsAxisImpl->axisError".
This commit is contained in:
@@ -432,184 +432,181 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
Read out the error if either a fault condition status flag has been set or
|
Read out the error if either a fault condition status flag has been set or
|
||||||
if a movement has just ended.
|
if a movement has just ended.
|
||||||
*/
|
*/
|
||||||
|
if (faultConditionSet() || !(*moving)) {
|
||||||
|
rw_status = readAxisError();
|
||||||
|
}
|
||||||
|
|
||||||
msgPrintControlKey keyError = msgPrintControlKey(
|
msgPrintControlKey keyError = msgPrintControlKey(
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||||
|
|
||||||
if (faultConditionSet() || !(*moving)) {
|
/*
|
||||||
rw_status = readAxisError();
|
A communication error is a special case. If a communication between
|
||||||
|
controller and axis error occurred, all subsequent errors are ignored,
|
||||||
|
since this information is not reliable.
|
||||||
|
*/
|
||||||
|
if (communicationError()) {
|
||||||
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
|
pC_->pasynUser())) {
|
||||||
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\", axis %d => %s, line "
|
||||||
|
"%d\nCommunication error.%s\n",
|
||||||
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
pC_->getMsgPrintControl().getSuffix());
|
||||||
|
}
|
||||||
|
|
||||||
|
setAxisParamChecked(this, motorMessageText,
|
||||||
|
"Communication error between PC and motor "
|
||||||
|
"controller. Please call the support.");
|
||||||
|
|
||||||
|
poll_status = asynError;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// This buffer must be initialized to zero because we build the
|
||||||
|
// error message by appending strings.
|
||||||
|
char errorMessage[pC_->MAXBUF_] = {0};
|
||||||
|
char shellMessage[pC_->MAXBUF_] = {0};
|
||||||
|
|
||||||
|
// Concatenate all other errors
|
||||||
|
if (shortCircuit()) {
|
||||||
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
|
"Short circuit fault.");
|
||||||
|
appendErrorMessage(errorMessage, sizeof(errorMessage),
|
||||||
|
"Short circuit error. Please call the support.");
|
||||||
|
|
||||||
|
poll_status = asynError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encoderError()) {
|
||||||
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
|
"Encoder error.");
|
||||||
|
appendErrorMessage(errorMessage, sizeof(errorMessage),
|
||||||
|
"Encoder error. Please call the support.");
|
||||||
|
|
||||||
|
poll_status = asynError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (followingError()) {
|
||||||
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
|
"Maximum callowed following error exceeded.");
|
||||||
|
appendErrorMessage(
|
||||||
|
errorMessage, sizeof(errorMessage),
|
||||||
|
"Maximum allowed following error exceeded.Check if "
|
||||||
|
"movement range is blocked. Otherwise please call the "
|
||||||
|
"support.");
|
||||||
|
|
||||||
|
poll_status = asynError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (feedbackError()) {
|
||||||
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
|
"Feedback error.");
|
||||||
|
appendErrorMessage(errorMessage, sizeof(errorMessage),
|
||||||
|
"Feedback error. Please call the support.");
|
||||||
|
|
||||||
|
poll_status = asynError;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A communication error is a special case. If a communication between
|
Either the software limits or the end switches of the controller
|
||||||
controller and axis error occurred, all subsequent errors are ignored,
|
have been hit. Since the EPICS limits are derived from the software
|
||||||
since this information is not reliable.
|
limits and are a little bit smaller, these error cases can only
|
||||||
*/
|
happen if either the axis has an incremental encoder which is not
|
||||||
if (communicationError()) {
|
properly homed or if a bug occured.
|
||||||
|
*/
|
||||||
|
if (positiveLimitSwitch() || negativeLimitSwitch() ||
|
||||||
|
positiveSoftwareLimit() || negativeSoftwareLimit()) {
|
||||||
|
|
||||||
|
// Distinction for developers
|
||||||
|
if (positiveLimitSwitch()) {
|
||||||
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
|
"Positive limit switch.");
|
||||||
|
}
|
||||||
|
if (negativeLimitSwitch()) {
|
||||||
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
|
"Negative limit switch.");
|
||||||
|
}
|
||||||
|
if (positiveSoftwareLimit()) {
|
||||||
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
|
"Positive software limit.");
|
||||||
|
}
|
||||||
|
if (negativeSoftwareLimit()) {
|
||||||
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
|
"Negative software limit.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic error message for user
|
||||||
|
appendErrorMessage(
|
||||||
|
errorMessage, sizeof(errorMessage),
|
||||||
|
"Software limits or end switch hit. Try homing the motor, "
|
||||||
|
"moving in the opposite direction or check the SPS for "
|
||||||
|
"errors (if available). Otherwise please call the "
|
||||||
|
"support.");
|
||||||
|
|
||||||
|
poll_status = asynError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overCurrent()) {
|
||||||
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
|
"Overcurrent error.");
|
||||||
|
appendErrorMessage(errorMessage, sizeof(errorMessage),
|
||||||
|
"Overcurrent error. Please call the support.");
|
||||||
|
|
||||||
|
poll_status = asynError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overTemperature()) {
|
||||||
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
|
"Overtemperature error.");
|
||||||
|
appendErrorMessage(
|
||||||
|
errorMessage, sizeof(errorMessage),
|
||||||
|
"Overtemperature error. Please call the support.");
|
||||||
|
|
||||||
|
poll_status = asynError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overVoltage()) {
|
||||||
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
|
"Overvoltage error.");
|
||||||
|
appendErrorMessage(errorMessage, sizeof(errorMessage),
|
||||||
|
"Overvoltage error. Please call the support.");
|
||||||
|
|
||||||
|
poll_status = asynError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (underVoltage()) {
|
||||||
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
|
"Undervoltage error.");
|
||||||
|
appendErrorMessage(errorMessage, sizeof(errorMessage),
|
||||||
|
"Undervoltage error. Please call the support.");
|
||||||
|
|
||||||
|
poll_status = asynError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stoFault()) {
|
||||||
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
|
"STO input is on disable state.");
|
||||||
|
appendErrorMessage(errorMessage, sizeof(errorMessage),
|
||||||
|
"STO fault. Please call the support.");
|
||||||
|
|
||||||
|
poll_status = asynError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(shellMessage) > 0) {
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
pC_->pasynUser())) {
|
pC_->pasynUser())) {
|
||||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line "
|
"Controller \"%s\", axis %d => %s, line "
|
||||||
"%d\nCommunication error.%s\n",
|
"%d\n%s%s\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
pC_->getMsgPrintControl().getSuffix());
|
shellMessage, pC_->getMsgPrintControl().getSuffix());
|
||||||
}
|
}
|
||||||
|
|
||||||
setAxisParamChecked(this, motorMessageText,
|
|
||||||
"Communication error between PC and motor "
|
|
||||||
"controller. Please call the support.");
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// This buffer must be initialized to zero because we build the
|
|
||||||
// error message by appending strings.
|
|
||||||
char errorMessage[pC_->MAXBUF_] = {0};
|
|
||||||
char shellMessage[pC_->MAXBUF_] = {0};
|
|
||||||
|
|
||||||
// Concatenate all other errors
|
|
||||||
if (shortCircuit()) {
|
|
||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
|
||||||
"Short circuit fault.");
|
|
||||||
appendErrorMessage(
|
|
||||||
errorMessage, sizeof(errorMessage),
|
|
||||||
"Short circuit error. Please call the support.");
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (encoderError()) {
|
|
||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
|
||||||
"Encoder error.");
|
|
||||||
appendErrorMessage(errorMessage, sizeof(errorMessage),
|
|
||||||
"Encoder error. Please call the support.");
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (followingError()) {
|
|
||||||
appendErrorMessage(
|
|
||||||
shellMessage, sizeof(shellMessage),
|
|
||||||
"Maximum callowed following error exceeded.");
|
|
||||||
appendErrorMessage(
|
|
||||||
errorMessage, sizeof(errorMessage),
|
|
||||||
"Maximum allowed following error exceeded.Check if "
|
|
||||||
"movement range is blocked. Otherwise please call the "
|
|
||||||
"support.");
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (feedbackError()) {
|
|
||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
|
||||||
"Feedback error.");
|
|
||||||
appendErrorMessage(errorMessage, sizeof(errorMessage),
|
|
||||||
"Feedback error. Please call the support.");
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Either the software limits or the end switches of the controller
|
|
||||||
have been hit. Since the EPICS limits are derived from the software
|
|
||||||
limits and are a little bit smaller, these error cases can only
|
|
||||||
happen if either the axis has an incremental encoder which is not
|
|
||||||
properly homed or if a bug occured.
|
|
||||||
*/
|
|
||||||
if (positiveLimitSwitch() || negativeLimitSwitch() ||
|
|
||||||
positiveSoftwareLimit() || negativeSoftwareLimit()) {
|
|
||||||
|
|
||||||
// Distinction for developers
|
|
||||||
if (positiveLimitSwitch()) {
|
|
||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
|
||||||
"Positive limit switch.");
|
|
||||||
}
|
|
||||||
if (negativeLimitSwitch()) {
|
|
||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
|
||||||
"Negative limit switch.");
|
|
||||||
}
|
|
||||||
if (positiveSoftwareLimit()) {
|
|
||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
|
||||||
"Positive software limit.");
|
|
||||||
}
|
|
||||||
if (negativeSoftwareLimit()) {
|
|
||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
|
||||||
"Negative software limit.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generic error message for user
|
|
||||||
appendErrorMessage(
|
|
||||||
errorMessage, sizeof(errorMessage),
|
|
||||||
"Software limits or end switch hit. Try homing the motor, "
|
|
||||||
"moving in the opposite direction or check the SPS for "
|
|
||||||
"errors (if available). Otherwise please call the "
|
|
||||||
"support.");
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overCurrent()) {
|
|
||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
|
||||||
"Overcurrent error.");
|
|
||||||
appendErrorMessage(
|
|
||||||
errorMessage, sizeof(errorMessage),
|
|
||||||
"Overcurrent error. Please call the support.");
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overTemperature()) {
|
|
||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
|
||||||
"Overtemperature error.");
|
|
||||||
appendErrorMessage(
|
|
||||||
errorMessage, sizeof(errorMessage),
|
|
||||||
"Overtemperature error. Please call the support.");
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overVoltage()) {
|
|
||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
|
||||||
"Overvoltage error.");
|
|
||||||
appendErrorMessage(
|
|
||||||
errorMessage, sizeof(errorMessage),
|
|
||||||
"Overvoltage error. Please call the support.");
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (underVoltage()) {
|
|
||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
|
||||||
"Undervoltage error.");
|
|
||||||
appendErrorMessage(
|
|
||||||
errorMessage, sizeof(errorMessage),
|
|
||||||
"Undervoltage error. Please call the support.");
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stoFault()) {
|
|
||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
|
||||||
"STO input is on disable state.");
|
|
||||||
appendErrorMessage(errorMessage, sizeof(errorMessage),
|
|
||||||
"STO fault. Please call the support.");
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(shellMessage) > 0) {
|
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(
|
|
||||||
keyError, true, pC_->pasynUser())) {
|
|
||||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
|
||||||
"Controller \"%s\", axis %d => %s, line "
|
|
||||||
"%d\n%s%s\n",
|
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__, shellMessage,
|
|
||||||
pC_->getMsgPrintControl().getSuffix());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setAxisParamChecked(this, motorMessageText, errorMessage);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
setAxisParamChecked(this, motorMessageText, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No error has been detected -> Reset the error count
|
||||||
|
if (poll_status == asynSuccess) {
|
||||||
pC_->getMsgPrintControl().resetCount(keyError, pC_->pasynUser());
|
pC_->getMsgPrintControl().resetCount(keyError, pC_->pasynUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user