diff --git a/firmware/controllers/actuators/fan_control.cpp b/firmware/controllers/actuators/fan_control.cpp index 28e49afe16..54f3972576 100644 --- a/firmware/controllers/actuators/fan_control.cpp +++ b/firmware/controllers/actuators/fan_control.cpp @@ -7,10 +7,19 @@ EXTERN_ENGINE; -static void fanControl(bool acActive, OutputPin& pin, int8_t fanOnTemp, int8_t fanOffTemp, bool enableWithAc DECLARE_ENGINE_PARAMETER_SUFFIX) { +static void fanControl(bool acActive, OutputPin& pin, int8_t fanOnTemp, int8_t fanOffTemp, bool enableWithAc, bool disableWhenStopped DECLARE_ENGINE_PARAMETER_SUFFIX) { auto [cltValid, clt] = Sensor::get(SensorType::Clt); - if (!cltValid) { + bool isCranking = ENGINE(rpmCalculator).isCranking(); + bool isRunning = ENGINE(rpmCalculator).isRunning(); + + if (isCranking) { + // Inhibit while cranking + pin.setValue(false); + } else if (disableWhenStopped && !isRunning) { + // Inhibit while not running (if so configured) + pin.setValue(false); + } else if (!cltValid) { // If CLT is broken, turn the fan on pin.setValue(true); } else if (enableWithAc && acActive) { @@ -33,6 +42,6 @@ void updateFans(bool acActive DECLARE_ENGINE_PARAMETER_SUFFIX) { } #endif - fanControl(acActive, enginePins.fanRelay, CONFIG(fanOnTemperature), CONFIG(fanOffTemperature), CONFIG(enableFan1WithAc) PASS_ENGINE_PARAMETER_SUFFIX); - fanControl(acActive, enginePins.fanRelay2, CONFIG(fan2OnTemperature), CONFIG(fan2OffTemperature), CONFIG(enableFan2WithAc) PASS_ENGINE_PARAMETER_SUFFIX); + fanControl(acActive, enginePins.fanRelay, CONFIG(fanOnTemperature), CONFIG(fanOffTemperature), CONFIG(enableFan1WithAc), CONFIG(disableFan1WhenStopped) PASS_ENGINE_PARAMETER_SUFFIX); + fanControl(acActive, enginePins.fanRelay2, CONFIG(fan2OnTemperature), CONFIG(fan2OffTemperature), CONFIG(enableFan2WithAc), CONFIG(disableFan2WhenStopped) PASS_ENGINE_PARAMETER_SUFFIX); } diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 45def6fa2b..b7ecf7a2a4 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -532,8 +532,8 @@ bit isVerboseAuxPid1 bit overrideTriggerGaps bit enableFan1WithAc;+Turn on this fan when AC is on. bit enableFan2WithAc;+Turn on this fan when AC is on. -bit unused_294_6 -bit unused_294_7 +bit disableFan1WhenStopped;+Inhibit operation of this fan while the engine is not running. +bit disableFan2WhenStopped;+Inhibit operation of this fan while the engine is not running. bit unused_294_8 bit isCJ125Verbose;enable cj125verbose/disable cj125verbose bit cj125isUaDivided;+Is your UA CJ125 output wired to MCU via resistor divider? Ua can go over 3.3v but only at lambda >3, i.e very lean AFR above 44.1\nWhen exposed to free air and 17x gain, Ua will be 4.17 volt diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index 11dba2f08a..41c0aa4c77 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -2690,6 +2690,7 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00" field = "On temperature", fanOnTemperature field = "Off temperature", fanOffTemperature field = "Enable with AC", enableFan1WithAc + field = "Disable when engine stopped", disableFan1WhenStopped dialog = fan2Settings, "Fan 2" field = "Pin", fan2Pin @@ -2697,6 +2698,7 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00" field = "On temperature", fan2OnTemperature field = "Off temperature", fan2OffTemperature field = "Enable with AC", enableFan2WithAc + field = "Disable when engine stopped", disableFan2WhenStopped dialog = acSettings, "A/C Settings" field = "A/C Relay", acRelayPin diff --git a/unit_tests/tests/test_fan_control.cpp b/unit_tests/tests/test_fan_control.cpp index 54f204d594..0643b51bd8 100644 --- a/unit_tests/tests/test_fan_control.cpp +++ b/unit_tests/tests/test_fan_control.cpp @@ -43,4 +43,29 @@ TEST(FanControl, fan1) { // Turn off AC, fan should turn off too. updateFans(false PASS_ENGINE_PARAMETER_SUFFIX); EXPECT_EQ(false, enginePins.fanRelay.getLogicValue()); + + // Back to hot, fan should turn on + Sensor::setMockValue(SensorType::Clt, 95); + updateFans(false PASS_ENGINE_PARAMETER_SUFFIX); + EXPECT_EQ(true, enginePins.fanRelay.getLogicValue()); + + // Engine starts cranking, fan should turn off + ENGINE(rpmCalculator).setRpmValue(100); + updateFans(false PASS_ENGINE_PARAMETER_SUFFIX); + EXPECT_EQ(false, enginePins.fanRelay.getLogicValue()); + + // Engine running, fan should turn back on + ENGINE(rpmCalculator).setRpmValue(1000); + updateFans(false PASS_ENGINE_PARAMETER_SUFFIX); + EXPECT_EQ(true, enginePins.fanRelay.getLogicValue()); + + // Stop the engine, fan should stay on + ENGINE(rpmCalculator).setRpmValue(0); + updateFans(false PASS_ENGINE_PARAMETER_SUFFIX); + EXPECT_EQ(true, enginePins.fanRelay.getLogicValue()); + + // Set configuration to inhibit fan while engine is stopped, fan should stop + engineConfiguration->disableFan1WhenStopped = true; + updateFans(false PASS_ENGINE_PARAMETER_SUFFIX); + EXPECT_EQ(false, enginePins.fanRelay.getLogicValue()); }