From ec55dd165700a17caec4c7432823b11bfc5430fe Mon Sep 17 00:00:00 2001 From: smathis Date: Mon, 8 Jun 2026 14:45:15 +0200 Subject: [PATCH] Updated to sinqMotor 2.1.1 and expanded driver error messages Added controller name and axis number to the driver error messages. --- sinqMotor | 2 +- src/masterMacsAxis.cpp | 63 +++++++++++++++------------- src/masterMacsController.cpp | 79 ++++++++++++++++++++---------------- 3 files changed, 80 insertions(+), 64 deletions(-) diff --git a/sinqMotor b/sinqMotor index 95bc899..1470f90 160000 --- a/sinqMotor +++ b/sinqMotor @@ -1 +1 @@ -Subproject commit 95bc899114f90fa0b5925054d1eb374db9678bd7 +Subproject commit 1470f901bc834739ccb0c0a506c7214fe5056bb0 diff --git a/src/masterMacsAxis.cpp b/src/masterMacsAxis.cpp index ca53089..d0a388a 100644 --- a/src/masterMacsAxis.cpp +++ b/src/masterMacsAxis.cpp @@ -81,10 +81,6 @@ void appendErrorMessage(char *fullMessage, size_t capacityFullMessage, // fullMessage suffices. We need capacity for one additional character // because of the linebreak. if (lenFullMessage + lenToBeAppended + 1 < capacityFullMessage) { - // Append the linebreak and readd the null terminator behind it - // fullMessage[lenFullMessage] = '\n'; - // fullMessage[lenFullMessage + 1] = '\0'; - // We check before that the capacity of fullMessage is sufficient strcat(fullMessage, toBeAppended); } @@ -158,9 +154,9 @@ masterMacsAxis::masterMacsAxis(masterMacsController *pC, int axisNo) } // Even though this happens already in sinqAxis, a default value for - // motorMessageText is set here again, because apparently the sinqAxis + // motorErrorMessage is set here again, because apparently the sinqAxis // constructor is not run before the string is accessed? - status = setStringParam(pC_->motorMessageText(), ""); + status = setStringParam(pC_->motorErrorMessage(), ""); if (status != asynSuccess) { asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR " @@ -447,9 +443,12 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { } if (timedOut) { - setAxisParamChecked(this, motorMessageText, - "Timed out while waiting for a handshake. " - "Please call the support."); + char msg[pC_->MAXBUF_]; + snprintf(msg, sizeof(msg), + "Controller \"%s\", axis %d: Timed out while waiting for " + "a handshake. Please call the support.", + pC_->portName, axisNo()); + setAxisParamChecked(this, motorErrorMessage, msg); poll_status = asynError; } @@ -576,9 +575,12 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { pC_->getMsgPrintControl().getSuffix()); } - setAxisParamChecked(this, motorMessageText, - "Communication error between PC and motor " - "controller. Please call the support."); + char msg[pC_->MAXBUF_]; + snprintf(msg, sizeof(msg), + "Controller \"%s\", axis %d: Communication error between IOC " + "and motor controller. Please call the support.", + pC_->portName, axisNo()); + setAxisParamChecked(this, motorErrorMessage, msg); poll_status = asynError; } else { @@ -587,13 +589,16 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { // error message by appending strings. char errorMessage[pC_->MAXBUF_] = {0}; char shellMessage[pC_->MAXBUF_] = {0}; + snprintf(errorMessage, sizeof(errorMessage), + "Controller \"%s\", axis %d: ", pC_->portName, axisNo()); // Concatenate all other errors if (shortCircuit()) { appendErrorMessage(shellMessage, sizeof(shellMessage), "Short circuit fault."); - appendErrorMessage(errorMessage, sizeof(errorMessage), - "Short circuit error. Please call the support."); + appendErrorMessage( + errorMessage, sizeof(errorMessage), + "Short circuit error. Please call the support. "); poll_status = asynError; } @@ -602,7 +607,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { appendErrorMessage(shellMessage, sizeof(shellMessage), "Encoder error."); appendErrorMessage(errorMessage, sizeof(errorMessage), - "Encoder error. Please call the support."); + "Encoder error. Please call the support. "); poll_status = asynError; } @@ -614,7 +619,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { errorMessage, sizeof(errorMessage), "Maximum allowed following error exceeded.Check if " "movement range is blocked. Otherwise please call the " - "support."); + "support. "); poll_status = asynError; } @@ -623,7 +628,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { appendErrorMessage(shellMessage, sizeof(shellMessage), "Feedback error."); appendErrorMessage(errorMessage, sizeof(errorMessage), - "Feedback error. Please call the support."); + "Feedback error. Please call the support. "); poll_status = asynError; } @@ -702,7 +707,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { "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."); + "support. "); poll_status = asynError; } @@ -712,7 +717,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { appendErrorMessage(shellMessage, sizeof(shellMessage), "Overcurrent error."); appendErrorMessage(errorMessage, sizeof(errorMessage), - "Overcurrent error. Please call the support."); + "Overcurrent error. Please call the support. "); poll_status = asynError; } @@ -722,7 +727,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { "Overtemperature error."); appendErrorMessage( errorMessage, sizeof(errorMessage), - "Overtemperature error. Please call the support."); + "Overtemperature error. Please call the support. "); poll_status = asynError; } @@ -731,7 +736,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { appendErrorMessage(shellMessage, sizeof(shellMessage), "Overvoltage error."); appendErrorMessage(errorMessage, sizeof(errorMessage), - "Overvoltage error. Please call the support."); + "Overvoltage error. Please call the support. "); poll_status = asynError; } @@ -740,7 +745,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { appendErrorMessage(shellMessage, sizeof(shellMessage), "Undervoltage error."); appendErrorMessage(errorMessage, sizeof(errorMessage), - "Undervoltage error. Please call the support."); + "Undervoltage error. Please call the support. "); poll_status = asynError; } @@ -749,7 +754,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { appendErrorMessage(shellMessage, sizeof(shellMessage), "STO input is on disable state."); appendErrorMessage(errorMessage, sizeof(errorMessage), - "STO fault. Please call the support."); + "STO fault. Please call the support. "); poll_status = asynError; } @@ -765,7 +770,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) { } } - setAxisParamChecked(this, motorMessageText, errorMessage); + setAxisParamChecked(this, motorErrorMessage, errorMessage); } // No error has been detected -> Reset the error count @@ -1147,7 +1152,7 @@ asynStatus masterMacsAxis::enable(bool on) { "idle and can therefore not be disabled.\n", pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__); - setAxisParamChecked(this, motorMessageText, + setAxisParamChecked(this, motorErrorMessage, "Axis cannot be disabled while it is moving."); return asynError; @@ -1214,10 +1219,12 @@ asynStatus masterMacsAxis::enable(bool on) { on ? "enable" : "disable", PowerCycleTimeout); // Output message to user - snprintf(msg, sizeof(msg), "Failed to %s within %f seconds", - on ? "enable" : "disable", PowerCycleTimeout); + snprintf(msg, sizeof(msg), + "Controller \"%s\", axis %d: Failed to %s within %f seconds", + pC_->portName, axisNo_, on ? "enable" : "disable", + PowerCycleTimeout); - setAxisParamChecked(this, motorMessageText, msg); + setAxisParamChecked(this, motorErrorMessage, msg); return asynError; } diff --git a/src/masterMacsController.cpp b/src/masterMacsController.cpp index 5a19b09..dd5b78c 100644 --- a/src/masterMacsController.cpp +++ b/src/masterMacsController.cpp @@ -171,17 +171,16 @@ masterMacsController::masterMacsController(const char *portName, // Compare to target values if (firmware_major_version() != major || firmware_minor_version() > minor) { - asynPrint(this->pasynUser(), ASYN_TRACE_ERROR, - "Controller \"%s\" => %s, line %d\nFATAL ERROR " - "(Incorrect " - "version number of firmware: Expected major " - "version equal " - "to %d, got %d. Expected minor version equal to " - "or larger " - "than %d, got %d).\nTerminating IOC", - portName, __PRETTY_FUNCTION__, __LINE__, - firmware_major_version(), major, - firmware_minor_version(), minor); + asynPrint( + this->pasynUser(), ASYN_TRACE_ERROR, + "Controller \"%s\" => %s, line %d\nFATAL ERROR " + "(Incorrect version number of firmware: Expected major " + "version equal to %d, got %d. Expected minor version " + "equal to or larger than %d, got %d).\nTerminating " + "IOC.\n", + portName, __PRETTY_FUNCTION__, __LINE__, + firmware_major_version(), major, + firmware_minor_version(), minor); exit(-1); } } @@ -189,7 +188,7 @@ masterMacsController::masterMacsController(const char *portName, asynPrint( this->pasynUser(), ASYN_TRACE_ERROR, "Controller \"%s\" => %s, line %d\nCould not read firmware " - "version\n", + "version.\n", portName, __PRETTY_FUNCTION__, __LINE__); } } @@ -248,7 +247,7 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd, asynStatus status = asynSuccess; char fullCommand[MAXBUF_] = {0}; char fullResponse[MAXBUF_] = {0}; - char drvMessageText[MAXBUF_] = {0}; + char drvMessage[MAXBUF_] = {0}; int motorStatusProblem = 0; int valueStart = 0; @@ -306,7 +305,7 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd, adjustForPrint(printableCommand, fullCommand, MAXBUF_); asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line %d:\nError " - "%s while sending command %s to the controller\n", + "%s while sending command %s to the controller.\n", portName, axisNo, __PRETTY_FUNCTION__, __LINE__, stringifyAsynStatus(status), printableCommand); } @@ -319,7 +318,7 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd, case asynSuccess: // We did get a response, but does it make sense and is it designated as // OK from the controller? This is checked here. - status = parseResponse(fullCommand, fullResponse, drvMessageText, + status = parseResponse(fullCommand, fullResponse, drvMessage, &valueStart, &valueStop, axisNo, tcpCmd, isRead); // Read out the important information from the response @@ -336,23 +335,29 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd, } break; case asynTimeout: - snprintf(drvMessageText, sizeof(drvMessageText), - "Connection timeout. Please call the support."); + snprintf(drvMessage, sizeof(drvMessage), + "Controller \"%s\", axis %d: Connection timeout. Please call " + "the support.", + portName, axisNo); break; case asynDisconnected: - snprintf(drvMessageText, sizeof(drvMessageText), - "Axis is not connected."); + snprintf(drvMessage, sizeof(drvMessage), + "Controller \"%s\", axis %d: Axis is disconnected.", portName, + axisNo); break; case asynDisabled: - snprintf(drvMessageText, sizeof(drvMessageText), "Axis is disabled."); + snprintf(drvMessage, sizeof(drvMessage), + "Controller \"%s\", axis %d: Axis is disabled.", portName, + axisNo); break; case asynError: - // Do nothing - error message drvMessageText has already been set. + // Do nothing - error message has already been set. break; default: - snprintf(drvMessageText, sizeof(drvMessageText), - "Communication failed (%s). Please call the support.", - stringifyAsynStatus(status)); + snprintf(drvMessage, sizeof(drvMessage), + "Controller \"%s\", axis %d: Communication failed (%s). " + "Please call the support.", + portName, axisNo, stringifyAsynStatus(status)); break; } @@ -386,7 +391,7 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd, getAxisParamChecked(axis, motorStatusProblem, &motorStatusProblem); if (motorStatusProblem == 0) { - setAxisParamChecked(axis, motorMessageText, drvMessageText); + setAxisParamChecked(axis, motorErrorMessage, drvMessage); setAxisParamChecked(axis, motorStatusProblem, true); setAxisParamChecked(axis, motorStatusCommsError, false); } @@ -402,11 +407,11 @@ message!): - [ENQ][LSB][MSB][PDO1] 1 R 2=12.819[ACK][CR] (No error) - [ENQ][LSB][MSB][PDO1] 1 R 2=12.819[NAK][CR] (Communication failed) - [ENQ][LSB][MSB][PDO1] 1 S 10 [CAN][CR] (Driver tried to write with -a read-only command) Read out the second-to-last char of the +a read-only command). Read out the second-to-last char of the response and check if it is NAK or CAN. */ asynStatus masterMacsController::parseResponse( - const char *fullCommand, const char *fullResponse, char *drvMessageText, + const char *fullCommand, const char *fullResponse, char *drvMessage, int *valueStart, int *valueStop, int axisNo, int tcpCmd, bool isRead) { bool responseValid = false; @@ -469,7 +474,9 @@ asynStatus masterMacsController::parseResponse( NAK This indicates that the axis is not connected. This is not an error! */ - snprintf(drvMessageText, MAXBUF_, "Axis not connected."); + snprintf(drvMessage, MAXBUF_, + "Controller \"%s\", axis %d: Axis is disconnected.", + portName, axisNo); // Motor was connected before -> Update the paramLib entry and PV // to show it is now disconnected. @@ -496,9 +503,11 @@ asynStatus masterMacsController::parseResponse( return asynDisconnected; } else if (fullResponse[i] == '\x18') { // CAN - snprintf(drvMessageText, MAXBUF_, - "Tried to write with a read-only command. This is a " - "bug, please call the support."); + snprintf( + drvMessage, MAXBUF_, + "Controller \"%s\", axis %d: Tried to write with a " + "read-only command. This is a bug, please call the support.", + portName, axisNo); if (getMsgPrintControl().shouldBePrinted(parseKey, true, pasynUserSelf)) { @@ -551,10 +560,10 @@ asynStatus masterMacsController::parseResponse( getMsgPrintControl().getSuffix()); } - snprintf(drvMessageText, MAXBUF_, - "Mismatched response %s to command %s. Please call the " - "support.", - printableResponse, printableCommand); + snprintf(drvMessage, MAXBUF_, + "Controller \"%s\", axis %d: Mismatched response %s for " + "command %s. Please call the support.", + portName, axisNo, printableResponse, printableCommand); return asynError; } else { getMsgPrintControl().resetCount(responseMatchKey, pasynUserSelf);