diff --git a/firmware/console/status_loop.cpp b/firmware/console/status_loop.cpp index af07c612f4..e3ff9ddbc4 100644 --- a/firmware/console/status_loop.cpp +++ b/firmware/console/status_loop.cpp @@ -876,6 +876,11 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_ tsOutputChannels->isIatError = !isValidIntakeAirTemperature(getIntakeAirTemperature(PASS_ENGINE_PARAMETER_SIGNATURE)); #endif /* EFI_PROD_CODE */ +#if 0 + // todo: add output variable 'fuelConsumptionPerHour' + tsOutputChannels->fuelConsumptionPerHour = engine->engineState.fuelConsumption.perSecondConsumption; +#endif + tsOutputChannels->warningCounter = engine->engineState.warningCounter; tsOutputChannels->lastErrorCode = engine->engineState.lastErrorCode; diff --git a/firmware/controllers/algo/engine.cpp b/firmware/controllers/algo/engine.cpp index 602e5eb3e6..47a3f43b53 100644 --- a/firmware/controllers/algo/engine.cpp +++ b/firmware/controllers/algo/engine.cpp @@ -152,7 +152,30 @@ void Engine::reset() { FuelConsumptionState::FuelConsumptionState() { perSecondConsumption = perSecondAccumulator = 0; perMinuteConsumption = perMinuteAccumulator = 0; - accumulatedSecond = accumulatedMinute = -1; + accumulatedSecondPrevNt = accumulatedMinutePrevNt = getTimeNowNt(); +} + +void FuelConsumptionState::addData(float durationMs) { + if (durationMs > 0.0f) { + perSecondAccumulator += durationMs; + perMinuteAccumulator += durationMs; + } +} + +void FuelConsumptionState::update(efitick_t nowNt) { + efitick_t deltaNt = nowNt - accumulatedSecondPrevNt; + if (deltaNt >= US2NT(US_PER_SECOND_LL)) { + perSecondConsumption = getFuelRate(perSecondAccumulator, deltaNt PASS_ENGINE_PARAMETER_SUFFIX); + perSecondAccumulator = 0; + accumulatedSecondPrevNt = nowNt; + } + + deltaNt = nowNt - accumulatedMinutePrevNt; + if (deltaNt >= US2NT(US_PER_SECOND_LL * 60)) { + perMinuteConsumption = getFuelRate(perMinuteAccumulator, deltaNt PASS_ENGINE_PARAMETER_SUFFIX); + perMinuteAccumulator = 0; + accumulatedMinutePrevNt = nowNt; + } } TransmissionState::TransmissionState() { @@ -229,6 +252,9 @@ void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) { cltFuelCorrection = getCltFuelCorrection(PASS_ENGINE_PARAMETER_SIGNATURE); } + // update fuel consumption states + fuelConsumption.update(nowNt); + // post-cranking fuel enrichment. // for compatibility reasons, apply only if the factor is greater than zero (0.01 margin used) if (engineConfiguration->postCrankingFactor > 0.01f) { diff --git a/firmware/controllers/algo/engine.h b/firmware/controllers/algo/engine.h index 1645ae0bfc..e7d7c3730c 100644 --- a/firmware/controllers/algo/engine.h +++ b/firmware/controllers/algo/engine.h @@ -110,12 +110,13 @@ class FuelConsumptionState { public: FuelConsumptionState(); void addData(float durationMs); + void update(efitick_t nowNt); float perSecondConsumption; float perMinuteConsumption; float perSecondAccumulator; float perMinuteAccumulator; - int accumulatedSecond; - int accumulatedMinute; + efitick_t accumulatedSecondPrevNt; + efitick_t accumulatedMinutePrevNt; }; class TransmissionState { diff --git a/firmware/controllers/algo/fuel_math.cpp b/firmware/controllers/algo/fuel_math.cpp index a4939e4798..00b35f432a 100644 --- a/firmware/controllers/algo/fuel_math.cpp +++ b/firmware/controllers/algo/fuel_math.cpp @@ -47,6 +47,8 @@ extern fuel_Map3D_t ve2Map; extern afr_Map3D_t afrMap; extern baroCorr_Map3D_t baroCorrMap; +static float fuelRate = 0.0f; + /** * @return total duration of fuel injection per engine cycle, in milliseconds */ @@ -290,7 +292,11 @@ floatms_t getCrankingFuel3(float coolantTemperature, return baseCrankingFuel * durationCoef * coolantTempCoef * tpsCoef; } -float getFuelRate(DECLARE_ENGINE_PARAMETER_SIGNATURE) { - // todo: L/h - return 0.0f; +float getFuelRate(floatms_t totalInjDuration, efitick_t timePeriod DECLARE_ENGINE_PARAMETER_SUFFIX) { + if (timePeriod <= 0.0f) + return 0.0f; + float timePeriodMs = (float)NT2US(timePeriod) / 1000.0f; + float fuelRate = totalInjDuration / timePeriodMs; + const float cc_min_to_L_h = 60.0f / 1000.0f; + return fuelRate * CONFIG(injector.flow) * cc_min_to_L_h; } diff --git a/firmware/controllers/algo/fuel_math.h b/firmware/controllers/algo/fuel_math.h index 02a925efeb..578b2bf932 100644 --- a/firmware/controllers/algo/fuel_math.h +++ b/firmware/controllers/algo/fuel_math.h @@ -36,6 +36,8 @@ floatms_t getCrankingFuel(DECLARE_ENGINE_PARAMETER_SIGNATURE); floatms_t getCrankingFuel3(float coolantTemperature, uint32_t revolutionCounterSinceStart DECLARE_ENGINE_PARAMETER_SUFFIX); floatms_t getInjectionDuration(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX); percent_t getInjectorDutyCycle(int rpm DECLARE_ENGINE_PARAMETER_SUFFIX); -float getFuelRate(DECLARE_ENGINE_PARAMETER_SIGNATURE); + +// convert injection duration (Ms/Nt) to fuel rate (L/h) +float getFuelRate(floatms_t totalInjDuration, efitick_t timePeriod DECLARE_ENGINE_PARAMETER_SUFFIX); #endif /* FUEL_MAP_H_ */ diff --git a/firmware/controllers/obd2.cpp b/firmware/controllers/obd2.cpp index f1539a629c..46ae12e727 100644 --- a/firmware/controllers/obd2.cpp +++ b/firmware/controllers/obd2.cpp @@ -170,7 +170,7 @@ static void handleGetDataRequest(CANRxFrame *rx) { break; case PID_FUEL_RATE: scheduleMsg(&logger, "Got fuel rate request"); - obdSendValue(1, pid, 2, getFuelRate(PASS_ENGINE_PARAMETER_SIGNATURE) * 20.0f); // L/h. (A*256+B)/20 + obdSendValue(1, pid, 2, engine->engineState.fuelConsumption.perSecondConsumption * 20.0f); // L/h. (A*256+B)/20 break; default: scheduleMsg(&logger, "Got unhandled request (PID 0x%02x)", pid); diff --git a/firmware/controllers/trigger/main_trigger_callback.cpp b/firmware/controllers/trigger/main_trigger_callback.cpp index 483882e7a5..3603e5574b 100644 --- a/firmware/controllers/trigger/main_trigger_callback.cpp +++ b/firmware/controllers/trigger/main_trigger_callback.cpp @@ -232,6 +232,9 @@ static ALWAYS_INLINE void handleFuelInjectionEvent(int injEventIndex, InjectionE warning(CUSTOM_TOO_LONG_CRANKING_FUEL_INJECTION, "Too long cranking fuel injection %fms", injectionDuration); } + // Store 'pure' injection duration (w/o injector lag) for fuel rate calc. + engine->engineState.fuelConsumption.addData(injectionDuration - ENGINE(engineState.injectorLag)); + ENGINE(actualLastInjection) = injectionDuration; if (cisnan(injectionDuration)) { warning(CUSTOM_OBD_NAN_INJECTION, "NaN injection pulse");