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
|
||||
|
||||
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() {
|
||||
|
|
|
@ -122,6 +122,7 @@ public:
|
|||
* [0, specs.cylindersCount)
|
||||
*/
|
||||
int cylinderIndex = 0;
|
||||
int8_t cylinderNumber = 0;
|
||||
char *name = nullptr;
|
||||
DECLARE_ENGINE_PTR;
|
||||
IgnitionOutputPin *getOutputForLoggins();
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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<size_t>(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;
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue