diff --git a/firmware/controllers/actuators/electronic_throttle.cpp b/firmware/controllers/actuators/electronic_throttle.cpp index ed4cf7fd41..e2f38df9aa 100644 --- a/firmware/controllers/actuators/electronic_throttle.cpp +++ b/firmware/controllers/actuators/electronic_throttle.cpp @@ -104,6 +104,10 @@ static pedal2tps_t pedal2tpsMap("Pedal2Tps", 1); EXTERN_ENGINE; +static bool startupPositionError = false; + +#define STARTUP_NEUTRAL_POSITION_ERROR_THRESHOLD 1 + class EtbControl { private: OutputPin m_pinEnable; @@ -193,6 +197,11 @@ static percent_t currentEtbDuty; #endif /* EFI_TUNER_STUDIO */ } + if (startupPositionError) { + etb1.dcMotor.Set(0); + return; + } + if (shouldResetPid) { etbPid.reset(); shouldResetPid = false; @@ -572,6 +581,17 @@ void initElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE) { } autoTune.SetOutputStep(0.1); + percent_t startupThrottlePosition = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE); + if (absF(startupThrottlePosition - engineConfiguration->etbNeutralPosition) > STARTUP_NEUTRAL_POSITION_ERROR_THRESHOLD) { + /** + * Unexpected electronic throttle start-up position is worth a fatal error + */ + firmwareError(OBD_Throttle_Actuator_Control_Range_Performance_Bank_1, "startup ETB position %.2f not %d", + startupThrottlePosition, + engineConfiguration->etbNeutralPosition); + startupPositionError = true; + } + startETBPins(PASS_ENGINE_PARAMETER_SIGNATURE); tuneWorkingPidSettings.pFactor = 1; diff --git a/firmware/controllers/algo/obd_error_codes.h b/firmware/controllers/algo/obd_error_codes.h index 8451f87fa5..018ca1bf68 100644 --- a/firmware/controllers/algo/obd_error_codes.h +++ b/firmware/controllers/algo/obd_error_codes.h @@ -668,7 +668,7 @@ typedef enum { //P0635 Power Steering Control Circuit //P0636 Power Steering Control Circuit Low //P0637 Power Steering Control Circuit High - //P0638 Throttle Actuator Control Range/Performance (Bank 1) + OBD_Throttle_Actuator_Control_Range_Performance_Bank_1 = 638, //P0639 Throttle Actuator Control Range/Performance (Bank 2) //P0640 Intake Air Heater Control Circuit //P0641 Sensor Reference Voltage “A” Circuit/Open diff --git a/firmware/controllers/generated/engine_configuration_generated_structures.h b/firmware/controllers/generated/engine_configuration_generated_structures.h index 3e7812cd51..faeb906803 100644 --- a/firmware/controllers/generated/engine_configuration_generated_structures.h +++ b/firmware/controllers/generated/engine_configuration_generated_structures.h @@ -1,4 +1,4 @@ -// this section was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Fri Sep 20 21:55:21 EDT 2019 +// this section was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Sun Sep 22 22:54:07 EDT 2019 // by class com.rusefi.output.CHeaderConsumer // begin #ifndef CONTROLLERS_GENERATED_ENGINE_CONFIGURATION_GENERATED_STRUCTURES_H @@ -1592,9 +1592,10 @@ struct engine_configuration_s { */ adc_channel_e vRefAdcChannel; /** + * Expected neutral position * offset 1471 */ - uint8_t unusedh; + uint8_t etbNeutralPosition; /** * See also idleRpmPid * offset 1472 @@ -2828,4 +2829,4 @@ typedef struct persistent_config_s persistent_config_s; #endif // end -// this section was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Fri Sep 20 21:55:21 EDT 2019 +// this section was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Sun Sep 22 22:54:07 EDT 2019 diff --git a/firmware/controllers/generated/rusefi_generated.h b/firmware/controllers/generated/rusefi_generated.h index 39b6c3c64e..c763769535 100644 --- a/firmware/controllers/generated/rusefi_generated.h +++ b/firmware/controllers/generated/rusefi_generated.h @@ -553,6 +553,8 @@ #define etbIdleRange_offset_hex 3cc #define etbIdleThrottleRange_offset 4012 #define etbIdleThrottleRange_offset_hex fac +#define etbNeutralPosition_offset 1471 +#define etbNeutralPosition_offset_hex 5bf #define externalKnockSenseAdc_offset 3103 #define externalKnockSenseAdc_offset_hex c1f #define extraInjectionOffset_offset 432 @@ -1891,8 +1893,6 @@ #define unusedFlexFuelSensor_offset_hex c1c #define unusedFormerWarmupAfrPid_offset 1756 #define unusedFormerWarmupAfrPid_offset_hex 6dc -#define unusedh_offset 1471 -#define unusedh_offset_hex 5bf #define unusedMa2_offset 711 #define unusedMa2_offset_hex 2c7 #define unusedOldWarmupAfr_offset 744 diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 696b6e03f6..7a752d6749 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -743,7 +743,7 @@ bit useFSIO13ForIdleMinValue; adc_channel_e hipOutputChannel; adc_channel_e acSwitchAdc;A/C button input handled as analogue input adc_channel_e vRefAdcChannel; -uint8_t[1] unusedh; + uint8_t etbNeutralPosition;+Expected neutral position;"%", 1, 0, 0, 100, 0 custom idle_mode_e 4 bits, U32, @OFFSET@, [0:0], "Automatic", "Manual" idle_mode_e idleMode;See also idleRpmPid; diff --git a/firmware/tunerstudio/rusefi.ini b/firmware/tunerstudio/rusefi.ini index 6dd726ae83..36637f6dfa 100644 --- a/firmware/tunerstudio/rusefi.ini +++ b/firmware/tunerstudio/rusefi.ini @@ -82,7 +82,7 @@ enable2ndByteCanID = false ; see PAGE_0_SIZE in C source code ; CONFIG_DEFINITION_START -; this section was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Fri Sep 20 21:57:50 EDT 2019 +; this section was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Sun Sep 22 22:54:07 EDT 2019 pageSize = 20000 page = 1 @@ -533,7 +533,7 @@ page = 1 hipOutputChannel = bits, U08, 1468, [0:4] "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PB0", "PB1", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "Disabled", "PB12", "PB13", "PC14", "PC15", "PC16", "PC17", "PD3", "PD4", "PE2", "PE6", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" acSwitchAdc = bits, U08, 1469, [0:4] "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PB0", "PB1", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "Disabled", "PB12", "PB13", "PC14", "PC15", "PC16", "PC17", "PD3", "PD4", "PE2", "PE6", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" vRefAdcChannel = bits, U08, 1470, [0:4] "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PB0", "PB1", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "Disabled", "PB12", "PB13", "PC14", "PC15", "PC16", "PC17", "PD3", "PD4", "PE2", "PE6", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" -;no TS info - skipping unusedh offset 1471 + etbNeutralPosition = scalar, U08, 1471, "%", 1, 0, 0, 100, 0 idleMode = bits, U32, 1472, [0:0], "Automatic", "Manual" isInjectionEnabled = bits, U32, 1476, [0:0], "false", "true" isIgnitionEnabled = bits, U32, 1476, [1:1], "false", "true" @@ -1025,6 +1025,7 @@ page = 1 isAlternatorControlEnabled = "This enables smart alternator control and activates the extra alternator settings." invertPrimaryTriggerSignal = "This setting flips the signal from the primary engine speed sensor." invertSecondaryTriggerSignal = "This setting flips the signal from the secondary engine speed sensor." + etbNeutralPosition = "Expected neutral position" isInjectionEnabled = "Enable fuel injection - This is default off for new projects as a safety feature, set to "true" to enable fuel injection and further injector settings." isIgnitionEnabled = "Enable ignition - This is default off for new projects as a safety feature, set to "true" to enable ignition and further ignition settings." isCylinderCleanupEnabled = "When enabled if TPS is held above 95% no fuel is injected while cranking to clear excess fuel from the cylinders." @@ -3458,6 +3459,7 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" dialog = etbDialogRight field = "!https://rusefi.com/s/debugmode" + field = "Neutral Position", etbNeutralPosition field = "Debug mode", debugMode field = "use ETB for idle", useETBforIdleControl field = "ETB idle maximum angle", etbIdleRange diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index 6f8a30f266..fff96acac4 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -2467,6 +2467,7 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" dialog = etbDialogRight field = "!https://rusefi.com/s/debugmode" + field = "Neutral Position", etbNeutralPosition field = "Debug mode", debugMode field = "use ETB for idle", useETBforIdleControl field = "ETB idle maximum angle", etbIdleRange diff --git a/firmware/tunerstudio/rusefi_frankenso.ini b/firmware/tunerstudio/rusefi_frankenso.ini index 0c91db2dc5..9627ba2327 100644 --- a/firmware/tunerstudio/rusefi_frankenso.ini +++ b/firmware/tunerstudio/rusefi_frankenso.ini @@ -82,7 +82,7 @@ enable2ndByteCanID = false ; see PAGE_0_SIZE in C source code ; CONFIG_DEFINITION_START -; this section was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Fri Sep 20 21:57:58 EDT 2019 +; this section was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Sun Sep 22 22:54:52 EDT 2019 pageSize = 20000 page = 1 @@ -533,7 +533,7 @@ page = 1 hipOutputChannel = bits, U08, 1468, [0:4] "Analog 3O","Analog 3L","Analog 3M","Analog 3J","Analog 3I","INVALID","Analog 3H","Analog 3G","INVALID","INVALID","INVALID","Analog 3P","Analog 3Q","Analog 3N","Analog VBatt","Analog 3E","NONE","INVALID","INVALID","INVALID" acSwitchAdc = bits, U08, 1469, [0:4] "Analog 3O","Analog 3L","Analog 3M","Analog 3J","Analog 3I","INVALID","Analog 3H","Analog 3G","INVALID","INVALID","INVALID","Analog 3P","Analog 3Q","Analog 3N","Analog VBatt","Analog 3E","NONE","INVALID","INVALID","INVALID" vRefAdcChannel = bits, U08, 1470, [0:4] "Analog 3O","Analog 3L","Analog 3M","Analog 3J","Analog 3I","INVALID","Analog 3H","Analog 3G","INVALID","INVALID","INVALID","Analog 3P","Analog 3Q","Analog 3N","Analog VBatt","Analog 3E","NONE","INVALID","INVALID","INVALID" -;no TS info - skipping unusedh offset 1471 + etbNeutralPosition = scalar, U08, 1471, "%", 1, 0, 0, 100, 0 idleMode = bits, U32, 1472, [0:0], "Automatic", "Manual" isInjectionEnabled = bits, U32, 1476, [0:0], "false", "true" isIgnitionEnabled = bits, U32, 1476, [1:1], "false", "true" @@ -1025,6 +1025,7 @@ page = 1 isAlternatorControlEnabled = "This enables smart alternator control and activates the extra alternator settings." invertPrimaryTriggerSignal = "This setting flips the signal from the primary engine speed sensor." invertSecondaryTriggerSignal = "This setting flips the signal from the secondary engine speed sensor." + etbNeutralPosition = "Expected neutral position" isInjectionEnabled = "Enable fuel injection - This is default off for new projects as a safety feature, set to "true" to enable fuel injection and further injector settings." isIgnitionEnabled = "Enable ignition - This is default off for new projects as a safety feature, set to "true" to enable ignition and further ignition settings." isCylinderCleanupEnabled = "When enabled if TPS is held above 95% no fuel is injected while cranking to clear excess fuel from the cylinders." @@ -3458,6 +3459,7 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" dialog = etbDialogRight field = "!https://rusefi.com/s/debugmode" + field = "Neutral Position", etbNeutralPosition field = "Debug mode", debugMode field = "use ETB for idle", useETBforIdleControl field = "ETB idle maximum angle", etbIdleRange diff --git a/firmware/tunerstudio/rusefi_microrusefi.ini b/firmware/tunerstudio/rusefi_microrusefi.ini index 25dcd570f3..f3206df6e4 100644 --- a/firmware/tunerstudio/rusefi_microrusefi.ini +++ b/firmware/tunerstudio/rusefi_microrusefi.ini @@ -82,7 +82,7 @@ enable2ndByteCanID = false ; see PAGE_0_SIZE in C source code ; CONFIG_DEFINITION_START -; this section was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Fri Sep 20 21:55:25 EDT 2019 +; this section was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Sun Sep 22 22:54:29 EDT 2019 pageSize = 20000 page = 1 @@ -533,7 +533,7 @@ page = 1 hipOutputChannel = bits, U08, 1468, [0:4] "18 - AN temp 1","23 - AN temp 2","24 - AN temp 3","22 - AN temp 4","28 - AN volt 10","INVALID","26 - AN volt 2","31 - AN volt 3","36 - AN volt 8","40 - AN volt 9","27 - AN volt 1","Battery Sense","19 - AN volt 4","20 - AN volt 5","32 - AN volt 6","30 - AN volt 7","NONE","INVALID","INVALID","INVALID" acSwitchAdc = bits, U08, 1469, [0:4] "18 - AN temp 1","23 - AN temp 2","24 - AN temp 3","22 - AN temp 4","28 - AN volt 10","INVALID","26 - AN volt 2","31 - AN volt 3","36 - AN volt 8","40 - AN volt 9","27 - AN volt 1","Battery Sense","19 - AN volt 4","20 - AN volt 5","32 - AN volt 6","30 - AN volt 7","NONE","INVALID","INVALID","INVALID" vRefAdcChannel = bits, U08, 1470, [0:4] "18 - AN temp 1","23 - AN temp 2","24 - AN temp 3","22 - AN temp 4","28 - AN volt 10","INVALID","26 - AN volt 2","31 - AN volt 3","36 - AN volt 8","40 - AN volt 9","27 - AN volt 1","Battery Sense","19 - AN volt 4","20 - AN volt 5","32 - AN volt 6","30 - AN volt 7","NONE","INVALID","INVALID","INVALID" -;no TS info - skipping unusedh offset 1471 + etbNeutralPosition = scalar, U08, 1471, "%", 1, 0, 0, 100, 0 idleMode = bits, U32, 1472, [0:0], "Automatic", "Manual" isInjectionEnabled = bits, U32, 1476, [0:0], "false", "true" isIgnitionEnabled = bits, U32, 1476, [1:1], "false", "true" @@ -1025,6 +1025,7 @@ page = 1 isAlternatorControlEnabled = "This enables smart alternator control and activates the extra alternator settings." invertPrimaryTriggerSignal = "This setting flips the signal from the primary engine speed sensor." invertSecondaryTriggerSignal = "This setting flips the signal from the secondary engine speed sensor." + etbNeutralPosition = "Expected neutral position" isInjectionEnabled = "Enable fuel injection - This is default off for new projects as a safety feature, set to "true" to enable fuel injection and further injector settings." isIgnitionEnabled = "Enable ignition - This is default off for new projects as a safety feature, set to "true" to enable ignition and further ignition settings." isCylinderCleanupEnabled = "When enabled if TPS is held above 95% no fuel is injected while cranking to clear excess fuel from the cylinders." @@ -3441,6 +3442,7 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" dialog = etbDialogRight field = "!https://rusefi.com/s/debugmode" + field = "Neutral Position", etbNeutralPosition field = "Debug mode", debugMode field = "use ETB for idle", useETBforIdleControl field = "ETB idle maximum angle", etbIdleRange diff --git a/firmware/tunerstudio/rusefi_prometheus.ini b/firmware/tunerstudio/rusefi_prometheus.ini index 420e482936..95d80749d4 100644 --- a/firmware/tunerstudio/rusefi_prometheus.ini +++ b/firmware/tunerstudio/rusefi_prometheus.ini @@ -82,7 +82,7 @@ enable2ndByteCanID = false ; see PAGE_0_SIZE in C source code ; CONFIG_DEFINITION_START -; this section was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Fri Sep 20 21:58:01 EDT 2019 +; this section was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Sun Sep 22 22:55:15 EDT 2019 pageSize = 20000 page = 1 @@ -533,7 +533,7 @@ page = 1 hipOutputChannel = bits, U08, 1468, [0:4] "Analog 3O","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","NONE","INVALID","INVALID","INVALID" acSwitchAdc = bits, U08, 1469, [0:4] "Analog 3O","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","NONE","INVALID","INVALID","INVALID" vRefAdcChannel = bits, U08, 1470, [0:4] "Analog 3O","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","INVALID","NONE","INVALID","INVALID","INVALID" -;no TS info - skipping unusedh offset 1471 + etbNeutralPosition = scalar, U08, 1471, "%", 1, 0, 0, 100, 0 idleMode = bits, U32, 1472, [0:0], "Automatic", "Manual" isInjectionEnabled = bits, U32, 1476, [0:0], "false", "true" isIgnitionEnabled = bits, U32, 1476, [1:1], "false", "true" @@ -1025,6 +1025,7 @@ page = 1 isAlternatorControlEnabled = "This enables smart alternator control and activates the extra alternator settings." invertPrimaryTriggerSignal = "This setting flips the signal from the primary engine speed sensor." invertSecondaryTriggerSignal = "This setting flips the signal from the secondary engine speed sensor." + etbNeutralPosition = "Expected neutral position" isInjectionEnabled = "Enable fuel injection - This is default off for new projects as a safety feature, set to "true" to enable fuel injection and further injector settings." isIgnitionEnabled = "Enable ignition - This is default off for new projects as a safety feature, set to "true" to enable ignition and further ignition settings." isCylinderCleanupEnabled = "When enabled if TPS is held above 95% no fuel is injected while cranking to clear excess fuel from the cylinders." @@ -3454,6 +3455,7 @@ cmd_set_engine_type_default = "w\x00\x31\x00\x00" dialog = etbDialogRight field = "!https://rusefi.com/s/debugmode" + field = "Neutral Position", etbNeutralPosition field = "Debug mode", debugMode field = "use ETB for idle", useETBforIdleControl field = "ETB idle maximum angle", etbIdleRange diff --git a/java_console/models/src/com/rusefi/config/generated/Fields.java b/java_console/models/src/com/rusefi/config/generated/Fields.java index d326a46d30..88bebbcddd 100644 --- a/java_console/models/src/com/rusefi/config/generated/Fields.java +++ b/java_console/models/src/com/rusefi/config/generated/Fields.java @@ -1,6 +1,6 @@ package com.rusefi.config.generated; -// this file was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Sat Sep 21 21:56:11 EDT 2019 +// this file was generated automatically by rusEfi tool ConfigDefinition.jar based on integration\rusefi_config.txt Sun Sep 22 22:54:07 EDT 2019 // by class com.rusefi.output.FileJavaFieldsConsumer import com.rusefi.config.*; @@ -356,6 +356,7 @@ public class Fields { public static final int etbFreq_offset = 2514; public static final int etbIdleRange_offset = 972; public static final int etbIdleThrottleRange_offset = 4012; + public static final int etbNeutralPosition_offset = 1471; public static final int externalKnockSenseAdc_offset = 3103; public static final int extraInjectionOffset_offset = 432; public static final int fanOffTemperature_offset = 472; @@ -1232,7 +1233,6 @@ public class Fields { public static final int unusedErrorPin_offset = 2040; public static final int unusedFlexFuelSensor_offset = 3100; public static final int unusedFormerWarmupAfrPid_offset = 1756; - public static final int unusedh_offset = 1471; public static final int unusedMa2_offset = 711; public static final int unusedOldWarmupAfr_offset = 744; public static final int unusedSpiPadding2_offset = 806; @@ -1747,7 +1747,7 @@ public class Fields { public static final Field HIPOUTPUTCHANNEL = Field.create("HIPOUTPUTCHANNEL", 1468, FieldType.INT8, adc_channel_e); public static final Field ACSWITCHADC = Field.create("ACSWITCHADC", 1469, FieldType.INT8, adc_channel_e); public static final Field VREFADCCHANNEL = Field.create("VREFADCCHANNEL", 1470, FieldType.INT8, adc_channel_e); - public static final Field UNUSEDH = Field.create("UNUSEDH", 1471, FieldType.INT8); + public static final Field ETBNEUTRALPOSITION = Field.create("ETBNEUTRALPOSITION", 1471, FieldType.INT8); public static final Field IDLEMODE = Field.create("IDLEMODE", 1472, FieldType.INT); public static final Field ISINJECTIONENABLED = Field.create("ISINJECTIONENABLED", 1476, FieldType.BIT, 0); public static final Field ISIGNITIONENABLED = Field.create("ISIGNITIONENABLED", 1476, FieldType.BIT, 1); @@ -2527,7 +2527,7 @@ public class Fields { HIPOUTPUTCHANNEL, ACSWITCHADC, VREFADCCHANNEL, - UNUSEDH, + ETBNEUTRALPOSITION, IDLEMODE, ISINJECTIONENABLED, ISIGNITIONENABLED, diff --git a/java_console/ui/src/com/rusefi/ui/etb/EtbReturnToNeutral.java b/java_console/ui/src/com/rusefi/ui/etb/EtbReturnToNeutral.java index c023219a82..175919c4da 100644 --- a/java_console/ui/src/com/rusefi/ui/etb/EtbReturnToNeutral.java +++ b/java_console/ui/src/com/rusefi/ui/etb/EtbReturnToNeutral.java @@ -24,7 +24,8 @@ public class EtbReturnToNeutral { private JButton button = new JButton("ETB Spring Test"); - private final static float SHUT_CLOSED = -30; + private final static float SHUT_OPEN = 70; + private final static float SHUT_CLOSED = -70; public EtbReturnToNeutral() { button.addActionListener(new ActionListener() { @@ -65,6 +66,8 @@ public class EtbReturnToNeutral { if (isError) errorCount++; + CommandQueue.getInstance().write(CMD_ETB_DUTY + " " + SHUT_OPEN); + Thread.sleep((long) (0.5 * SECOND)); CommandQueue.getInstance().write(CMD_ETB_DUTY + " " + SHUT_CLOSED); Thread.sleep(SECOND);