diff --git a/firmware/console/binary/tunerstudio_outputs.h b/firmware/console/binary/tunerstudio_outputs.h index 9109607c1f..cddacf5266 100644 --- a/firmware/console/binary/tunerstudio_outputs.h +++ b/firmware/console/binary/tunerstudio_outputs.h @@ -234,7 +234,9 @@ typedef struct { scaled_voltage rawPpsSecondary; // 248 - uint8_t unusedAtTheEnd[38]; // we have some unused bytes to allow compatible TS changes + int8_t knockLevels[12]; + + uint8_t unusedAtTheEnd[26]; // we have some unused bytes to allow compatible TS changes // Temporary - will remove soon TsDebugChannels* getDebugChannels() { diff --git a/firmware/controllers/algo/event_registry.h b/firmware/controllers/algo/event_registry.h index b80ff2f8c5..2d7c932b17 100644 --- a/firmware/controllers/algo/event_registry.h +++ b/firmware/controllers/algo/event_registry.h @@ -122,6 +122,7 @@ public: * [0, specs.cylindersCount) */ int cylinderIndex = 0; + int8_t cylinderNumber = 0; char *name = nullptr; DECLARE_ENGINE_PTR; IgnitionOutputPin *getOutputForLoggins(); diff --git a/firmware/controllers/engine_cycle/spark_logic.cpp b/firmware/controllers/engine_cycle/spark_logic.cpp index ba532450f8..2b2ce8b45c 100644 --- a/firmware/controllers/engine_cycle/spark_logic.cpp +++ b/firmware/controllers/engine_cycle/spark_logic.cpp @@ -117,6 +117,9 @@ static void prepareCylinderIgnitionSchedule(angle_t dwellAngleDuration, floatms_ event->outputs[0] = output; event->outputs[1] = secondOutput; event->sparkAngle = sparkAngle; + // Stash which cylinder we're scheduling so that knock sensing knows which + // cylinder just fired + event->cylinderNumber = coilIndex; angle_t dwellStartAngle = sparkAngle - dwellAngleDuration; efiAssertVoid(CUSTOM_ERR_6590, !cisnan(dwellStartAngle), "findAngle#5"); @@ -206,7 +209,7 @@ if (engineConfiguration->debugMode == DBG_DWELL_METRIC) { } #if EFI_SOFTWARE_KNOCK - startKnockSampling(event->cylinderIndex); + startKnockSampling(event->cylinderNumber); #endif } diff --git a/firmware/controllers/sensors/software_knock.cpp b/firmware/controllers/sensors/software_knock.cpp index bf179e7197..7cd07d3d81 100644 --- a/firmware/controllers/sensors/software_knock.cpp +++ b/firmware/controllers/sensors/software_knock.cpp @@ -13,6 +13,7 @@ EXTERN_ENGINE; #include "knock_config.h" adcsample_t sampleBuffer[2000]; +int8_t currentCylinderIndex = 0; Biquad knockFilter; static volatile bool knockIsSampling = false; @@ -56,6 +57,10 @@ void startKnockSampling(uint8_t cylinderIndex) { return; } + if (!engine->rpmCalculator.isRunning()) { + return; + } + // Cancel if ADC isn't ready if (!((KNOCK_ADC.state == ADC_READY) || (KNOCK_ADC.state == ADC_COMPLETE) || @@ -73,6 +78,7 @@ void startKnockSampling(uint8_t cylinderIndex) { constexpr int sampleRate = KNOCK_SAMPLE_RATE; sampleCount = 0xFFFFFFFE & static_cast(clampF(100, samplingSeconds * sampleRate, efi::size(sampleBuffer))); + currentCylinderIndex = cylinderIndex; adcStartConversionI(&KNOCK_ADC, &adcConvGroup, sampleBuffer, sampleCount); } @@ -129,6 +135,7 @@ void processLastKnockEvent() { // RMS float db = 10 * log10(meanSquares); + tsOutputChannels.knockLevels[currentCylinderIndex] = roundf(clampF(-100, db, 100)); tsOutputChannels.knockLevel = db; knockNeedsProcess = false; diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index c15c1ef70d..e9182fb9ec 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -343,6 +343,15 @@ enable2ndByteCanID = false tuneCrc16 = scalar, U16, 244, "crc16", 1, 0 sd_status = scalar, U08, 246, "", 1.0, 0.0 + knock1 = scalar, S08, 250, "dbv", 1, 0 + knock2 = scalar, S08, 251, "dbv", 1, 0 + knock3 = scalar, S08, 252, "dbv", 1, 0 + knock4 = scalar, S08, 253, "dbv", 1, 0 + knock5 = scalar, S08, 254, "dbv", 1, 0 + knock6 = scalar, S08, 255, "dbv", 1, 0 + knock7 = scalar, S08, 256, "dbv", 1, 0 + knock8 = scalar, S08, 257, "dbv", 1, 0 + ; ; see TunerStudioOutputChannels struct ; @@ -964,6 +973,16 @@ gaugeCategory = Sensors - Raw rawOilPressureGauge = rawOilPressure, "Raw Oil Pressure", "volts", 0, 5, 0, 0, 5, 5, 3, 0 rawPpsSecondaryGauge = rawPpsSecondary,"Raw Pedal Secondary","volts", 0, 5, 0, 0, 5, 5, 3, 0 +gaugeCategory = Knock + knock1Gauge = knock1, "Knock Cyl 1", "dBv", -60, 10, -60, -60, 10, 10, 0, 0 + knock2Gauge = knock2, "Knock Cyl 2", "dBv", -60, 10, -60, -60, 10, 10, 0, 0 + knock3Gauge = knock3, "Knock Cyl 3", "dBv", -60, 10, -60, -60, 10, 10, 0, 0 + knock4Gauge = knock4, "Knock Cyl 4", "dBv", -60, 10, -60, -60, 10, 10, 0, 0 + knock5Gauge = knock5, "Knock Cyl 5", "dBv", -60, 10, -60, -60, 10, 10, 0, 0 + knock6Gauge = knock6, "Knock Cyl 6", "dBv", -60, 10, -60, -60, 10, 10, 0, 0 + knock7Gauge = knock7, "Knock Cyl 7", "dBv", -60, 10, -60, -60, 10, 10, 0, 0 + knock8Gauge = knock8, "Knock Cyl 8", "dBv", -60, 10, -60, -60, 10, 10, 0, 0 + [WueAnalyze] ; wueCurveName, afrTempCompensationCurve, lambdaTargetTableName, lambdaChannel, coolantTempChannel, egoCorrectionChannel, wueChannel, activeCondition @@ -1167,6 +1186,14 @@ gaugeCategory = Sensors - Raw entry = etb1DutyCycle, @@GAUGE_NAME_ETB_DUTY@@, float, "%.3f" entry = etbTarget, "ETB Target", float, "%.3f" + entry = knock1, "Knock 1", int, "%d" + entry = knock2, "Knock 2", int, "%d" + entry = knock3, "Knock 3", int, "%d" + entry = knock4, "Knock 4", int, "%d" + entry = knock5, "Knock 5", int, "%d" + entry = knock6, "Knock 6", int, "%d" + entry = knock7, "Knock 7", int, "%d" + entry = knock8, "Knock 8", int, "%d" ; tpsADC = U16, "ADC", ; alignmet = U16, "al",