Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

oil pressure protection (while running) #460

Merged
merged 7 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions firmware/controllers/algo/defaults/default_base_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ void setDefaultBaseEngine() {

setDefaultVrThresholds();

// Oil pressure protection
engineConfiguration->minimumOilPressureTimeout = 0.5f;
setLinearCurve(config->minimumOilPressureBins, 0, 7000);
}

void setPPSInputs(adc_channel_e pps1, adc_channel_e pps2) {
Expand Down
4 changes: 4 additions & 0 deletions firmware/controllers/engine_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,10 @@ bool validateConfig() {
}
#endif

if (engineConfiguration->enableOilPressureProtect) {
ensureArrayIsAscending("Oil pressure protection", config->minimumOilPressureBins);
}

return true;
}

Expand Down
20 changes: 17 additions & 3 deletions firmware/controllers/limp_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,17 @@ void LimpManager::updateState(int rpm, efitick_t nowNt) {
}
#if EFI_SHAFT_POSITION_INPUT
if (engine->rpmCalculator.isRunning()) {
bool hasOilpSensor = Sensor::hasSensor(SensorType::OilPressure);
auto oilp = Sensor::get(SensorType::OilPressure);
uint16_t minOilPressure = engineConfiguration->minOilPressureAfterStart;

// Only check if the setting is enabled and you have an oil pressure sensor
if (minOilPressure > 0 && Sensor::hasSensor(SensorType::OilPressure)) {
if (minOilPressure > 0 && hasOilpSensor) {
// Has it been long enough we should have pressure?
bool isTimedOut = engine->rpmCalculator.getSecondsSinceEngineStart(nowNt) > 5.0f;

// Only check before timed out
if (!isTimedOut) {
auto oilp = Sensor::get(SensorType::OilPressure);

if (oilp) {
// We had oil pressure! Set the flag.
if (oilp.Value > minOilPressure) {
Expand All @@ -135,9 +135,23 @@ void LimpManager::updateState(int rpm, efitick_t nowNt) {
allowFuel.clear(ClearReason::OilPressure);
}
}

if (oilp && engineConfiguration->enableOilPressureProtect) {
float minPressure = interpolate2d(rpm, config->minimumOilPressureBins, config->minimumOilPressureValues);
bool isPressureSufficient = oilp.Value > minPressure;

if (isPressureSufficient) {
m_lowOilPressureTimer.reset(nowNt);
}

if (m_lowOilPressureTimer.hasElapsedSec(engineConfiguration->minimumOilPressureTimeout)) {
allowFuel.clear(ClearReason::OilPressure);
}
}
} else {
// reset state in case of stalled engine
m_hadOilPressureAfterStart = false;
m_lowOilPressureTimer.reset(nowNt);
}

// If we're in engine stop mode, inhibit fuel
Expand Down
3 changes: 3 additions & 0 deletions firmware/controllers/limp_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ class LimpManager : public EngineModule {

// Tracks how long injector duty has been over the sustained limit
Timer m_injectorDutySustainedTimer;

// Tracks how long oil pressure has been below threshold
Timer m_lowOilPressureTimer;
};

LimpManager * getLimpManager();
Expand Down
7 changes: 5 additions & 2 deletions firmware/integration/rusefi_config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,7 @@ custom uart_device_e 1 bits, U08, @OFFSET@, [0:1], "Off", "UART1", "UART2", "UAR
pin_output_mode_e acRelayPinMode;
output_pin_e acRelayPin;

uint8_t unused754
uint8_t autoscale minimumOilPressureTimeout;Delay before cutting fuel due to low oil pressure. Use this to ignore short pressure blips and sensor noise.;"sec", 0.1, 0, 0, 5, 1

spi_device_e drv8860spiDevice;

Expand Down Expand Up @@ -826,7 +826,7 @@ sensor_chart_e sensorChartMode;rusEFI console Sensor Sniffer mode;
bit enableLaunchRetard
bit enableCanVss;Read VSS from OEM CAN bus according to selected CAN vehicle configuration.
bit enableInnovateLC2
bit unused808b7
bit enableOilPressureProtect
bit stftIgnoreErrorMagnitude;If enabled, adjust at a constant rate instead of a rate proportional to the current lambda error. This mode may be easier to tune, and more tolerant of sensor noise.
bit enableSoftwareKnock
bit verboseVVTDecoding;Verbose info in console below engineSnifferRpmThreshold\nenable vvt_details
Expand Down Expand Up @@ -1731,6 +1731,9 @@ uint8_t[FUEL_LEVEL_TABLE_COUNT] fuelLevelValues;;"%", 1, 0, 0, 100, 0
uint8_t[DWELL_CURVE_SIZE] autoscale dwellVoltageCorrVoltBins;;"volts", 0.1, 0, 0, 20, 1
uint8_t[DWELL_CURVE_SIZE] autoscale dwellVoltageCorrValues;;"multiplier", 0.02, 0, 0, 5, 2

uint8_t[8] autoscale minimumOilPressureBins;;"RPM", 100, 0, 0, 25000, 0
uint8_t[8] autoscale minimumOilPressureValues;;"kPa", 10, 0, 0, 1000, 0

end_struct

! Pedal Position Sensor
Expand Down
11 changes: 11 additions & 0 deletions firmware/tunerstudio/tunerstudio.template.ini
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,14 @@ curve = 32Curve, "3-2 Shift Solenoid Percent by Speed"
yBins = throttleEstimateEffectiveAreaValues
gauge = TPSGauge

curve = minimumOilPressure, "Minimum oil pressure"
columnLabel = "RPM", "min pressure"
xAxis = 0, 8000, 9
yAxis = 0, 500, 6
xBins = minimumOilPressureBins, RPMValue
yBins = minimumOilPressureValues
gauge = OilPressGauge

[TableEditor]
; table_id, map3d_id, "title", page

Expand Down Expand Up @@ -3805,6 +3813,9 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@@@ts_command_e_TS_

dialog = oilPressureProtection, "Oil pressure protection"
field = "Minimum oil pressure after start", minOilPressureAfterStart
field = "Enable low oil pressure protection", enableOilPressureProtect
field = "Oil pressure protection timeout", minimumOilPressureTimeout
panel = minimumOilPressure

dialog = etbLimits, "Electronic Throttle Limiting"
field = "Smoothly close the throttle to limit RPM."
Expand Down
46 changes: 44 additions & 2 deletions unit_tests/tests/test_limp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ TEST(limp, boostCut) {
EXPECT_TRUE(dut.allowInjection());
}

TEST(limp, oilPressureFailureCase) {
TEST(limp, oilPressureStartupFailureCase) {
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
engineConfiguration->minOilPressureAfterStart = 200;

Expand Down Expand Up @@ -165,7 +165,7 @@ TEST(limp, oilPressureFailureCase) {
ASSERT_FALSE(dut.allowInjection());
}

TEST(limp, oilPressureSuccessCase) {
TEST(limp, oilPressureStartupSuccessCase) {
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
engineConfiguration->minOilPressureAfterStart = 200;

Expand Down Expand Up @@ -202,3 +202,45 @@ TEST(limp, oilPressureSuccessCase) {
dut.updateState(1000, getTimeNowNt());
ASSERT_TRUE(dut.allowInjection());
}

TEST(limp, oilPressureRunning) {
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
engineConfiguration->enableOilPressureProtect = true;
engineConfiguration->minimumOilPressureTimeout = 1.0f;
setArrayValues(config->minimumOilPressureValues, 100);

LimpManager dut;

// Oil pressure starts OK
Sensor::setMockValue(SensorType::OilPressure, 110);

// Start the engine
engine->rpmCalculator.setRpmValue(1000);

// update & check: injection should be allowed
dut.updateState(1000, getTimeNowNt());
EXPECT_TRUE(dut.allowInjection());

// A long time later, everything should still be OK
advanceTimeUs(60e6);
dut.updateState(1000, getTimeNowNt());
EXPECT_TRUE(dut.allowInjection());

// Now oil pressure drops below threshold
Sensor::setMockValue(SensorType::OilPressure, 90);

// 0.9 second later, injection should continue as timeout isn't hit yet
advanceTimeUs(0.9e6);
dut.updateState(1000, getTimeNowNt());
ASSERT_TRUE(dut.allowInjection());

// 0.2 second later (1.1s since low pressure starts), injection should cut
advanceTimeUs(1.0e6);
dut.updateState(1000, getTimeNowNt());
ASSERT_FALSE(dut.allowInjection());

// Oil pressure is restored, and fuel should be restored too
Sensor::setMockValue(SensorType::OilPressure, 110);
dut.updateState(1000, getTimeNowNt());
ASSERT_TRUE(dut.allowInjection());
}
Loading