diff --git a/firmware/console/binary/tunerstudio_outputs.h b/firmware/console/binary/tunerstudio_outputs.h index 54bb51b212..b95f45c1dc 100644 --- a/firmware/console/binary/tunerstudio_outputs.h +++ b/firmware/console/binary/tunerstudio_outputs.h @@ -281,7 +281,9 @@ struct TunerStudioOutputChannels { scaled_voltage rawTps2Primary; // 302 scaled_voltage rawTps2Secondary; // 304 - uint8_t unusedAtTheEnd[32]; // we have some unused bytes to allow compatible TS changes + scaled_channel knockCount; + + uint8_t unusedAtTheEnd[30]; // we have some unused bytes to allow compatible TS changes // Temporary - will remove soon TsDebugChannels* getDebugChannels() { diff --git a/firmware/controllers/algo/engine2.cpp b/firmware/controllers/algo/engine2.cpp index e332b59643..1cfeac0f55 100644 --- a/firmware/controllers/algo/engine2.cpp +++ b/firmware/controllers/algo/engine2.cpp @@ -138,7 +138,7 @@ void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) { cltTimingCorrection = getCltTimingCorrection(PASS_ENGINE_PARAMETER_SIGNATURE); - engineNoiseHipLevel = interpolate2d(rpm, engineConfiguration->knockNoiseRpmBins, + knockThreshold = interpolate2d(rpm, engineConfiguration->knockNoiseRpmBins, engineConfiguration->knockNoise); baroCorrection = getBaroCorrection(PASS_ENGINE_PARAMETER_SIGNATURE); diff --git a/firmware/controllers/algo/engine_state.h b/firmware/controllers/algo/engine_state.h index 1fccb868c0..07dd6252f2 100644 --- a/firmware/controllers/algo/engine_state.h +++ b/firmware/controllers/algo/engine_state.h @@ -32,7 +32,7 @@ public: */ float airFlow = 0; - float engineNoiseHipLevel = 0; + float knockThreshold = 0; float auxValveStart = 0; float auxValveEnd = 0; diff --git a/firmware/controllers/sensors/software_knock.cpp b/firmware/controllers/sensors/software_knock.cpp index fc0b3e3bbd..138b8aa923 100644 --- a/firmware/controllers/sensors/software_knock.cpp +++ b/firmware/controllers/sensors/software_knock.cpp @@ -232,6 +232,11 @@ void processLastKnockEvent() { tsOutputChannels.knockLevels[currentCylinderIndex] = roundf(cylPeak); tsOutputChannels.knockLevel = allCylinderPeakDetector.detect(db, lastKnockTime); + // If this was a knock, count it! + bool isKnock = db > ENGINE(engineState).knockThreshold; + if (isKnock) { + tsOutputChannels.knockCount++; + } } void KnockThread::ThreadTask() { diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index 0381ff773e..297090af73 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -294,6 +294,7 @@ enable2ndByteCanID = false ; Knock knockLevel = scalar, F32, 108, "Volts", 1, 0 + knockCount = scalar, U16, 306, "count", 1, 0 ; Mode, firmware, protocol, run time ; TS requires 'seconds' name since it has special internal meaning @@ -979,6 +980,7 @@ gaugeCategory = Sensors - Extra 2 egt8Gauge = egt8, "EGT#8", "C", 0, 2000 rpmAccelerationGa = rpmAcceleration, "rpm delta", "RPM/s", -2000, 2000, -2000, 2000, -2000, 2000, 0, 0 knockLevelGauge = knockLevel,"Knock level", "volts", 0, 7, 10, 10, 100, 100, 1, 2 + knockCountGauge = knockCount, "Knock count", "count", 0, 10000, 0, 0, 10000, 10000, 0, 0 fuelTankLevelGauge = fuelTankLevel,"Fuel level", "%", 0, 100, 10, 20, 100, 100, 1, 1 speedToRpmRatioGauge = speedToRpmRatio, "speed2rpm", "", 0, 100, 0, 0, 100, 100, 4, 4 wastegatePosGauge = wastegatePositionSensor, @@GAUGE_NAME_WG_POSITION@@, "%", 0, 100, 0, 0, 100, 100, 1, 1 diff --git a/firmware/util/scaled_channel.h b/firmware/util/scaled_channel.h index 9acf7fa93e..f3f4b4a8ed 100644 --- a/firmware/util/scaled_channel.h +++ b/firmware/util/scaled_channel.h @@ -12,6 +12,7 @@ #pragma once #include +#include #include "rusefi_generated.h" @@ -22,6 +23,8 @@ // float x = myVar; // converts back to float, returns 2.4f template class scaled_channel { + using TSelf = scaled_channel; + public: constexpr scaled_channel() : m_value(static_cast(0)) { } constexpr scaled_channel(float val) @@ -35,8 +38,14 @@ public: } // Postfix increment operator - T operator ++(int) { - return (m_value / (float)mult) + 1; + // only enable if: + // - base type T is an integral type (integer) + // - multiplier is equal to 1 + void operator++(int) { + static_assert(mult == 1, "Increment operator only supported for non-scaled integer types"); + static_assert(std::is_integral_v, "Increment operator only supported for non-scaled integer types"); + + m_value++; } constexpr const char* getFirstByteAddr() const {