detect which cylinder knocked (#1732)
* s * science * set pin mode * turn stuff off so it fits * filtering maybe * filtering actually works * generate filter parameters internally * shorter window * guard behind enable flag * use checked in filter * add biquad reset * tracing * const * exec order * do it from a thread * smaller buffer, comment * configure with header * only for proteus * oops * unused * not needed * guards * pin config * don't need that include * precook filter steady state * define sample rate * multi cylinder knock * TS * only sense when running
This commit is contained in:
parent
5fc1b6902c
commit
988d9b138c
|
@ -234,7 +234,9 @@ typedef struct {
|
||||||
|
|
||||||
scaled_voltage rawPpsSecondary; // 248
|
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
|
// Temporary - will remove soon
|
||||||
TsDebugChannels* getDebugChannels() {
|
TsDebugChannels* getDebugChannels() {
|
||||||
|
|
|
@ -122,6 +122,7 @@ public:
|
||||||
* [0, specs.cylindersCount)
|
* [0, specs.cylindersCount)
|
||||||
*/
|
*/
|
||||||
int cylinderIndex = 0;
|
int cylinderIndex = 0;
|
||||||
|
int8_t cylinderNumber = 0;
|
||||||
char *name = nullptr;
|
char *name = nullptr;
|
||||||
DECLARE_ENGINE_PTR;
|
DECLARE_ENGINE_PTR;
|
||||||
IgnitionOutputPin *getOutputForLoggins();
|
IgnitionOutputPin *getOutputForLoggins();
|
||||||
|
|
|
@ -117,6 +117,9 @@ static void prepareCylinderIgnitionSchedule(angle_t dwellAngleDuration, floatms_
|
||||||
event->outputs[0] = output;
|
event->outputs[0] = output;
|
||||||
event->outputs[1] = secondOutput;
|
event->outputs[1] = secondOutput;
|
||||||
event->sparkAngle = sparkAngle;
|
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;
|
angle_t dwellStartAngle = sparkAngle - dwellAngleDuration;
|
||||||
efiAssertVoid(CUSTOM_ERR_6590, !cisnan(dwellStartAngle), "findAngle#5");
|
efiAssertVoid(CUSTOM_ERR_6590, !cisnan(dwellStartAngle), "findAngle#5");
|
||||||
|
@ -206,7 +209,7 @@ if (engineConfiguration->debugMode == DBG_DWELL_METRIC) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if EFI_SOFTWARE_KNOCK
|
#if EFI_SOFTWARE_KNOCK
|
||||||
startKnockSampling(event->cylinderIndex);
|
startKnockSampling(event->cylinderNumber);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ EXTERN_ENGINE;
|
||||||
#include "knock_config.h"
|
#include "knock_config.h"
|
||||||
|
|
||||||
adcsample_t sampleBuffer[2000];
|
adcsample_t sampleBuffer[2000];
|
||||||
|
int8_t currentCylinderIndex = 0;
|
||||||
Biquad knockFilter;
|
Biquad knockFilter;
|
||||||
|
|
||||||
static volatile bool knockIsSampling = false;
|
static volatile bool knockIsSampling = false;
|
||||||
|
@ -56,6 +57,10 @@ void startKnockSampling(uint8_t cylinderIndex) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!engine->rpmCalculator.isRunning()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Cancel if ADC isn't ready
|
// Cancel if ADC isn't ready
|
||||||
if (!((KNOCK_ADC.state == ADC_READY) ||
|
if (!((KNOCK_ADC.state == ADC_READY) ||
|
||||||
(KNOCK_ADC.state == ADC_COMPLETE) ||
|
(KNOCK_ADC.state == ADC_COMPLETE) ||
|
||||||
|
@ -73,6 +78,7 @@ void startKnockSampling(uint8_t cylinderIndex) {
|
||||||
constexpr int sampleRate = KNOCK_SAMPLE_RATE;
|
constexpr int sampleRate = KNOCK_SAMPLE_RATE;
|
||||||
sampleCount = 0xFFFFFFFE & static_cast<size_t>(clampF(100, samplingSeconds * sampleRate, efi::size(sampleBuffer)));
|
sampleCount = 0xFFFFFFFE & static_cast<size_t>(clampF(100, samplingSeconds * sampleRate, efi::size(sampleBuffer)));
|
||||||
|
|
||||||
|
currentCylinderIndex = cylinderIndex;
|
||||||
adcStartConversionI(&KNOCK_ADC, &adcConvGroup, sampleBuffer, sampleCount);
|
adcStartConversionI(&KNOCK_ADC, &adcConvGroup, sampleBuffer, sampleCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +135,7 @@ void processLastKnockEvent() {
|
||||||
// RMS
|
// RMS
|
||||||
float db = 10 * log10(meanSquares);
|
float db = 10 * log10(meanSquares);
|
||||||
|
|
||||||
|
tsOutputChannels.knockLevels[currentCylinderIndex] = roundf(clampF(-100, db, 100));
|
||||||
tsOutputChannels.knockLevel = db;
|
tsOutputChannels.knockLevel = db;
|
||||||
|
|
||||||
knockNeedsProcess = false;
|
knockNeedsProcess = false;
|
||||||
|
|
|
@ -343,6 +343,15 @@ enable2ndByteCanID = false
|
||||||
tuneCrc16 = scalar, U16, 244, "crc16", 1, 0
|
tuneCrc16 = scalar, U16, 244, "crc16", 1, 0
|
||||||
sd_status = scalar, U08, 246, "", 1.0, 0.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
|
; see TunerStudioOutputChannels struct
|
||||||
;
|
;
|
||||||
|
@ -964,6 +973,16 @@ gaugeCategory = Sensors - Raw
|
||||||
rawOilPressureGauge = rawOilPressure, "Raw Oil Pressure", "volts", 0, 5, 0, 0, 5, 5, 3, 0
|
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
|
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]
|
[WueAnalyze]
|
||||||
|
|
||||||
; wueCurveName, afrTempCompensationCurve, lambdaTargetTableName, lambdaChannel, coolantTempChannel, egoCorrectionChannel, wueChannel, activeCondition
|
; wueCurveName, afrTempCompensationCurve, lambdaTargetTableName, lambdaChannel, coolantTempChannel, egoCorrectionChannel, wueChannel, activeCondition
|
||||||
|
@ -1167,6 +1186,14 @@ gaugeCategory = Sensors - Raw
|
||||||
entry = etb1DutyCycle, @@GAUGE_NAME_ETB_DUTY@@, float, "%.3f"
|
entry = etb1DutyCycle, @@GAUGE_NAME_ETB_DUTY@@, float, "%.3f"
|
||||||
entry = etbTarget, "ETB Target", 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",
|
; tpsADC = U16, "ADC",
|
||||||
; alignmet = U16, "al",
|
; alignmet = U16, "al",
|
||||||
|
|
Loading…
Reference in New Issue