diff --git a/firmware/config/engines/ford_festiva.cpp b/firmware/config/engines/ford_festiva.cpp index ccc8a7427e..6cb9a7f6b1 100644 --- a/firmware/config/engines/ford_festiva.cpp +++ b/firmware/config/engines/ford_festiva.cpp @@ -127,6 +127,7 @@ void setFordEscortGt(DECLARE_ENGINE_PARAMETER_SIGNATURE) { // set_idle_position 10 boardConfiguration->manIdlePosition = 10; + engineConfiguration->crankingIACposition = 65; setWholeIatCorrTimingTable(0 PASS_ENGINE_PARAMETER_SUFFIX); diff --git a/firmware/config/engines/mazda_miata_vvt.cpp b/firmware/config/engines/mazda_miata_vvt.cpp index dc4f8593f5..18de48cf14 100644 --- a/firmware/config/engines/mazda_miata_vvt.cpp +++ b/firmware/config/engines/mazda_miata_vvt.cpp @@ -430,5 +430,5 @@ void setMazdaMiata2003EngineConfigurationNewBoard(DECLARE_ENGINE_PARAMETER_SIGNA // set idle_position 30 boardConfiguration->manIdlePosition = 30; - engineConfiguration->crankingIdleAdjustment = 30; + engineConfiguration->crankingIACposition = 65; } diff --git a/firmware/controllers/algo/engine_configuration.cpp b/firmware/controllers/algo/engine_configuration.cpp index 534188e420..0698a55ceb 100644 --- a/firmware/controllers/algo/engine_configuration.cpp +++ b/firmware/controllers/algo/engine_configuration.cpp @@ -740,6 +740,7 @@ void setDefaultConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE) { boardConfiguration->idle.solenoidFrequency = 200; // set idle_position 50 boardConfiguration->manIdlePosition = 50; + engineConfiguration->crankingIACposition = 50; engineConfiguration->targetIdleRpm = 1200; // engineConfiguration->idleMode = IM_AUTO; engineConfiguration->idleMode = IM_MANUAL; diff --git a/firmware/controllers/algo/engine_configuration_generated_structures.h b/firmware/controllers/algo/engine_configuration_generated_structures.h index 13a2bc710c..0f2d6ea469 100644 --- a/firmware/controllers/algo/engine_configuration_generated_structures.h +++ b/firmware/controllers/algo/engine_configuration_generated_structures.h @@ -1,4 +1,4 @@ -// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Tue May 16 20:30:28 EDT 2017 +// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Tue May 16 21:58:40 EDT 2017 // begin #ifndef ENGINE_CONFIGURATION_GENERATED_H_ #define ENGINE_CONFIGURATION_GENERATED_H_ @@ -1189,7 +1189,7 @@ typedef struct { bool fuelClosedLoopCorrectionEnabled : 1; /** offset 1488 bit 2 */ - bool unusedBit__5 : 1; + bool isVerboseIAC : 1; /** offset 1488 bit 3 */ bool unusedBit__6 : 1; @@ -1694,10 +1694,10 @@ typedef struct { */ pid_dt auxPidDT[AUX_PID_COUNT]; /** - * Extra idle while cranking + * IAC cranking position * offset 2428 */ - float crankingIdleAdjustment; + int crankingIACposition; /** * offset 2432 */ @@ -2104,4 +2104,4 @@ typedef struct { #endif // end -// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Tue May 16 20:30:28 EDT 2017 +// this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Tue May 16 21:58:40 EDT 2017 diff --git a/firmware/controllers/algo/rusefi_generated.h b/firmware/controllers/algo/rusefi_generated.h index 2d5f83cdbd..306fc4cd6b 100644 --- a/firmware/controllers/algo/rusefi_generated.h +++ b/firmware/controllers/algo/rusefi_generated.h @@ -841,8 +841,8 @@ #define vvtDisplayInverted_offset_hex 5d0 #define fuelClosedLoopCorrectionEnabled_offset 1488 #define fuelClosedLoopCorrectionEnabled_offset_hex 5d0 -#define unusedBit__5_offset 1488 -#define unusedBit__5_offset_hex 5d0 +#define isVerboseIAC_offset 1488 +#define isVerboseIAC_offset_hex 5d0 #define unusedBit__6_offset 1488 #define unusedBit__6_offset_hex 5d0 #define useConstantDwellDuringCranking_offset 1488 @@ -1163,8 +1163,8 @@ #define auxPidDT3_offset_hex 974 #define auxPidDT4_offset 2424 #define auxPidDT4_offset_hex 978 -#define crankingIdleAdjustment_offset 2428 -#define crankingIdleAdjustment_offset_hex 97c +#define crankingIACposition_offset 2428 +#define crankingIACposition_offset_hex 97c #define tChargeMinRpmMinTps_offset 2432 #define tChargeMinRpmMinTps_offset_hex 980 #define tChargeMinRpmMaxTps_offset 2436 diff --git a/firmware/controllers/idle_thread.cpp b/firmware/controllers/idle_thread.cpp index 372884ad0a..4cff1810e6 100644 --- a/firmware/controllers/idle_thread.cpp +++ b/firmware/controllers/idle_thread.cpp @@ -42,6 +42,9 @@ extern TunerStudioOutputChannels tsOutputChannels; EXTERN_ENGINE ; + +static Pid idlePid(&engineConfiguration->idleRpmPid, 1, 99); + // todo: extract interface for idle valve hardware, with solenoid and stepper implementations? static SimplePwm idleSolenoid; @@ -88,44 +91,39 @@ void setIdleMode(idle_mode_e value) { showIdleInfo(); } -static void setIdleValvePwm(percent_t value) { - /** - * currently idle level is an percent value (0-100 range), and PWM takes a float in the 0..1 range - * todo: unify? - */ - idleSolenoid.setSimplePwmDutyCycle(value / 100); +static void applyIACposition(percent_t position) { + if (boardConfiguration->useStepperIdle) { + iacMotor.setTargetPosition(position / 100 * engineConfiguration->idleStepperTotalSteps); + } else { + /** + * currently idle level is an percent value (0-100 range), and PWM takes a float in the 0..1 range + * todo: unify? + */ + idleSolenoid.setSimplePwmDutyCycle(position / 100.0); + } } -static void manualIdleController() { +/** + * Adjusts cra + * + * @param target percentage of manual-controlled IAC or RPM for auto idle + */ +static float adjustIdleTarget(float target) { - int positionPercent = boardConfiguration->manIdlePosition; - if (isCranking()) { - positionPercent += engineConfiguration->crankingIdleAdjustment; - } - percent_t cltCorrectedPosition = interpolate2d(engine->sensors.clt, config->cltIdleCorrBins, config->cltIdleCorr, - CLT_CURVE_SIZE) / PERCENT_MULT * positionPercent; + return target; +} + +static float manualIdleController(float cltCorrection) { + + percent_t correctedPosition = cltCorrection * boardConfiguration->manIdlePosition; // let's put the value into the right range - cltCorrectedPosition = maxF(cltCorrectedPosition, 0.01); - cltCorrectedPosition = minF(cltCorrectedPosition, 99.9); + correctedPosition = maxF(correctedPosition, 0.01); + correctedPosition = minF(correctedPosition, 99.9); - if (engineConfiguration->debugMode == DBG_IDLE) { - tsOutputChannels.debugFloatField1 = actualIdlePosition; - } - - if (absF(cltCorrectedPosition - actualIdlePosition) < 1) { - return; // value is pretty close, let's leave the poor valve alone - } - actualIdlePosition = cltCorrectedPosition; - - - if (boardConfiguration->useStepperIdle) { - iacMotor.setTargetPosition(cltCorrectedPosition / 100 * engineConfiguration->idleStepperTotalSteps); - } else { - setIdleValvePwm(cltCorrectedPosition); - } + return correctedPosition; } void setIdleValvePosition(int positionPercent) { @@ -135,10 +133,9 @@ void setIdleValvePosition(int positionPercent) { showIdleInfo(); // todo: this is not great that we have to write into configuration here boardConfiguration->manIdlePosition = positionPercent; - manualIdleController(); } -static int idlePositionBeforeBlip; +static int blipIdlePosition; static efitimeus_t timeToStopBlip = 0; static efitimeus_t timeToStopIdleTest = 0; @@ -146,12 +143,10 @@ static efitimeus_t timeToStopIdleTest = 0; * I use this questionable feature to tune acceleration enrichment */ static void blipIdle(int idlePosition, int durationMs) { - // todo: add 'blip' feature for automatic target control if (timeToStopBlip != 0) { return; // already in idle blip } - idlePositionBeforeBlip = boardConfiguration->manIdlePosition; - setIdleValvePosition(idlePosition); + blipIdlePosition = idlePosition; timeToStopBlip = getTimeNowUs() + 1000 * durationMs; } @@ -163,7 +158,6 @@ static void finishIdleTestIfNeeded() { static void undoIdleBlipIfNeeded() { if (timeToStopBlip != 0 && getTimeNowUs() > timeToStopBlip) { timeToStopBlip = 0; - setIdleValvePosition(idlePositionBeforeBlip); } } @@ -177,18 +171,13 @@ percent_t getIdlePosition(void) { } } -static void autoIdle() { - efitimems_t now = currentTimeMillis(); +static float autoIdle(float cltCorrection) { - percent_t newValue = 0;//idlePositionController.getIdle(getRpmE(engine), now PASS_ENGINE_PARAMETER_SUFFIX); + int targetRpm = 1400 * cltCorrection; - if (currentIdleValve != newValue) { - currentIdleValve = newValue; + percent_t newValue = idlePid.getValue(targetRpm, getRpmE(engine)); - // todo: looks like in auto mode stepper value is not set, only solenoid? - - setIdleValvePwm(newValue); - } + return newValue; } static msg_t ivThread(int param) { @@ -219,13 +208,34 @@ static msg_t ivThread(int param) { finishIdleTestIfNeeded(); undoIdleBlipIfNeeded(); - if (engineConfiguration->idleMode == IM_MANUAL) { + float cltCorrection = interpolate2d(engine->sensors.clt, config->cltIdleCorrBins, config->cltIdleCorr, + CLT_CURVE_SIZE) / PERCENT_MULT; + + float iacPosition; + + if (timeToStopBlip != 0) { + iacPosition = blipIdlePosition; + } else if (isCranking()) { + // during cranking it's always manual mode, PID would make no sence during cranking + iacPosition = cltCorrection * engineConfiguration->crankingIACposition; + } else if (engineConfiguration->idleMode == IM_MANUAL) { // let's re-apply CLT correction - manualIdleController(); + iacPosition = manualIdleController(cltCorrection); } else { - autoIdle(); + iacPosition = autoIdle(cltCorrection); } + if (absF(iacPosition - actualIdlePosition) < 1) { + continue; // value is pretty close, let's leave the poor valve alone + } + + if (engineConfiguration->debugMode == DBG_IDLE) { + tsOutputChannels.debugFloatField1 = iacPosition; + } + + actualIdlePosition = iacPosition; + + applyIACposition(actualIdlePosition); } #if defined __GNUC__ return -1; diff --git a/firmware/controllers/settings.cpp b/firmware/controllers/settings.cpp index 6173f8b7f7..06efa4bb83 100644 --- a/firmware/controllers/settings.cpp +++ b/firmware/controllers/settings.cpp @@ -466,7 +466,7 @@ static void setRpmHardLimit(int value) { } static void setCrankingIACExtra(float percent) { - engineConfiguration->crankingIdleAdjustment = percent; + engineConfiguration->crankingIACposition = percent; scheduleMsg(&logger, "cranking_iac %f", percent); } @@ -994,6 +994,7 @@ plain_get_integer_s getI_plain[] = { // {"malfunction_indicator_pin_mode", setMalfunctionIndicatorPinMode}, // {"operation_mode", setOM}, {"debug_mode", (int*)&engineConfiguration->debugMode}, + {"cranking_iac", &engineConfiguration->crankingIACposition}, {"trigger_type", (int*)&engineConfiguration->trigger.type}, // {"idle_solenoid_freq", setIdleSolenoidFrequency}, // {"tps_accel_len", setTpsAccelLen}, @@ -1016,7 +1017,6 @@ plain_get_float_s getF_plain[] = { {"injection_offset", &engineConfiguration->extraInjectionOffset}, {"global_trigger_offset_angle", &engineConfiguration->globalTriggerAngleOffset}, {"cranking_fuel", &engineConfiguration->cranking.baseFuel}, - {"cranking_iac", &engineConfiguration->crankingIdleAdjustment}, {"cranking_timing_angle", &engineConfiguration->crankingTimingAngle}, {"cranking_charge_angle", &engineConfiguration->crankingChargeAngle}, }; diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 08e55829bb..371d53c843 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -586,7 +586,7 @@ custom le_formula_t 200 array, U08, @OFFSET@, [200],"char", 1, 0, 0.0, 3.0, 2 board_configuration_s bc; bit vvtDisplayInverted bit fuelClosedLoopCorrectionEnabled - bit unusedBit__5 + bit isVerboseIAC bit unusedBit__6 bit useConstantDwellDuringCranking bit isEngineChartEnabled;This options enables data for 'engine sniffer' tab in console, which comes at some CPU price @@ -752,7 +752,7 @@ float[MAP_ACCEL_TAPER] mapAccelTaperMult;;"mult", 1, 0, 0.0, 300, float egoValueShift;EGO value correction;"value", 1, 0, -10.0, 10, 2 brain_input_pin_e camInput; pid_dt[AUX_PID_COUNT iterate] auxPidDT; - float crankingIdleAdjustment;Extra idle while cranking;"percent", 1, 0, -100.0, 100, + int crankingIACposition;IAC cranking position;"percent", 1, 0, -100.0, 100, float tChargeMinRpmMinTps;;"mult", 1, 0, 0, 3, 4 float tChargeMinRpmMaxTps;;"mult", 1, 0, 0, 3, 4 float tChargeMaxRpmMinTps;;"mult", 1, 0, 0, 3, 4 diff --git a/firmware/tunerstudio/rusefi.ini b/firmware/tunerstudio/rusefi.ini index d83c4c1045..3f474c0ad2 100644 --- a/firmware/tunerstudio/rusefi.ini +++ b/firmware/tunerstudio/rusefi.ini @@ -45,7 +45,7 @@ enable2ndByteCanID = false ; see PAGE_0_SIZE in C source code ; CONFIG_DEFINITION_START -; this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Tue May 16 20:30:28 EDT 2017 +; this section was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Tue May 16 21:58:40 EDT 2017 pageSize = 16376 page = 1 @@ -426,7 +426,7 @@ page = 1 frequencyReportingMapInputPin = bits, U32, 1484, [0:6], "INVALID", "PA1", "PA2", "PA3", "INVALID", "PA5", "PA6", "PA7", "PA8", "PA9", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "PA15", "INVALID", "INVALID", "INVALID", "PB3", "PB4", "PB5", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "PC6", "PC7", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "PE5", "PE6", "INVALID", "INVALID", "PE9", "INVALID", "PE11", "INVALID", "INVALID", "INVALID", "INVALID", "NONE", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" vvtDisplayInverted = bits, U32, 1488, [0:0], "false", "true" fuelClosedLoopCorrectionEnabled= bits, U32, 1488, [1:1], "false", "true" - unusedBit__5 = bits, U32, 1488, [2:2], "false", "true" + isVerboseIAC = bits, U32, 1488, [2:2], "false", "true" unusedBit__6 = bits, U32, 1488, [3:3], "false", "true" useConstantDwellDuringCranking= bits, U32, 1488, [4:4], "false", "true" isEngineChartEnabled = bits, U32, 1488, [5:5], "false", "true" @@ -583,7 +583,7 @@ page = 1 auxPidDT2 = scalar, U32, 2416, "ms", 1, 0, 0, 3000, 0 auxPidDT3 = scalar, U32, 2420, "ms", 1, 0, 0, 3000, 0 auxPidDT4 = scalar, U32, 2424, "ms", 1, 0, 0, 3000, 0 - crankingIdleAdjustment = scalar, F32, 2428, "percent", 1, 0, -100.0, 100, + crankingIACposition = scalar, S32, 2428, "percent", 1, 0, -100.0, 100, tChargeMinRpmMinTps = scalar, F32, 2432, "mult", 1, 0, 0, 3, 4 tChargeMinRpmMaxTps = scalar, F32, 2436, "mult", 1, 0, 0, 3, 4 tChargeMaxRpmMinTps = scalar, F32, 2440, "mult", 1, 0, 0, 3, 4 diff --git a/java_console/models/src/com/rusefi/config/Fields.java b/java_console/models/src/com/rusefi/config/Fields.java index bc7816cd11..2fa1f72f61 100644 --- a/java_console/models/src/com/rusefi/config/Fields.java +++ b/java_console/models/src/com/rusefi/config/Fields.java @@ -1,6 +1,6 @@ package com.rusefi.config; -// this file was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Tue May 16 20:30:28 EDT 2017 +// this file was generated automatically by ConfigDefinition.jar based on rusefi_config.txt Tue May 16 21:58:40 EDT 2017 public class Fields { public static final int LE_COMMAND_LENGTH = 200; public static final int FSIO_ADC_COUNT = 4; @@ -622,7 +622,7 @@ public class Fields { public static final int frequencyReportingMapInputPin_offset = 1484; public static final int vvtDisplayInverted_offset = 1488; public static final int fuelClosedLoopCorrectionEnabled_offset = 1488; - public static final int unusedBit__5_offset = 1488; + public static final int isVerboseIAC_offset = 1488; public static final int unusedBit__6_offset = 1488; public static final int useConstantDwellDuringCranking_offset = 1488; public static final int isEngineChartEnabled_offset = 1488; @@ -843,7 +843,7 @@ public class Fields { public static final int auxPidDT3_offset_hex = 974; public static final int auxPidDT4_offset = 2424; public static final int auxPidDT4_offset_hex = 978; - public static final int crankingIdleAdjustment_offset = 2428; + public static final int crankingIACposition_offset = 2428; public static final int tChargeMinRpmMinTps_offset = 2432; public static final int tChargeMinRpmMinTps_offset_hex = 980; public static final int tChargeMinRpmMaxTps_offset = 2436; @@ -1435,7 +1435,7 @@ public class Fields { public static final Field FREQUENCYREPORTINGMAPINPUTPIN = Field.create("FREQUENCYREPORTINGMAPINPUTPIN", 1484, FieldType.INT, brain_input_pin_e); public static final Field VVTDISPLAYINVERTED = Field.create("VVTDISPLAYINVERTED", 1488, FieldType.BIT, 0); public static final Field FUELCLOSEDLOOPCORRECTIONENABLED = Field.create("FUELCLOSEDLOOPCORRECTIONENABLED", 1488, FieldType.BIT, 1); - public static final Field UNUSEDBIT__5 = Field.create("UNUSEDBIT__5", 1488, FieldType.BIT, 2); + public static final Field ISVERBOSEIAC = Field.create("ISVERBOSEIAC", 1488, FieldType.BIT, 2); public static final Field UNUSEDBIT__6 = Field.create("UNUSEDBIT__6", 1488, FieldType.BIT, 3); public static final Field USECONSTANTDWELLDURINGCRANKING = Field.create("USECONSTANTDWELLDURINGCRANKING", 1488, FieldType.BIT, 4); public static final Field ISENGINECHARTENABLED = Field.create("ISENGINECHARTENABLED", 1488, FieldType.BIT, 5); @@ -1579,7 +1579,7 @@ public class Fields { public static final Field AUXPIDDT2 = Field.create("AUXPIDDT2", 2416, FieldType.INT); public static final Field AUXPIDDT3 = Field.create("AUXPIDDT3", 2420, FieldType.INT); public static final Field AUXPIDDT4 = Field.create("AUXPIDDT4", 2424, FieldType.INT); - public static final Field CRANKINGIDLEADJUSTMENT = Field.create("CRANKINGIDLEADJUSTMENT", 2428, FieldType.FLOAT); + public static final Field CRANKINGIACPOSITION = Field.create("CRANKINGIACPOSITION", 2428, FieldType.INT); public static final Field TCHARGEMINRPMMINTPS = Field.create("TCHARGEMINRPMMINTPS", 2432, FieldType.FLOAT); public static final Field TCHARGEMINRPMMAXTPS = Field.create("TCHARGEMINRPMMAXTPS", 2436, FieldType.FLOAT); public static final Field TCHARGEMAXRPMMINTPS = Field.create("TCHARGEMAXRPMMINTPS", 2440, FieldType.FLOAT);