Compare commits

...

6 Commits

Author SHA1 Message Date
mathis_s 1440fafc7d Fixed wrong limits after power cycle
Test And Build / Lint (push) Failing after 4s
Test And Build / Build (push) Successful in 7s
2026-06-09 15:14:06 +02:00
mathis_s b476b2a499 Guard against race condition with targetReached 2026-06-09 13:37:08 +02:00
mathis_s 1cddc9f761 Extended description of bit 2 in utils/decodeStatus.py
Test And Build / Lint (push) Failing after 4s
Test And Build / Build (push) Successful in 7s
2026-06-09 13:24:48 +02:00
mathis_s 55bd5ee3f2 Only print help in utils scripts if specifically requested (bugfix)
Test And Build / Lint (push) Failing after 4s
Test And Build / Build (push) Successful in 7s
2026-06-09 13:14:09 +02:00
mathis_s 1aaca37b6e Ignore limit errors if motor is currently at reference position
Test And Build / Lint (push) Failing after 5s
Test And Build / Build (push) Successful in 7s
2026-06-08 14:48:31 +02:00
mathis_s ec55dd1657 Updated to sinqMotor 2.1.1 and expanded driver error messages
Added controller name and axis number to the driver error messages.
2026-06-08 14:45:15 +02:00
5 changed files with 112 additions and 77 deletions
+64 -38
View File
@@ -81,10 +81,6 @@ void appendErrorMessage(char *fullMessage, size_t capacityFullMessage,
// fullMessage suffices. We need capacity for one additional character // fullMessage suffices. We need capacity for one additional character
// because of the linebreak. // because of the linebreak.
if (lenFullMessage + lenToBeAppended + 1 < capacityFullMessage) { 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 // We check before that the capacity of fullMessage is sufficient
strcat(fullMessage, toBeAppended); strcat(fullMessage, toBeAppended);
} }
@@ -158,9 +154,9 @@ masterMacsAxis::masterMacsAxis(masterMacsController *pC, int axisNo)
} }
// Even though this happens already in sinqAxis, a default value for // 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? // constructor is not run before the string is accessed?
status = setStringParam(pC_->motorMessageText(), ""); status = setStringParam(pC_->motorErrorMessage(), "");
if (status != asynSuccess) { if (status != asynSuccess) {
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR, asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR " "Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR "
@@ -447,9 +443,12 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
} }
if (timedOut) { if (timedOut) {
setAxisParamChecked(this, motorMessageText, char msg[pC_->MAXBUF_];
"Timed out while waiting for a handshake. " snprintf(msg, sizeof(msg),
"Please call the support."); "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; poll_status = asynError;
} }
@@ -532,9 +531,9 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
} else { } else {
// If we wait for a handshake, but the motor was moving in its last poll // If the motor hasn't moved after being enabled, we cannot trust
// cycle and has reached its target, it is not moving. Otherwise it is // targetReached. Hence, the targetReachedUninitialized flag guards
// considered moving, even if we're still waiting for the handshake. // against invalid detection of the "moving" status.
if (pMasterMacsA_->targetReachedUninitialized) { if (pMasterMacsA_->targetReachedUninitialized) {
*moving = false; *moving = false;
} else { } else {
@@ -545,7 +544,13 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
} }
} }
if (targetReached()) { // If the motor is not switched on, the targetReached bit is set to
// true. targetReachedUninitialized is set to true in the enable
// function, which is in a separate thread than doPoll. Therefore,
// doPoll can reset targetReachedUninitialized, which then can lead to
// a false "moving" status. Therefore, we only trust targetReached if
// the motor is switched on.
if (targetReached() && switchedOn()) {
pMasterMacsA_->targetReachedUninitialized = false; pMasterMacsA_->targetReachedUninitialized = false;
} }
} }
@@ -576,9 +581,12 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
pC_->getMsgPrintControl().getSuffix()); pC_->getMsgPrintControl().getSuffix());
} }
setAxisParamChecked(this, motorMessageText, char msg[pC_->MAXBUF_];
"Communication error between PC and motor " snprintf(msg, sizeof(msg),
"controller. Please call the support."); "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; poll_status = asynError;
} else { } else {
@@ -587,13 +595,16 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
// error message by appending strings. // error message by appending strings.
char errorMessage[pC_->MAXBUF_] = {0}; char errorMessage[pC_->MAXBUF_] = {0};
char shellMessage[pC_->MAXBUF_] = {0}; char shellMessage[pC_->MAXBUF_] = {0};
snprintf(errorMessage, sizeof(errorMessage),
"Controller \"%s\", axis %d: ", pC_->portName, axisNo());
// Concatenate all other errors // Concatenate all other errors
if (shortCircuit()) { if (shortCircuit()) {
appendErrorMessage(shellMessage, sizeof(shellMessage), appendErrorMessage(shellMessage, sizeof(shellMessage),
"Short circuit fault."); "Short circuit fault.");
appendErrorMessage(errorMessage, sizeof(errorMessage), appendErrorMessage(
"Short circuit error. Please call the support."); errorMessage, sizeof(errorMessage),
"Short circuit error. Please call the support. ");
poll_status = asynError; poll_status = asynError;
} }
@@ -602,7 +613,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
appendErrorMessage(shellMessage, sizeof(shellMessage), appendErrorMessage(shellMessage, sizeof(shellMessage),
"Encoder error."); "Encoder error.");
appendErrorMessage(errorMessage, sizeof(errorMessage), appendErrorMessage(errorMessage, sizeof(errorMessage),
"Encoder error. Please call the support."); "Encoder error. Please call the support. ");
poll_status = asynError; poll_status = asynError;
} }
@@ -614,7 +625,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
errorMessage, sizeof(errorMessage), errorMessage, sizeof(errorMessage),
"Maximum allowed following error exceeded.Check if " "Maximum allowed following error exceeded.Check if "
"movement range is blocked. Otherwise please call the " "movement range is blocked. Otherwise please call the "
"support."); "support. ");
poll_status = asynError; poll_status = asynError;
} }
@@ -623,7 +634,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
appendErrorMessage(shellMessage, sizeof(shellMessage), appendErrorMessage(shellMessage, sizeof(shellMessage),
"Feedback error."); "Feedback error.");
appendErrorMessage(errorMessage, sizeof(errorMessage), appendErrorMessage(errorMessage, sizeof(errorMessage),
"Feedback error. Please call the support."); "Feedback error. Please call the support. ");
poll_status = asynError; poll_status = asynError;
} }
@@ -632,9 +643,9 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
If the motor is homing or has been homed, ignore limit switch errors. If the motor is homing or has been homed, ignore limit switch errors.
*/ */
int homing = 0; int homing = 0;
int homed = 0; int at_home = 0;
getAxisParamChecked(this, motorStatusHome, &homing); getAxisParamChecked(this, motorStatusHome, &homing);
getAxisParamChecked(this, motorStatusHomed, &homed); getAxisParamChecked(this, motorStatusAtHome, &at_home);
/* /*
Ignore limit switch errors when homing / motor has been homed or when Ignore limit switch errors when homing / motor has been homed or when
@@ -665,7 +676,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
moving would be set to true anyway. The check is here for clarity / moving would be set to true anyway. The check is here for clarity /
being explicit. being explicit.
*/ */
if (!homing && !homed && !(*moving)) { if (!homing && !at_home && !(*moving)) {
/* /*
Either the software limits or the end switches of the controller Either the software limits or the end switches of the controller
have been hit. Since the EPICS limits are derived from the software have been hit. Since the EPICS limits are derived from the software
@@ -702,7 +713,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
"Software limits or end switch hit. Try homing the motor, " "Software limits or end switch hit. Try homing the motor, "
"moving in the opposite direction or check the SPS for " "moving in the opposite direction or check the SPS for "
"errors (if available). Otherwise please call the " "errors (if available). Otherwise please call the "
"support."); "support. ");
poll_status = asynError; poll_status = asynError;
} }
@@ -712,7 +723,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
appendErrorMessage(shellMessage, sizeof(shellMessage), appendErrorMessage(shellMessage, sizeof(shellMessage),
"Overcurrent error."); "Overcurrent error.");
appendErrorMessage(errorMessage, sizeof(errorMessage), appendErrorMessage(errorMessage, sizeof(errorMessage),
"Overcurrent error. Please call the support."); "Overcurrent error. Please call the support. ");
poll_status = asynError; poll_status = asynError;
} }
@@ -722,7 +733,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
"Overtemperature error."); "Overtemperature error.");
appendErrorMessage( appendErrorMessage(
errorMessage, sizeof(errorMessage), errorMessage, sizeof(errorMessage),
"Overtemperature error. Please call the support."); "Overtemperature error. Please call the support. ");
poll_status = asynError; poll_status = asynError;
} }
@@ -731,7 +742,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
appendErrorMessage(shellMessage, sizeof(shellMessage), appendErrorMessage(shellMessage, sizeof(shellMessage),
"Overvoltage error."); "Overvoltage error.");
appendErrorMessage(errorMessage, sizeof(errorMessage), appendErrorMessage(errorMessage, sizeof(errorMessage),
"Overvoltage error. Please call the support."); "Overvoltage error. Please call the support. ");
poll_status = asynError; poll_status = asynError;
} }
@@ -740,7 +751,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
appendErrorMessage(shellMessage, sizeof(shellMessage), appendErrorMessage(shellMessage, sizeof(shellMessage),
"Undervoltage error."); "Undervoltage error.");
appendErrorMessage(errorMessage, sizeof(errorMessage), appendErrorMessage(errorMessage, sizeof(errorMessage),
"Undervoltage error. Please call the support."); "Undervoltage error. Please call the support. ");
poll_status = asynError; poll_status = asynError;
} }
@@ -749,7 +760,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
appendErrorMessage(shellMessage, sizeof(shellMessage), appendErrorMessage(shellMessage, sizeof(shellMessage),
"STO input is on disable state."); "STO input is on disable state.");
appendErrorMessage(errorMessage, sizeof(errorMessage), appendErrorMessage(errorMessage, sizeof(errorMessage),
"STO fault. Please call the support."); "STO fault. Please call the support. ");
poll_status = asynError; poll_status = asynError;
} }
@@ -765,7 +776,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
} }
} }
setAxisParamChecked(this, motorMessageText, errorMessage); setAxisParamChecked(this, motorErrorMessage, errorMessage);
} }
// No error has been detected -> Reset the error count // No error has been detected -> Reset the error count
@@ -782,9 +793,22 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
} }
} }
// Update the enable PV /*
setAxisParamChecked(this, motorEnableRBV, If the motor just got enabled, we need to initialize it, because some
readyToBeSwitchedOn() && switchedOn()); parameters like the limits on the motor controllers are lost during a power
cycle and are rewritten from the masterMacs "meta-controller" when enabling.
*/
int wasEnabled = 0;
int isEnabled = readyToBeSwitchedOn() && switchedOn();
getAxisParamChecked(this, motorEnableRBV, &wasEnabled);
if (isEnabled && !wasEnabled) {
rwStatus = init();
if (rwStatus != asynSuccess) {
return rwStatus;
}
}
setAxisParamChecked(this, motorEnableRBV, isEnabled);
if (*moving) { if (*moving) {
// If the axis is moving, evaluate the movement direction // If the axis is moving, evaluate the movement direction
@@ -1147,7 +1171,7 @@ asynStatus masterMacsAxis::enable(bool on) {
"idle and can therefore not be disabled.\n", "idle and can therefore not be disabled.\n",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__); pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
setAxisParamChecked(this, motorMessageText, setAxisParamChecked(this, motorErrorMessage,
"Axis cannot be disabled while it is moving."); "Axis cannot be disabled while it is moving.");
return asynError; return asynError;
@@ -1214,10 +1238,12 @@ asynStatus masterMacsAxis::enable(bool on) {
on ? "enable" : "disable", PowerCycleTimeout); on ? "enable" : "disable", PowerCycleTimeout);
// Output message to user // Output message to user
snprintf(msg, sizeof(msg), "Failed to %s within %f seconds", snprintf(msg, sizeof(msg),
on ? "enable" : "disable", PowerCycleTimeout); "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; return asynError;
} }
+44 -35
View File
@@ -171,17 +171,16 @@ masterMacsController::masterMacsController(const char *portName,
// Compare to target values // Compare to target values
if (firmware_major_version() != major || if (firmware_major_version() != major ||
firmware_minor_version() > minor) { firmware_minor_version() > minor) {
asynPrint(this->pasynUser(), ASYN_TRACE_ERROR, asynPrint(
"Controller \"%s\" => %s, line %d\nFATAL ERROR " this->pasynUser(), ASYN_TRACE_ERROR,
"(Incorrect " "Controller \"%s\" => %s, line %d\nFATAL ERROR "
"version number of firmware: Expected major " "(Incorrect version number of firmware: Expected major "
"version equal " "version equal to %d, got %d. Expected minor version "
"to %d, got %d. Expected minor version equal to " "equal to or larger than %d, got %d).\nTerminating "
"or larger " "IOC.\n",
"than %d, got %d).\nTerminating IOC", portName, __PRETTY_FUNCTION__, __LINE__,
portName, __PRETTY_FUNCTION__, __LINE__, firmware_major_version(), major,
firmware_major_version(), major, firmware_minor_version(), minor);
firmware_minor_version(), minor);
exit(-1); exit(-1);
} }
} }
@@ -189,7 +188,7 @@ masterMacsController::masterMacsController(const char *portName,
asynPrint( asynPrint(
this->pasynUser(), ASYN_TRACE_ERROR, this->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\" => %s, line %d\nCould not read firmware " "Controller \"%s\" => %s, line %d\nCould not read firmware "
"version\n", "version.\n",
portName, __PRETTY_FUNCTION__, __LINE__); portName, __PRETTY_FUNCTION__, __LINE__);
} }
} }
@@ -248,7 +247,7 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
asynStatus status = asynSuccess; asynStatus status = asynSuccess;
char fullCommand[MAXBUF_] = {0}; char fullCommand[MAXBUF_] = {0};
char fullResponse[MAXBUF_] = {0}; char fullResponse[MAXBUF_] = {0};
char drvMessageText[MAXBUF_] = {0}; char drvMessage[MAXBUF_] = {0};
int motorStatusProblem = 0; int motorStatusProblem = 0;
int valueStart = 0; int valueStart = 0;
@@ -306,7 +305,7 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
adjustForPrint(printableCommand, fullCommand, MAXBUF_); adjustForPrint(printableCommand, fullCommand, MAXBUF_);
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d:\nError " "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__, portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
stringifyAsynStatus(status), printableCommand); stringifyAsynStatus(status), printableCommand);
} }
@@ -319,7 +318,7 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
case asynSuccess: case asynSuccess:
// We did get a response, but does it make sense and is it designated as // We did get a response, but does it make sense and is it designated as
// OK from the controller? This is checked here. // OK from the controller? This is checked here.
status = parseResponse(fullCommand, fullResponse, drvMessageText, status = parseResponse(fullCommand, fullResponse, drvMessage,
&valueStart, &valueStop, axisNo, tcpCmd, isRead); &valueStart, &valueStop, axisNo, tcpCmd, isRead);
// Read out the important information from the response // Read out the important information from the response
@@ -336,23 +335,29 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
} }
break; break;
case asynTimeout: case asynTimeout:
snprintf(drvMessageText, sizeof(drvMessageText), snprintf(drvMessage, sizeof(drvMessage),
"Connection timeout. Please call the support."); "Controller \"%s\", axis %d: Connection timeout. Please call "
"the support.",
portName, axisNo);
break; break;
case asynDisconnected: case asynDisconnected:
snprintf(drvMessageText, sizeof(drvMessageText), snprintf(drvMessage, sizeof(drvMessage),
"Axis is not connected."); "Controller \"%s\", axis %d: Axis is disconnected.", portName,
axisNo);
break; break;
case asynDisabled: case asynDisabled:
snprintf(drvMessageText, sizeof(drvMessageText), "Axis is disabled."); snprintf(drvMessage, sizeof(drvMessage),
"Controller \"%s\", axis %d: Axis is disabled.", portName,
axisNo);
break; break;
case asynError: case asynError:
// Do nothing - error message drvMessageText has already been set. // Do nothing - error message has already been set.
break; break;
default: default:
snprintf(drvMessageText, sizeof(drvMessageText), snprintf(drvMessage, sizeof(drvMessage),
"Communication failed (%s). Please call the support.", "Controller \"%s\", axis %d: Communication failed (%s). "
stringifyAsynStatus(status)); "Please call the support.",
portName, axisNo, stringifyAsynStatus(status));
break; break;
} }
@@ -386,7 +391,7 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
getAxisParamChecked(axis, motorStatusProblem, &motorStatusProblem); getAxisParamChecked(axis, motorStatusProblem, &motorStatusProblem);
if (motorStatusProblem == 0) { if (motorStatusProblem == 0) {
setAxisParamChecked(axis, motorMessageText, drvMessageText); setAxisParamChecked(axis, motorErrorMessage, drvMessage);
setAxisParamChecked(axis, motorStatusProblem, true); setAxisParamChecked(axis, motorStatusProblem, true);
setAxisParamChecked(axis, motorStatusCommsError, false); 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[ACK][CR] (No error)
- [ENQ][LSB][MSB][PDO1] 1 R 2=12.819[NAK][CR] (Communication failed) - [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 - [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. response and check if it is NAK or CAN.
*/ */
asynStatus masterMacsController::parseResponse( 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) { int *valueStart, int *valueStop, int axisNo, int tcpCmd, bool isRead) {
bool responseValid = false; bool responseValid = false;
@@ -469,7 +474,9 @@ asynStatus masterMacsController::parseResponse(
NAK NAK
This indicates that the axis is not connected. This is not an error! 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 // Motor was connected before -> Update the paramLib entry and PV
// to show it is now disconnected. // to show it is now disconnected.
@@ -496,9 +503,11 @@ asynStatus masterMacsController::parseResponse(
return asynDisconnected; return asynDisconnected;
} else if (fullResponse[i] == '\x18') { } else if (fullResponse[i] == '\x18') {
// CAN // CAN
snprintf(drvMessageText, MAXBUF_, snprintf(
"Tried to write with a read-only command. This is a " drvMessage, MAXBUF_,
"bug, please call the support."); "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, if (getMsgPrintControl().shouldBePrinted(parseKey, true,
pasynUserSelf)) { pasynUserSelf)) {
@@ -551,10 +560,10 @@ asynStatus masterMacsController::parseResponse(
getMsgPrintControl().getSuffix()); getMsgPrintControl().getSuffix());
} }
snprintf(drvMessageText, MAXBUF_, snprintf(drvMessage, MAXBUF_,
"Mismatched response %s to command %s. Please call the " "Controller \"%s\", axis %d: Mismatched response %s for "
"support.", "command %s. Please call the support.",
printableResponse, printableCommand); portName, axisNo, printableResponse, printableCommand);
return asynError; return asynError;
} else { } else {
getMsgPrintControl().resetCount(responseMatchKey, pasynUserSelf); getMsgPrintControl().resetCount(responseMatchKey, pasynUserSelf);
+1 -1
View File
@@ -67,7 +67,7 @@ the next value can be typed in. Type 'quit' to close the prompt.
if __name__ == "__main__": if __name__ == "__main__":
from sys import argv from sys import argv
if "-h" or "--help" in argv: if "-h" in argv or "--help" in argv:
print(help) print(help)
if len(argv) == 1: if len(argv) == 1:
+2 -2
View File
@@ -18,7 +18,7 @@ from decodeCommon import interactive, decode, print_decoded
interpretation = [ interpretation = [
("Not ready to be switched on", "Ready to be switched on"), # Bit 0 ("Not ready to be switched on", "Ready to be switched on"), # Bit 0
("Not switched on", "Switched on"), # Bit 1 ("Not switched on", "Switched on"), # Bit 1
("Disabled", "Enabled"), # Bit 2 ("Operation disabled (no current)", "Operation enabled (current)"), # Bit 2
("Ok", "Fault condition set"), # Bit 3 ("Ok", "Fault condition set"), # Bit 3
("Motor supply voltage absent ", "Motor supply voltage present"), # Bit 4 ("Motor supply voltage absent ", "Motor supply voltage present"), # Bit 4
("Motor performs quick stop", "Ok"), # Bit 5 ("Motor performs quick stop", "Ok"), # Bit 5
@@ -68,7 +68,7 @@ the next value can be typed in. Type 'quit' to close the prompt.
if __name__ == "__main__": if __name__ == "__main__":
from sys import argv from sys import argv
if "-h" or "--help" in argv: if "-h" in argv or "--help" in argv:
print(help) print(help)
if len(argv) == 1: if len(argv) == 1: