mirror of
https://github.com/grblHAL/core.git
synced 2026-08-17 16:41:45 +08:00
Fixed silly typedef mistake in setting struct, added settings $392 and $393 for spindle and coolant startup delays on safety door open.
This commit is contained in:
@@ -11,14 +11,14 @@ It has been written to complement grblHAL and has features such as proper keyboa
|
||||
|
||||
---
|
||||
|
||||
Latest build date is 20211121, see the [changelog](changelog.md) for details.
|
||||
__NOTE:__ A settings reset will be performed on an update for versions earlier than 20211121. Backup and restore of settings is recommended.
|
||||
Latest build date is 20211122, see the [changelog](changelog.md) for details.
|
||||
__NOTE:__ A settings reset will be performed on an update for versions earlier than 20211122. Backup and restore of settings is recommended.
|
||||
__IMPORTANT!__ A new setting has been introduced for ganged axes motors in version 20211121.
|
||||
I have only bench tested this for a couple of drivers, correct function should be verified after updating by those who have more than three motors configured.
|
||||
More details in the [changelog](changelog.md).
|
||||
|
||||
---
|
||||
|
||||
Updated for lates core changes.
|
||||
__NOTE:__ Arduino drivers has now been converted to Arduino libraries, [installation and compilation procedure](https://github.com/grblHAL/core/wiki/Compiling-GrblHAL) has been changed!
|
||||
|
||||
---
|
||||
@@ -83,4 +83,4 @@ List of Supported G-Codes:
|
||||
Some [plugins](https://github.com/grblHAL/plugins) implements additional M-codes.
|
||||
|
||||
---
|
||||
2021-11-21
|
||||
2021-11-22
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
## grblHAL changelog
|
||||
|
||||
Build 20211122:
|
||||
|
||||
Core:
|
||||
|
||||
* Fixed silly typedef mistake in setting struct, added settings $392 and $393 for spindle and coolant startup delays on safety door open.
|
||||
* Removed Grbl v0.9 error messages.
|
||||
|
||||
Drivers:
|
||||
|
||||
* Added setting $308 for FTP port to use for networking capable drivers. Defaults to 21.
|
||||
* Fixed WebUI processor clock speed report in ESP32 driver, added FTP port, board name and driver version to same.
|
||||
|
||||
Build 20211121:
|
||||
|
||||
Core:
|
||||
|
||||
@@ -27,68 +27,68 @@
|
||||
#include "core_handlers.h"
|
||||
|
||||
PROGMEM static const status_detail_t status_detail[] = {
|
||||
{ Status_OK, "ok", NULL },
|
||||
{ Status_ExpectedCommandLetter, "Expected command letter", "G-code words consist of a letter and a value. Letter was not found." },
|
||||
{ Status_BadNumberFormat, "Bad number format", "Missing the expected G-code word value or numeric value format is not valid." },
|
||||
{ Status_InvalidStatement, "Invalid statement", "'$' system command was not recognized or supported." },
|
||||
{ Status_NegativeValue, "Value < 0", "Negative value received for an expected positive value." },
|
||||
{ Status_HomingDisabled, "Homing disabled", "Homing cycle failure. Homing is not configured via settings." },
|
||||
{ Status_SettingStepPulseMin, "Value < 2 microseconds", "Step pulse time must be greater or equal to 2 microseconds." },
|
||||
{ Status_SettingReadFail, "Settings read failed. Using defaults", "A settings read failed. Auto-restoring affected settings to default values." },
|
||||
{ Status_IdleError, "Not idle", "'$' command cannot be used unless controller state is IDLE. Ensures smooth operation during a job." },
|
||||
{ Status_SystemGClock, "G-code lock", "G-code commands are locked out during alarm or jog state." },
|
||||
{ Status_SoftLimitError, "Homing not enabled", "Soft limits cannot be enabled without homing also enabled." },
|
||||
{ Status_Overflow, "Line overflow", "Max characters per line exceeded. Received command line was not executed." },
|
||||
{ Status_MaxStepRateExceeded, "Max step rate too high", "'$' setting value cause the step rate to exceed the maximum supported." },
|
||||
{ Status_CheckDoor, "Check Door", "Safety door detected as opened and door state initiated." },
|
||||
{ Status_LineLengthExceeded, "Line length exceeded", "Build info or startup line exceeded line length limit. Line not stored." },
|
||||
{ Status_TravelExceeded, "Travel exceeded", "Jog target exceeds machine travel. Jog command has been ignored." },
|
||||
{ Status_InvalidJogCommand, "Invalid jog command", "Jog command has no '=' or contains prohibited g-code." },
|
||||
{ Status_SettingDisabledLaser, "Setting disabled", "Laser mode requires PWM output." },
|
||||
{ Status_Reset, "Reset asserted", "" },
|
||||
{ Status_NonPositiveValue, "Non positive value", "" },
|
||||
{ Status_GcodeUnsupportedCommand, "Unsupported command", "Unsupported or invalid g-code command found in block." },
|
||||
{ Status_GcodeModalGroupViolation, "Modal group violation", "More than one g-code command from same modal group found in block." },
|
||||
{ Status_GcodeUndefinedFeedRate, "Undefined feed rate", "Feed rate has not yet been set or is undefined." },
|
||||
{ Status_GcodeCommandValueNotInteger, "Invalid gcode ID:23", "G-code command in block requires an integer value." },
|
||||
{ Status_GcodeAxisCommandConflict, "Invalid gcode ID:24", "More than one g-code command that requires axis words found in block." },
|
||||
{ Status_GcodeWordRepeated, "Invalid gcode ID:25", "Repeated g-code word found in block." },
|
||||
{ Status_GcodeNoAxisWords, "Invalid gcode ID:26", "No axis words found in block for g-code command or current modal state which requires them." },
|
||||
{ Status_GcodeInvalidLineNumber, "Invalid gcode ID:27", "Line number value is invalid." },
|
||||
{ Status_GcodeValueWordMissing, "Invalid gcode ID:28", "G-code command is missing a required value word." },
|
||||
{ Status_GcodeUnsupportedCoordSys, "Invalid gcode ID:29", "G59.x work coordinate systems are not supported." },
|
||||
{ Status_GcodeG53InvalidMotionMode, "Invalid gcode ID:30", "G53 only allowed with G0 and G1 motion modes." },
|
||||
{ Status_GcodeAxisWordsExist, "Invalid gcode ID:31", "Axis words found in block when no command or current modal state uses them." },
|
||||
{ Status_GcodeNoAxisWordsInPlane, "Invalid gcode ID:32", "G2 and G3 arcs require at least one in-plane axis word." },
|
||||
{ Status_GcodeInvalidTarget, "Invalid gcode ID:33", "Motion command target is invalid." },
|
||||
{ Status_GcodeArcRadiusError, "Invalid gcode ID:34", "Arc radius value is invalid." },
|
||||
{ Status_GcodeNoOffsetsInPlane, "Invalid gcode ID:35", "G2 and G3 arcs require at least one in-plane offset word." },
|
||||
{ Status_GcodeUnusedWords, "Invalid gcode ID:36", "Unused value words found in block." },
|
||||
{ Status_GcodeG43DynamicAxisError, "Invalid gcode ID:37", "G43.1 dynamic tool length offset is not assigned to configured tool length axis." },
|
||||
{ Status_GcodeIllegalToolTableEntry, "Invalid gcode ID:38", "Tool number greater than max supported value or undefined tool selected." },
|
||||
{ Status_GcodeValueOutOfRange, "Invalid gcode ID:39", "Value out of range." },
|
||||
{ Status_GcodeToolChangePending, "Invalid gcode ID:40", "G-code command not allowed when tool change is pending." },
|
||||
{ Status_GcodeSpindleNotRunning, "Invalid gcode ID:41", "Spindle not running when motion commanded in CSS or spindle sync mode." },
|
||||
{ Status_GcodeIllegalPlane, "Invalid gcode ID:42", "Plane must be ZX for threading." },
|
||||
{ Status_GcodeMaxFeedRateExceeded, "Invalid gcode ID:43", "Max. feed rate exceeded." },
|
||||
{ Status_GcodeRPMOutOfRange, "Invalid gcode ID:44", "RPM out of range." },
|
||||
{ Status_LimitsEngaged, "Limit switch engaged", "Only homing is allowed when a limit switch is engaged." },
|
||||
{ Status_HomingRequired, "Homing required", "Home machine to continue." },
|
||||
{ Status_GCodeToolError, "Invalid gcode ID:47", "ATC: current tool is not set. Set current tool with M61." },
|
||||
{ Status_ValueWordConflict, "Invalid gcode ID:48", "Value word conflict." },
|
||||
{ Status_SelfTestFailed, "Self test failed", "Power on self test failed. A hard reset is required." },
|
||||
{ Status_EStop, "E-stop", "Emergency stop active." },
|
||||
{ Status_MotorFault, "Motor fault", "Motor fault." },
|
||||
{ Status_SettingValueOutOfRange, "Value out of range.", "Setting value is out of range." },
|
||||
{ Status_SettingDisabled, "Setting disabled", "Setting is not available, possibly due to limited driver support." },
|
||||
{ Status_GcodeInvalidRetractPosition, "Invalid gcode ID:54", "Retract position is less than drill depth." },
|
||||
{ Status_OK, NULL },
|
||||
{ Status_ExpectedCommandLetter, "G-code words consist of a letter and a value. Letter was not found." },
|
||||
{ Status_BadNumberFormat, "Missing the expected G-code word value or numeric value format is not valid." },
|
||||
{ Status_InvalidStatement, "'$' system command was not recognized or supported." },
|
||||
{ Status_NegativeValue, "Negative value received for an expected positive value." },
|
||||
{ Status_HomingDisabled, "Homing cycle failure. Homing is not configured via settings." },
|
||||
{ Status_SettingStepPulseMin, "Step pulse time must be greater or equal to 2 microseconds." },
|
||||
{ Status_SettingReadFail, "A settings read failed. Auto-restoring affected settings to default values." },
|
||||
{ Status_IdleError, "'$' command cannot be used unless controller state is IDLE. Ensures smooth operation during a job." },
|
||||
{ Status_SystemGClock, "G-code commands are locked out during alarm or jog state." },
|
||||
{ Status_SoftLimitError, "Soft limits cannot be enabled without homing also enabled." },
|
||||
{ Status_Overflow, "Max characters per line exceeded. Received command line was not executed." },
|
||||
{ Status_MaxStepRateExceeded, "'$' setting value cause the step rate to exceed the maximum supported." },
|
||||
{ Status_CheckDoor, "Safety door detected as opened and door state initiated." },
|
||||
{ Status_LineLengthExceeded, "Build info or startup line exceeded line length limit. Line not stored." },
|
||||
{ Status_TravelExceeded, "Jog target exceeds machine travel. Jog command has been ignored." },
|
||||
{ Status_InvalidJogCommand, "Jog command has no '=' or contains prohibited g-code." },
|
||||
{ Status_SettingDisabledLaser, "Laser mode requires PWM output." },
|
||||
{ Status_Reset, "Reset asserted" },
|
||||
{ Status_NonPositiveValue, "Non positive value" },
|
||||
{ Status_GcodeUnsupportedCommand, "Unsupported or invalid g-code command found in block." },
|
||||
{ Status_GcodeModalGroupViolation, "More than one g-code command from same modal group found in block." },
|
||||
{ Status_GcodeUndefinedFeedRate, "Feed rate has not yet been set or is undefined." },
|
||||
{ Status_GcodeCommandValueNotInteger, "G-code command in block requires an integer value." },
|
||||
{ Status_GcodeAxisCommandConflict, "More than one g-code command that requires axis words found in block." },
|
||||
{ Status_GcodeWordRepeated, "Repeated g-code word found in block." },
|
||||
{ Status_GcodeNoAxisWords, "No axis words found in block for g-code command or current modal state which requires them." },
|
||||
{ Status_GcodeInvalidLineNumber, "Line number value is invalid." },
|
||||
{ Status_GcodeValueWordMissing, "G-code command is missing a required value word." },
|
||||
{ Status_GcodeUnsupportedCoordSys, "G59.x work coordinate systems are not supported." },
|
||||
{ Status_GcodeG53InvalidMotionMode, "G53 only allowed with G0 and G1 motion modes." },
|
||||
{ Status_GcodeAxisWordsExist, "Axis words found in block when no command or current modal state uses them." },
|
||||
{ Status_GcodeNoAxisWordsInPlane, "G2 and G3 arcs require at least one in-plane axis word." },
|
||||
{ Status_GcodeInvalidTarget, "Motion command target is invalid." },
|
||||
{ Status_GcodeArcRadiusError, "Arc radius value is invalid." },
|
||||
{ Status_GcodeNoOffsetsInPlane, "G2 and G3 arcs require at least one in-plane offset word." },
|
||||
{ Status_GcodeUnusedWords, "Unused value words found in block." },
|
||||
{ Status_GcodeG43DynamicAxisError, "G43.1 dynamic tool length offset is not assigned to configured tool length axis." },
|
||||
{ Status_GcodeIllegalToolTableEntry, "Tool number greater than max supported value or undefined tool selected." },
|
||||
{ Status_GcodeValueOutOfRange, "Value out of range." },
|
||||
{ Status_GcodeToolChangePending, "G-code command not allowed when tool change is pending." },
|
||||
{ Status_GcodeSpindleNotRunning, "Spindle not running when motion commanded in CSS or spindle sync mode." },
|
||||
{ Status_GcodeIllegalPlane, "Plane must be ZX for threading." },
|
||||
{ Status_GcodeMaxFeedRateExceeded, "Max. feed rate exceeded." },
|
||||
{ Status_GcodeRPMOutOfRange, "RPM out of range." },
|
||||
{ Status_LimitsEngaged, "Only homing is allowed when a limit switch is engaged." },
|
||||
{ Status_HomingRequired, "Home machine to continue." },
|
||||
{ Status_GCodeToolError, "ATC: current tool is not set. Set current tool with M61." },
|
||||
{ Status_ValueWordConflict, "Value word conflict." },
|
||||
{ Status_SelfTestFailed, "Power on self test failed. A hard reset is required." },
|
||||
{ Status_EStop, "Emergency stop active." },
|
||||
{ Status_MotorFault, "Motor fault." },
|
||||
{ Status_SettingValueOutOfRange, "Setting value is out of range." },
|
||||
{ Status_SettingDisabled, "Setting is not available, possibly due to limited driver support." },
|
||||
{ Status_GcodeInvalidRetractPosition, "Retract position is less than drill depth." },
|
||||
#if NGC_EXPRESSIONS_ENABLE
|
||||
{ Status_ExpressionUknownOp, "Unknown operation found in expression", "Unknown operation found in expression." },
|
||||
{ Status_ExpressionDivideByZero, "Divide by zero in expression", "Divide by zero in expression attempted." },
|
||||
{ Status_ExpressionArgumentOutOfRange, "Expression argument out of range", "Too large or too small argrument provided." },
|
||||
{ Status_ExpressionInvalidArgument, "Invalid expression argument", "Argument is not valid for the operation" },
|
||||
{ Status_ExpressionSyntaxError, "Syntax error in expression", "Expression is not valid." },
|
||||
{ Status_ExpressionInvalidResult, "Invalid result returned from expression", "Either NAN (not a number) or infinity was returned from expression." }
|
||||
{ Status_ExpressionUknownOp, "Unknown operation found in expression." },
|
||||
{ Status_ExpressionDivideByZero, "Divide by zero in expression attempted." },
|
||||
{ Status_ExpressionArgumentOutOfRange, "Too large or too small argrument provided." },
|
||||
{ Status_ExpressionInvalidArgument, "Argument is not valid for the operation" },
|
||||
{ Status_ExpressionSyntaxError, "Expression is not valid." },
|
||||
{ Status_ExpressionInvalidResult, "Either NAN (not a number) or infinity was returned from expression." }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -108,7 +108,6 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
status_code_t id;
|
||||
const char *xname;
|
||||
const char *description;
|
||||
} status_detail_t;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#else
|
||||
#define GRBL_VERSION "1.1f"
|
||||
#endif
|
||||
#define GRBL_BUILD 20211121
|
||||
#define GRBL_BUILD 20211122
|
||||
|
||||
// The following symbols are set here if not already set by the compiler or in config.h
|
||||
// Do NOT change here!
|
||||
|
||||
+13
-3
@@ -505,6 +505,10 @@ PROGMEM static const setting_detail_t setting_detail[] = {
|
||||
#elif N_AXIS > 5
|
||||
{ Settings_Axis_Rotational, Group_Stepper, "Rotational axes", NULL, Format_Bitfield, "A-Axis,B-Axis,C-Axis", NULL, NULL, Setting_IsExtendedFn, set_rotational_axes, get_int, NULL },
|
||||
#endif
|
||||
#ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
|
||||
{ Setting_DoorSpindleOnDelay, Group_SafetyDoor, "Spindle on delay", "s", Format_Decimal, "#0.0", "0.5", "20", Setting_IsExtended, &settings.safety_door.spindle_on_delay, NULL, NULL },
|
||||
{ Setting_DoorCoolantOnDelay, Group_SafetyDoor, "Coolant on delay", "s", Format_Decimal, "#0.0", "0.5", "20", Setting_IsExtended, &settings.safety_door.coolant_on_delay, NULL, NULL },
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifndef NO_SETTINGS_DESCRIPTIONS
|
||||
@@ -516,16 +520,18 @@ PROGMEM static const setting_descr_t setting_descr[] = {
|
||||
{ Setting_StepperIdleLockTime, "Sets a short hold delay when stopping to let dynamics settle before disabling steppers. Value 255 keeps motors enabled." },
|
||||
{ Setting_StepInvertMask, "Inverts the step signals (active low)." },
|
||||
{ Setting_DirInvertMask, "Inverts the direction signals (active low)." },
|
||||
{ Setting_InvertStepperEnable, "Inverts the stepper driver enable signals. Most drivers uses active low enable requiring inversion.\\n"
|
||||
{ Setting_InvertStepperEnable, "Inverts the stepper driver enable signals. Most drivers uses active low enable requiring inversion.\\n\\n"
|
||||
"NOTE: If the stepper drivers shares the same enable signal only X is used."
|
||||
},
|
||||
{ Setting_LimitPinsInvertMask, "Inverts the axis limit input signals." },
|
||||
{ Setting_InvertProbePin, "Inverts the probe input pin signal." },
|
||||
{ Setting_SpindlePWMBehaviour, "" },
|
||||
{ Setting_GangedDirInvertMask, "Inverts the direction signals for ganged axes." },
|
||||
{ Setting_GangedDirInvertMask, "Inverts the direction signals for the second motor used for ganged axes.\\n\\n"
|
||||
"NOTE: This inversion will be applied in addition to the inversion from setting $3."
|
||||
},
|
||||
{ Setting_StatusReportMask, "Specifies optional data included in status reports.\\n"
|
||||
"If Run substatus is enabled it may be used for simple probe protection.\\n\\n"
|
||||
"Note that Parser state will be sent separately after the status report and only on changes."
|
||||
"NOTE: Parser state will be sent separately after the status report and only on changes."
|
||||
},
|
||||
{ Setting_JunctionDeviation, "Sets how fast Grbl travels through consecutive motions. Lower value slows it down." },
|
||||
{ Setting_ArcTolerance, "Sets the G2 and G3 arc tracing accuracy based on radial error. Beware: A very small value may effect performance." },
|
||||
@@ -636,6 +642,10 @@ PROGMEM static const setting_descr_t setting_descr[] = {
|
||||
#if COMPATIBILITY_LEVEL <= 1
|
||||
{ Setting_DisableG92Persistence, "Disables save/restore of G92 offset to non-volatile storage (NVS)." },
|
||||
#endif
|
||||
#ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
|
||||
{ Setting_DoorSpindleOnDelay, "Delay to allow spindle to spin up after safety door is opened." },
|
||||
{ Setting_DoorCoolantOnDelay, "Delay to allow coolant to restart after safety door is opened." },
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+8
-3
@@ -169,6 +169,7 @@ typedef enum {
|
||||
Setting_TelnetPort = 305,
|
||||
Setting_HttpPort = 306,
|
||||
Setting_WebSocketPort = 307,
|
||||
Setting_FtpPort = 308,
|
||||
|
||||
// Normally used for WiFi Access Point
|
||||
Setting_Hostname2 = 310,
|
||||
@@ -179,6 +180,7 @@ typedef enum {
|
||||
Setting_TelnetPort2 = 315,
|
||||
Setting_HttpPort2 = 316,
|
||||
Setting_WebSocketPort2 = 317,
|
||||
Setting_FtpPort2 = 318,
|
||||
|
||||
Setting_Hostname3 = 320,
|
||||
Setting_IpMode3 = 321,
|
||||
@@ -188,6 +190,7 @@ typedef enum {
|
||||
Setting_TelnetPort3 = 325,
|
||||
Setting_HttpPort3 = 326,
|
||||
Setting_WebSocketPort3 = 327,
|
||||
Setting_FtpPort3 = 328,
|
||||
|
||||
Setting_AdminPassword = 330,
|
||||
Setting_UserPassword = 331,
|
||||
@@ -249,6 +252,8 @@ typedef enum {
|
||||
Setting_FanPort3 = 389,
|
||||
Setting_CoolantTempPort = 390,
|
||||
Setting_CoolantOkPort = 391,
|
||||
Setting_DoorSpindleOnDelay = 392,
|
||||
Setting_DoorCoolantOnDelay = 393,
|
||||
|
||||
Setting_EncoderSettingsBase = 400, // NOTE: Reserving settings values >= 400 for encoder settings. Up to 449.
|
||||
Setting_EncoderSettingsMax = 449,
|
||||
@@ -319,13 +324,13 @@ typedef union {
|
||||
struct {
|
||||
uint16_t report_inches :1,
|
||||
restore_overrides :1,
|
||||
safety_door_ignore_when_idle :1,
|
||||
unused0 :1,
|
||||
sleep_enable :1,
|
||||
disable_laser_during_hold :1,
|
||||
force_initialization_alarm :1,
|
||||
legacy_rt_commands :1,
|
||||
restore_after_feed_hold :1,
|
||||
keep_coolant_state_on_door_open :1,
|
||||
unused1 :1,
|
||||
g92_is_volatile :1,
|
||||
unassigned :6;
|
||||
};
|
||||
@@ -372,7 +377,7 @@ typedef union {
|
||||
};
|
||||
} safety_door_setting_flags_t;
|
||||
|
||||
typedef union {
|
||||
typedef struct {
|
||||
safety_door_setting_flags_t flags;
|
||||
float spindle_on_delay;
|
||||
float coolant_on_delay;
|
||||
|
||||
+3
-3
@@ -455,13 +455,13 @@ static void state_await_hold (uint_fast16_t rt_exec)
|
||||
// Parking motion not possible. Just disable the spindle and coolant.
|
||||
// NOTE: Laser mode does not start a parking motion to ensure the laser stops immediately.
|
||||
hal.spindle.set_state((spindle_state_t){0}, 0.0f); // De-energize
|
||||
if (!settings.flags.keep_coolant_state_on_door_open)
|
||||
if (!settings.safety_door.flags.keep_coolant_on)
|
||||
hal.coolant.set_state((coolant_state_t){0}); // De-energize
|
||||
sys.parking_state = hal.control.get_state().safety_door_ajar ? Parking_DoorAjar : Parking_DoorClosed;
|
||||
}
|
||||
} else {
|
||||
hal.spindle.set_state((spindle_state_t){0}, 0.0f); // De-energize
|
||||
if (!settings.flags.keep_coolant_state_on_door_open)
|
||||
if (!settings.safety_door.flags.keep_coolant_on)
|
||||
hal.coolant.set_state((coolant_state_t){0}); // De-energize
|
||||
sys.parking_state = hal.control.get_state().safety_door_ajar ? Parking_DoorAjar : Parking_DoorClosed;
|
||||
}
|
||||
@@ -634,7 +634,7 @@ static void state_await_waypoint_retract (uint_fast16_t rt_exec)
|
||||
park.plan_data.spindle.rpm = 0.0f;
|
||||
hal.spindle.set_state(park.plan_data.condition.spindle, 0.0f); // De-energize
|
||||
|
||||
if (!settings.flags.keep_coolant_state_on_door_open) {
|
||||
if (!settings.safety_door.flags.keep_coolant_on) {
|
||||
park.plan_data.condition.coolant.value = 0;
|
||||
hal.coolant.set_state(park.plan_data.condition.coolant); // De-energize
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user