diff --git a/firmware/CHANGELOG.md b/firmware/CHANGELOG.md index 256b91e8a5..522852e28d 100644 --- a/firmware/CHANGELOG.md +++ b/firmware/CHANGELOG.md @@ -45,6 +45,7 @@ or - Add two more aux linear sensors #476 - Support wasted spark on odd cylinder count and odd-fire engines. Improves startup and allows running without a cam sensor! - Add an option for the DFCO MAP threshold to use a table dependent upon RPM #485 (thank you @alrijleh!) + - Option to disable DFCO on gear shift - Ability to use an 8x8 table for after-start fuel multiplier that depends on CLT and engine run time ### Fixed diff --git a/firmware/controllers/algo/defaults/default_fuel.cpp b/firmware/controllers/algo/defaults/default_fuel.cpp index ad7b7acd87..eb43c6a46e 100644 --- a/firmware/controllers/algo/defaults/default_fuel.cpp +++ b/firmware/controllers/algo/defaults/default_fuel.cpp @@ -109,6 +109,7 @@ static void setDefaultFuelCutParameters() { engineConfiguration->coastingFuelCutTps = 2; engineConfiguration->coastingFuelCutMap = 30; engineConfiguration->coastingFuelCutClt = 60; + engineConfiguration->disableFuelCutOnClutch = false; copyArray(config->dfcoMapRpmValuesBins, { 1500, 2000, 3500, 5000 }); copyArray(config->dfcoMapRpmValues, { 30, 25, 20, 18 }); diff --git a/firmware/controllers/algo/fuel/dfco.cpp b/firmware/controllers/algo/fuel/dfco.cpp index a6176818ee..1620a95d2f 100644 --- a/firmware/controllers/algo/fuel/dfco.cpp +++ b/firmware/controllers/algo/fuel/dfco.cpp @@ -1,4 +1,5 @@ +#include "pch.h" #include "engine_configuration.h" #include "sensor.h" #include "rusefi/interpolation.h" @@ -28,6 +29,11 @@ bool DfcoController::getState() const { float rpm = Sensor::getOrZero(SensorType::Rpm); float vss = Sensor::getOrZero(SensorType::VehicleSpeed); + // Setting to allow clutch to block DFCO activation + bool clutchActivate = !engineConfiguration->disableFuelCutOnClutch + || !isBrainPinValid(engineConfiguration->clutchUpPin) + || engine->engineState.clutchUpState; + float mapThreshold = engineConfiguration->useTableForDfcoMap ? interpolate2d(rpm, config->dfcoMapRpmValuesBins, config->dfcoMapRpmValues) : engineConfiguration->coastingFuelCutMap; @@ -35,8 +41,8 @@ bool DfcoController::getState() const { bool mapActivate = !hasMap || !m_mapHysteresis.test(map.value_or(0), mapThreshold + 1, mapThreshold - 1); bool tpsActivate = tps.Value < engineConfiguration->coastingFuelCutTps; bool cltActivate = clt.Value > engineConfiguration->coastingFuelCutClt; - // True if throttle, MAP, and CLT are all acceptable for DFCO to occur - bool dfcoAllowed = mapActivate && tpsActivate && cltActivate; + // True if throttle, MAP, CLT, and Clutch are all acceptable for DFCO to occur + bool dfcoAllowed = mapActivate && tpsActivate && cltActivate && clutchActivate; bool rpmActivate = (rpm > engineConfiguration->coastingFuelCutRpmHigh); bool rpmDeactivate = (rpm < engineConfiguration->coastingFuelCutRpmLow); diff --git a/firmware/controllers/sensors/sensor_type.h b/firmware/controllers/sensors/sensor_type.h index 3e70ed6690..4646b1d3ab 100644 --- a/firmware/controllers/sensors/sensor_type.h +++ b/firmware/controllers/sensors/sensor_type.h @@ -71,6 +71,8 @@ enum class SensorType : unsigned char { BarometricPressure, + ClutchUp, + FuelLevel, VehicleSpeed, diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 17b79a02c1..58248f9e7a 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -708,6 +708,7 @@ bit is_enabled_spi_2 bit stepperForceParkingEveryRestart bit isFasterEngineSpinUpEnabled;If enabled, try to fire the engine before a full engine cycle has been completed using RPM estimated from the last 90 degrees of engine rotation. As soon as the trigger syncs plus 90 degrees rotation, fuel and ignition events will occur. If disabled, worst case may require up to 4 full crank rotations before any events are scheduled. bit coastingFuelCutEnabled;This setting disables fuel injection while the engine is in overrun, this is useful as a fuel saving measure and to prevent back firing. + bit disableFuelCutOnClutch;True: Inhibits DFCO from activating when the clutch is pressed. This helps prevent transient knock during shifts\n\nFalse: Do not take clutch state into account. bit useIacTableForCoasting;Override the IAC position during overrun conditions to help reduce engine breaking, this can be helpful for large engines in light weight cars or engines that have trouble returning to idle. bit useIdleTimingPidControl bit disableEtbWhenEngineStopped;Allows disabling the ETB when the engine is stopped. You may not like the power draw or PWM noise from the motor, so this lets you turn it off until it's necessary. diff --git a/firmware/tunerstudio/tunerstudio.template.ini b/firmware/tunerstudio/tunerstudio.template.ini index 9485c56132..7ca4b35323 100644 --- a/firmware/tunerstudio/tunerstudio.template.ini +++ b/firmware/tunerstudio/tunerstudio.template.ini @@ -4482,6 +4482,8 @@ dialog = tcuControls, "Transmission Settings" dialog = coastingFuelCutControl, "Coasting Fuel Cutoff Settings" field = "Enable Coasting Fuel Cutoff", coastingFuelCutEnabled + field = "" + field = "Disable fuel cut on clutch", disableFuelCutOnClutch, {coastingFuelCutEnabled && clutchUpPin != @@ADC_CHANNEL_NONE@@} field = "No cut below CLT", coastingFuelCutClt, {coastingFuelCutEnabled} field = "RPM cut fuel above", coastingFuelCutRpmHigh, {coastingFuelCutEnabled} field = "RPM restore fuel below", coastingFuelCutRpmLow, {coastingFuelCutEnabled} diff --git a/unit_tests/tests/ignition_injection/test_fuelCut.cpp b/unit_tests/tests/ignition_injection/test_fuelCut.cpp index 8f27597d58..0876f5bfd4 100644 --- a/unit_tests/tests/ignition_injection/test_fuelCut.cpp +++ b/unit_tests/tests/ignition_injection/test_fuelCut.cpp @@ -141,7 +141,6 @@ TEST(fuelCut, delay) { engineConfiguration->coastingFuelCutRpmHigh = 1500; engineConfiguration->coastingFuelCutTps = 2; engineConfiguration->coastingFuelCutClt = 30; - engineConfiguration->useTableForDfcoMap = false; engineConfiguration->coastingFuelCutMap = 100; // set cranking threshold engineConfiguration->cranking.rpm = 999; @@ -256,4 +255,62 @@ TEST(fuelCut, mapTable) { Sensor::setMockValue(SensorType::Rpm, 4000); eth.engine.periodicFastCallback(); EXPECT_NORMAL(); +} +// testing the ablity to have clutch input disable fuel cut when configured +TEST(fuelCut, clutch) { + EngineTestHelper eth(engine_type_e::TEST_ENGINE); + EXPECT_CALL(*eth.mockAirmass, getAirmass(_, _)) + .WillRepeatedly(Return(AirmassResult{0.1008f, 50.0f})); + + // configure coastingFuelCut + engineConfiguration->coastingFuelCutEnabled = true; + engineConfiguration->coastingFuelCutRpmLow = 1300; + engineConfiguration->coastingFuelCutRpmHigh = 1500; + engineConfiguration->coastingFuelCutTps = 2; + engineConfiguration->coastingFuelCutClt = 30; + engineConfiguration->coastingFuelCutMap = 100; + // set cranking threshold + engineConfiguration->cranking.rpm = 999; + + // basic engine setup + setupSimpleTestEngineWithMafAndTT_ONE_trigger(ð); + + //all other conditions should allow fuel cut + float hotClt = engineConfiguration->coastingFuelCutClt + 1; + Sensor::setMockValue(SensorType::Clt, hotClt); + Sensor::setMockValue(SensorType::DriverThrottleIntent, 0); + Sensor::setMockValue(SensorType::Rpm, engineConfiguration->coastingFuelCutRpmHigh + 1); + Sensor::setMockValue(SensorType::Map, 0); + eth.moveTimeForwardUs(1000); + + const float normalInjDuration = 1.5f; + eth.engine.periodicFastCallback(); + + // feature disabled, all fuel cut conditions met + engineConfiguration->disableFuelCutOnClutch = false; + setMockState(engineConfiguration->clutchUpPin, false); + engine->updateSwitchInputs(); + eth.engine.periodicFastCallback(); + EXPECT_CUT(); + + // feature enabled, io not configured, fuelCut should still occur + engineConfiguration->disableFuelCutOnClutch = true; + setMockState(engineConfiguration->clutchUpPin, false); + engine->updateSwitchInputs(); + eth.engine.periodicFastCallback(); + EXPECT_CUT(); + + //configure io, fuelCut should now be inhibited + engineConfiguration->clutchUpPin = Gpio::G2; + engineConfiguration->clutchUpPinMode = PI_PULLDOWN; + setMockState(engineConfiguration->clutchUpPin, false); + engine->updateSwitchInputs(); + eth.engine.periodicFastCallback(); + EXPECT_NORMAL(); + + // release clutch, fuel cut should now happen + setMockState(engineConfiguration->clutchUpPin, true); + engine->updateSwitchInputs(); + eth.engine.periodicFastCallback(); + EXPECT_CUT(); } \ No newline at end of file