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:
Matthew Kennedy 2020-08-31 18:05:33 -07:00 committed by GitHub
parent 5fc1b6902c
commit 988d9b138c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 2 deletions

View File

@ -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() {

View File

@ -122,6 +122,7 @@ public:
* [0, specs.cylindersCount)
*/
int cylinderIndex = 0;
int8_t cylinderNumber = 0;
char *name = nullptr;
DECLARE_ENGINE_PTR;
IgnitionOutputPin *getOutputForLoggins();

View File

@ -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
}

View File

@ -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;

View File

@ -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",