void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_F) { int rpm = ENGINE(rpmCalculator.rpmValue); sparkDwell = getSparkDwell(rpm PASS_ENGINE_PARAMETER); dwellAngle = sparkDwell / getOneDegreeTimeMs(rpm); iatFuelCorrection = getIatCorrection(iat PASS_ENGINE_PARAMETER); cltFuelCorrection = getCltCorrection(clt PASS_ENGINE_PARAMETER); engineNoiseHipLevel = interpolate2d(rpm, engineConfiguration->knockNoiseRpmBins, engineConfiguration->knockNoise, ENGINE_NOISE_CURVE_SIZE); baroCorrection = getBaroCorrection(PASS_ENGINE_PARAMETER_F); injectionOffset = getinjectionOffset(rpm PASS_ENGINE_PARAMETER); float engineLoad = getEngineLoadT(PASS_ENGINE_PARAMETER_F); timingAdvance = getAdvance(rpm, engineLoad PASS_ENGINE_PARAMETER); if (engineConfiguration->algorithm == LM_SPEED_DENSITY) { float coolantC = ENGINE(engineState.clt); float intakeC = ENGINE(engineState.iat); float tps = getTPS(PASS_ENGINE_PARAMETER_F); tChargeK = convertCelsiusToKelvin(getTCharge(rpm, tps, coolantC, intakeC)); float map = getMap(); /** * *0.01 because of https://sourceforge.net/p/rusefi/tickets/153/ */ currentVE = baroCorrection * veMap.getValue(map, rpm) * 0.01; targerAFR = afrMap.getValue(map, rpm); } else { baseTableFuel = getBaseTableFuel(engineConfiguration, rpm, engineLoad); } }
void setDefaultVETable(DECLARE_ENGINE_PARAMETER_F) { setRpmTableBin(config->veRpmBins, FUEL_RPM_COUNT); veMap.setAll(80); // setRpmTableBin(engineConfiguration->ve2RpmBins, FUEL_RPM_COUNT); // setTableBin2(engineConfiguration->ve2LoadBins, FUEL_LOAD_COUNT, 10, 300, 1); // ve2Map.setAll(0.81); setRpmTableBin(config->afrRpmBins, FUEL_RPM_COUNT); afrMap.setAll(14.7); setRpmTableBin(engineConfiguration->baroCorrRpmBins, BARO_CORR_SIZE); setTableBin2(engineConfiguration->baroCorrPressureBins, BARO_CORR_SIZE, 75, 105, 1); memcpy(engineConfiguration->baroCorrTable, default_baro_corr, sizeof(default_baro_corr)); }
void initSpeedDensity(DECLARE_ENGINE_PARAMETER_SIGNATURE) { veMap.init(config->veTable, config->veLoadBins, config->veRpmBins); // ve2Map.init(engineConfiguration->ve2Table, engineConfiguration->ve2LoadBins, engineConfiguration->ve2RpmBins); afrMap.init(config->afrTable, config->afrLoadBins, config->afrRpmBins); baroCorrMap.init(engineConfiguration->baroCorrTable, engineConfiguration->baroCorrPressureBins, engineConfiguration->baroCorrRpmBins); initMaf2Map(); }
/** * @return Fuel injection duration injection as specified in the fuel map, in milliseconds */ floatms_t getBaseTableFuel(engine_configuration_s *engineConfiguration, int rpm, float engineLoad) { if (cisnan(engineLoad)) { warning(OBD_PCM_Processor_Fault, "NaN engine load"); return NAN; } return fuelMap.getValue(engineLoad, rpm); }
/** * @return total duration of fuel injection per engine cycle, in milliseconds */ float getRealMafFuel(float airSpeed, int rpm DECLARE_ENGINE_PARAMETER_S) { if (rpm == 0) return 0; // duration of engine cycle, in hours float engineCycleDurationHr = 1.0 / 60 / rpm; float airMassKg = airSpeed * engineCycleDurationHr; /** * todo: pre-calculate gramm/second injector flow to save one multiplication * open question if that's needed since that's just a multiplication */ float injectorFlowRate = cc_minute_to_gramm_second(engineConfiguration->injector.flow); float afr = afrMap.getValue(airSpeed, rpm); float fuelMassGramm = airMassKg / afr * 1000; return 1000 * fuelMassGramm / injectorFlowRate; }
float getinjectionOffset(int rpm DECLARE_ENGINE_PARAMETER_S) { float engineLoad = getEngineLoadT(PASS_ENGINE_PARAMETER_F); return fuelPhaseMap.getValue(engineLoad, rpm); }
/** * @brief Initialize fuel map data structure * @note this method has nothing to do with fuel map VALUES - it's job * is to prepare the fuel map data structure for 3d interpolation */ void prepareFuelMap(DECLARE_ENGINE_PARAMETER_F) { fuelMap.init(config->fuelTable, config->fuelLoadBins, config->fuelRpmBins); fuelPhaseMap.init(config->injectionPhase, config->injPhaseLoadBins, config->injPhaseRpmBins); }
chRegSetThreadName("lcd"); while (true) { if (engineConfiguration->bc.useLcdScreen) { #if EFI_HD44780_LCD updateHD44780lcd(engine); #endif } chThdSleepMilliseconds(engineConfiguration->bc.lcdThreadPeriod); } } #if EFI_TUNER_STUDIO || defined(__DOXYGEN__) extern WallFuel wallFuel; extern fuel_Map3D_t veMap; void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_ENGINE_PARAMETER_S) { #if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__) int rpm = getRpmE(engine); #else int rpm = 0; #endif float tps = getTPS(PASS_ENGINE_PARAMETER_F); float coolant = getCoolantTemperature(PASS_ENGINE_PARAMETER_F); float intake = getIntakeAirTemperature(PASS_ENGINE_PARAMETER_F); float engineLoad = getEngineLoadT(PASS_ENGINE_PARAMETER_F); float baseFuelMs = getBaseFuel(rpm PASS_ENGINE_PARAMETER);
void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) { efitick_t nowNt = getTimeNowNt(); if (ENGINE(rpmCalculator).isCranking(PASS_ENGINE_PARAMETER_SIGNATURE)) { crankingTime = nowNt; timeSinceCranking = 0.0f; } else { timeSinceCranking = nowNt - crankingTime; } updateAuxValves(PASS_ENGINE_PARAMETER_SIGNATURE); int rpm = ENGINE(rpmCalculator).getRpm(PASS_ENGINE_PARAMETER_SIGNATURE); sparkDwell = getSparkDwell(rpm PASS_ENGINE_PARAMETER_SUFFIX); dwellAngle = sparkDwell / getOneDegreeTimeMs(rpm); if (hasAfrSensor(PASS_ENGINE_PARAMETER_SIGNATURE)) { engine->sensors.currentAfr = getAfr(PASS_ENGINE_PARAMETER_SIGNATURE); } // todo: move this into slow callback, no reason for IAT corr to be here iatFuelCorrection = getIatFuelCorrection(engine->sensors.iat PASS_ENGINE_PARAMETER_SUFFIX); // todo: move this into slow callback, no reason for CLT corr to be here if (boardConfiguration->useWarmupPidAfr && engine->sensors.clt < engineConfiguration->warmupAfrThreshold) { if (rpm < 200) { cltFuelCorrection = 1; warmupAfrPid.reset(); } else { cltFuelCorrection = warmupAfrPid.getValue(warmupTargetAfr, engine->sensors.currentAfr, 1); } #if ! EFI_UNIT_TEST || defined(__DOXYGEN__) if (engineConfiguration->debugMode == DBG_WARMUP_ENRICH) { tsOutputChannels.debugFloatField1 = warmupTargetAfr; warmupAfrPid.postState(&tsOutputChannels); } #endif } else { cltFuelCorrection = getCltFuelCorrection(PASS_ENGINE_PARAMETER_SIGNATURE); } // update fuel consumption states fuelConsumption.update(nowNt PASS_ENGINE_PARAMETER_SUFFIX); // Fuel cut-off isn't just 0 or 1, it can be tapered fuelCutoffCorrection = getFuelCutOffCorrection(nowNt, rpm PASS_ENGINE_PARAMETER_SUFFIX); // 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) { // convert to microsecs and then to seconds float timeSinceCrankingInSecs = NT2US(timeSinceCranking) / 1000000.0f; // use interpolation for correction taper postCrankingFuelCorrection = interpolateClamped(0.0f, engineConfiguration->postCrankingFactor, engineConfiguration->postCrankingDurationSec, 1.0f, timeSinceCrankingInSecs); } else { postCrankingFuelCorrection = 1.0f; } cltTimingCorrection = getCltTimingCorrection(PASS_ENGINE_PARAMETER_SIGNATURE); engineNoiseHipLevel = interpolate2d("knock", rpm, engineConfiguration->knockNoiseRpmBins, engineConfiguration->knockNoise, ENGINE_NOISE_CURVE_SIZE); baroCorrection = getBaroCorrection(PASS_ENGINE_PARAMETER_SIGNATURE); injectionOffset = getinjectionOffset(rpm PASS_ENGINE_PARAMETER_SUFFIX); float engineLoad = getEngineLoadT(PASS_ENGINE_PARAMETER_SIGNATURE); timingAdvance = getAdvance(rpm, engineLoad PASS_ENGINE_PARAMETER_SUFFIX); if (engineConfiguration->fuelAlgorithm == LM_SPEED_DENSITY) { float coolantC = ENGINE(sensors.clt); float intakeC = ENGINE(sensors.iat); float tps = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE); tChargeK = convertCelsiusToKelvin(getTCharge(rpm, tps, coolantC, intakeC PASS_ENGINE_PARAMETER_SUFFIX)); float map = getMap(); /** * *0.01 because of https://sourceforge.net/p/rusefi/tickets/153/ */ float rawVe = veMap.getValue(rpm, map); // get VE from the separate table for Idle if (CONFIG(useSeparateVeForIdle)) { float idleVe = interpolate2d("idleVe", rpm, config->idleVeBins, config->idleVe, IDLE_VE_CURVE_SIZE); // interpolate between idle table and normal (running) table using TPS threshold rawVe = interpolateClamped(0.0f, idleVe, boardConfiguration->idlePidDeactivationTpsThreshold, rawVe, tps); } currentVE = baroCorrection * rawVe * 0.01; targetAFR = afrMap.getValue(rpm, map); } else { baseTableFuel = getBaseTableFuel(rpm, engineLoad); } }
void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_F) { int rpm = ENGINE(rpmCalculator.rpmValue); efitick_t nowNt = getTimeNowNt(); if (isCrankingR(rpm)) { crankingTime = nowNt; } else { timeSinceCranking = nowNt - crankingTime; } sparkDwell = getSparkDwell(rpm PASS_ENGINE_PARAMETER); dwellAngle = sparkDwell / getOneDegreeTimeMs(rpm); // todo: move this into slow callback, no reason for IAT corr to be here iatFuelCorrection = getIatCorrection(iat PASS_ENGINE_PARAMETER); // todo: move this into slow callback, no reason for CLT corr to be here if (boardConfiguration->useWarmupPidAfr && clt < engineConfiguration->warmupAfrThreshold) { if (rpm < 200) { cltFuelCorrection = 1; warmupAfrPid.reset(); } else { cltFuelCorrection = warmupAfrPid.getValue(warmupTargetAfr, getAfr(PASS_ENGINE_PARAMETER_F), 1); } #if ! EFI_UNIT_TEST || defined(__DOXYGEN__) if (engineConfiguration->debugMode == WARMUP_ENRICH) { tsOutputChannels.debugFloatField1 = warmupTargetAfr; warmupAfrPid.postState(&tsOutputChannels); } #endif } else { cltFuelCorrection = getCltFuelCorrection(clt PASS_ENGINE_PARAMETER); } cltTimingCorrection = getCltTimingCorrection(clt PASS_ENGINE_PARAMETER); engineNoiseHipLevel = interpolate2d(rpm, engineConfiguration->knockNoiseRpmBins, engineConfiguration->knockNoise, ENGINE_NOISE_CURVE_SIZE); baroCorrection = getBaroCorrection(PASS_ENGINE_PARAMETER_F); injectionOffset = getinjectionOffset(rpm PASS_ENGINE_PARAMETER); float engineLoad = getEngineLoadT(PASS_ENGINE_PARAMETER_F); timingAdvance = getAdvance(rpm, engineLoad PASS_ENGINE_PARAMETER); if (engineConfiguration->fuelAlgorithm == LM_SPEED_DENSITY) { float coolantC = ENGINE(engineState.clt); float intakeC = ENGINE(engineState.iat); float tps = getTPS(PASS_ENGINE_PARAMETER_F); tChargeK = convertCelsiusToKelvin(getTCharge(rpm, tps, coolantC, intakeC PASS_ENGINE_PARAMETER)); float map = getMap(); /** * *0.01 because of https://sourceforge.net/p/rusefi/tickets/153/ */ currentVE = baroCorrection * veMap.getValue(rpm, map) * 0.01; targetAFR = afrMap.getValue(rpm, map); } else { baseTableFuel = getBaseTableFuel(engineConfiguration, rpm, engineLoad); } }
static void printSensors(Logging *log, bool fileFormat) { // current time, in milliseconds int nowMs = currentTimeMillis(); float sec = ((float) nowMs) / 1000; reportSensorF(log, fileFormat, "time", "", sec, 3); // log column 1 int rpm = 0; #if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__) rpm = getRpmE(engine); reportSensorI(log, fileFormat, "rpm", "RPM", rpm); // log column 2 // reportSensorF(log, fileFormat, "TRG_0_DUTY", "%", getTriggerDutyCycle(0), 2); // reportSensorF(log, fileFormat, "TRG_1_DUTY", "%", getTriggerDutyCycle(1), 2); #endif #if EFI_PROD_CODE || defined(__DOXYGEN__) reportSensorF(log, fileFormat, "int_temp", "C", getMCUInternalTemperature(), 2); // log column #3 #endif reportSensorI(log, fileFormat, "mode", "v", packEngineMode(PASS_ENGINE_PARAMETER_F)); // log column #3 if (hasCltSensor()) { reportSensorF(log, fileFormat, "CLT", "C", getCoolantTemperature(PASS_ENGINE_PARAMETER_F), 2); // log column #4 } if (hasTpsSensor()) { reportSensorF(log, fileFormat, "TPS", "%", getTPS(PASS_ENGINE_PARAMETER_F), 2); // log column #5 } if (hasVBatt(PASS_ENGINE_PARAMETER_F)) { reportSensorF(log, fileFormat, "vbatt", "V", getVBatt(PASS_ENGINE_PARAMETER_F), 2); // log column #6 } if (hasIatSensor()) { reportSensorF(log, fileFormat, "IAT", "C", getIntakeAirTemperature(PASS_ENGINE_PARAMETER_F), 2); // log column #7 } if (hasMafSensor()) { reportSensorF(log, fileFormat, "maf", "V", getMaf(PASS_ENGINE_PARAMETER_F), 2); reportSensorF(log, fileFormat, "mafr", "kg/hr", getRealMaf(PASS_ENGINE_PARAMETER_F), 2); } #if EFI_ANALOG_SENSORS || defined(__DOXYGEN__) if (engineConfiguration->map.sensor.hwChannel != EFI_ADC_NONE) { reportSensorF(log, fileFormat, "MAP", "kPa", getMap(), 2); // reportSensorF(log, fileFormat, "map_r", "V", getRawMap(), 2); } #endif /* EFI_ANALOG_SENSORS */ #if EFI_ANALOG_SENSORS || defined(__DOXYGEN__) if (hasBaroSensor()) { reportSensorF(log, fileFormat, "baro", "kPa", getBaroPressure(), 2); } #endif /* EFI_ANALOG_SENSORS */ if (hasAfrSensor(PASS_ENGINE_PARAMETER_F)) { reportSensorF(log, fileFormat, "afr", "AFR", getAfr(PASS_ENGINE_PARAMETER_F), 2); } #if EFI_IDLE_CONTROL || defined(__DOXYGEN__) if (fileFormat) { reportSensorF(log, fileFormat, "idle", "%", getIdlePosition(), 2); } #endif /* EFI_IDLE_CONTROL */ #if EFI_ANALOG_SENSORS || defined(__DOXYGEN__) reportSensorF(log, fileFormat, "target", "AFR", engine->engineState.targetAFR, 2); #endif /* EFI_ANALOG_SENSORS */ if (fileFormat) { reportSensorF(log, fileFormat, "tCharge", "K", engine->engineState.tChargeK, 2); // log column #8 reportSensorF(log, fileFormat, "curVE", "%", veMap.getValue(rpm, getMap()), 2); } float engineLoad = getEngineLoadT(PASS_ENGINE_PARAMETER_F); reportSensorF(log, fileFormat, "ENGINE_LOAD", "x", engineLoad, 2); reportSensorF(log, fileFormat, "dwell", "ms", ENGINE(engineState.sparkDwell), 2); if (fileFormat) { reportSensorF(log, fileFormat, "timing", "deg", engine->engineState.timingAdvance, 2); } if (fileFormat) { floatms_t fuelBase = getBaseFuel(rpm PASS_ENGINE_PARAMETER); reportSensorF(log, fileFormat, "f: base", "ms", fuelBase, 2); reportSensorF(log, fileFormat, "f: actual", "ms", ENGINE(actualLastInjection), 2); reportSensorF(log, fileFormat, "f: lag", "ms", engine->engineState.injectorLag, 2); reportSensorF(log, fileFormat, "f: running", "ms", ENGINE(engineState.runningFuel), 2); reportSensorF(log, fileFormat, "f: wall amt", "v", ENGINE(wallFuel).getWallFuel(0), 2); reportSensorF(log, fileFormat, "f: wall crr", "v", ENGINE(wallFuelCorrection), 2); reportSensorI(log, fileFormat, "version", "#", getRusEfiVersion()); } if (engineConfiguration->hasVehicleSpeedSensor) { #if EFI_VEHICLE_SPEED || defined(__DOXYGEN__) float vehicleSpeed = getVehicleSpeed(); #else float vehicleSpeed = 0; #endif /* EFI_PROD_CODE */ reportSensorF(log, fileFormat, "vss", "kph", vehicleSpeed, 2); float sp2rpm = rpm == 0 ? 0 : vehicleSpeed / rpm; reportSensorF(log, fileFormat, "sp2rpm", "x", sp2rpm, 2); } reportSensorF(log, fileFormat, "knck_c", "count", engine->knockCount, 0); reportSensorF(log, fileFormat, "knck_v", "v", engine->knockVolts, 2); // reportSensorF(log, fileFormat, "vref", "V", getVRef(engineConfiguration), 2); if (fileFormat) { reportSensorF(log, fileFormat, "f: tps delta", "v", engine->tpsAccelEnrichment.getMaxDelta(), 2); reportSensorF(log, fileFormat, "f: tps fuel", "ms", engine->engineState.tpsAccelEnrich, 2); reportSensorF(log, fileFormat, "f: el delta", "v", engine->engineLoadAccelEnrichment.getMaxDelta(), 2); reportSensorF(log, fileFormat, "f: el fuel", "v", engine->engineLoadAccelEnrichment.getEngineLoadEnrichment(PASS_ENGINE_PARAMETER_F) * 100 / getMap(), 2); reportSensorF(log, fileFormat, "f: duty", "%", getInjectorDutyCycle(rpm PASS_ENGINE_PARAMETER), 2); } // debugFloat(&logger, "tch", getTCharge1(tps), 2); for (int i = 0;i<FSIO_ADC_COUNT;i++) { if (engineConfiguration->fsioAdc[i] != EFI_ADC_NONE) { strcpy(buf, "adcX"); buf[3] = '0' + i; reportSensorF(log, fileFormat, buf, "", getVoltage("fsio", engineConfiguration->fsioAdc[i]), 2); } } reportSensorI(log, fileFormat, "warn", "count", engine->engineState.warningCounter); reportSensorI(log, fileFormat, "error", "code", engine->engineState.lastErrorCode); }
#include "advance_map.h" #include "tunerstudio.h" #include "fuel_math.h" #include "main_trigger_callback.h" #include "engine_math.h" #include "idle_thread.h" #include "engine_configuration.h" #include "rfiutil.h" #include "svnversion.h" #include "engine.h" #include "lcd_controller.h" #include "settings.h" #include "rusefi_outputs.h" extern fuel_Map3D_t veMap; extern afr_Map3D_t afrMap; extern bool main_loop_started; #if EFI_PROD_CODE || defined(__DOXYGEN__) // todo: move this logic to algo folder! #include "rtc_helper.h" #include "lcd_HD44780.h" #include "rusefi.h" #include "pin_repository.h" #include "flash_main.h" #include "max31855.h" #include "vehicle_speed.h" #endif static bool subscription[(int) RO_LAST_ELEMENT];