Moved error handling out of error read condition.
Some checks failed
Test And Build / Lint (push) Failing after 9s
Test And Build / Build (push) Successful in 12s

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:
2025-08-05 09:04:11 +02:00
parent ff183576ec
commit 954fc82414

View File

@@ -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());
} }