[[Manual: Foreword]]:


[[Manual: Detailed.Sensor.Knock.Realize]]

[[Manual: Detailed.Sensor.Knock.Operate]]

Note that there are some very primitive modules on the market that output knock-or-not-knock. It is very simple to use their output (even the kindergarten ECM-s can do it), but without appropriate windowing (which is both for noise-suppression, and telling which cylinder has the problem) they are next to useless. They can only detect knock-levels that you definitely never want to hear. Selecting modules or setting the bandpass frequency is exactly the same step as setting the bandpass frequency (in configuration) for the real integrated knock solution (this is usually the hardest part of a knocksensing-setup install).

Any really useful knockdetection requires very close integration with the engine management. Factory ECM-s usually get it right (one can always show counter-examples ).

Also see KnockListener WaveletTransformForKnock

[[Manual: Detailed.Sensor.Knock.Config]]

Knock Frequency


As you can see, the x axis is bore diameter and the y axis is THEORETICAL knocking frequency based on the speed of sound at a typical combustion temperature and pressure. The different coloured lines are different knock modes from basic 1st order back and forth across the chamber, to 6th order, kind of segmented, like a wave moving around the edge of the chamber. In practice only really the first 4 orders (up to about 20kHz) are detectable by current knock sensors.

In reality the frequency detected at the sensor varies slightly from the theory according to the combustion temp and pressure, block design, how the sensor is mounted and the sensor design itself, but this generally isn't more than about 0.5 to 1kHz out.

The TPIC8101DW used on the v3.3 has two channels, both configurable with different gain and bandpass filters.

So if we were to take as an example, an 81mm bore engine we have a ~7khz knock frequency as defined by the graph. If we were to feed the same signal in to the second channel and look for the 3rd or 4th order (mode) harmonic, (~15khz or ~16.7khz) and suitably increase the gain, we should be able to better identify knock instead of incidental noise that happens to occur at the ~7k mark.

Graph and explaination text published by kind permission of the original Author.

How to set up the characteristic knock frequency?

Alternatively hit the block with a wrench while engine is stopped. The knock frequency can be clearly read from the FFT (freq of peak amplitude) of the wav file (eg. use audacity, view, spectral view). You can try the experiment with different crank positions, but results shouldn't vari too much. Eg. for a 2L Peugeot S16 engine we measured 7050 Hz (very close to the calculated/guessed value).

[[Manual: Detailed.Sensor.Knock.Config]]

[[Manual: Detailed.Sensor.Knock.Realize]]

operation of knock code: see knock.c

[[Manual: Details.Sensor.Knock.Operate]]

J�gen, answer, please: Should we make the given ADC channel available for other purposes on v3.2 ?

Yes, I guess so. It's an fairly unoptimal trace, let's add a pad to the ADC6 input instead. No fancy stuff.

TODO: add config variables to GenBoard/InitialConfig page

Exciting details of the implementation

The entire framework around the knock handling is almost complete, only a few issues needs to be solved.

[[Manual: Detailed.Sensor.Knock.Operate]]

Threshold function

Currently the primary problem is to tell when knocking occurs. A simple condition like "knock_val > noise_val" is not sufficient, by experiment that condition evaluated to true at idle speeds without knocking.

Suggestions for better detection are:

but how are k derived? Any other ideas? If you provide matching knocksensor-wavs, TPIC8101 output and some suggestion where in the sample happens knock and where not, I will find best constants with simulated annealing approximation using simple models (something. like the combination of the above 2).

More details here: DetonationDetection/LogAnalysis

For analysis of the log file

Parsing of c-structures: google->pstruct->I feel lucky. There are also some modules on cpan that might be useful, Inline::Struct, Convert::Binary::C

I was intimidated by the complexity of these, and a bit afraid that they just add to the newbies's troubles when they want to run make mtt. So I split out config_t parsing to ParseStruct?.pm (should be ready to help with knock_cyl_t structure), and made it more general, and easier to use. updated accordingly.

Noise_val could also be averaged over a couple of cycles, but any noise present in noise_val_j will propably also be present in knock_val_j.

Here are 2 [] to evaluate. Taken with knock.c revision 1.47. Unfortunately they were taken in cold humid, rainy day in city, (hard to accelerate as one wants) with good fuel with not too much advance and there was a seal-problem before the turbo (some of the pressure sissing away, don't use Al before the turbo even as a thin seal). Knock will be rare.

When we tried increasing advance with DANGEROUS_KNOCK_TESTING at idle (earlier we did this by increasing the cranking-treshold RPM and setting crank_adv) it seemed to work well. Btw, the ignition-advance based idle-control actuation is absolutely impressive!

Threshold reached, when to start retarding?

Next, after a knock has been detected in a single sample, should this sample be used alone or should a couple of samples be evaluated to eliminate spurious noise? I think it is best to start retarding immediately. Maybe best to increase retard (every sample a knock is "heard") at a slower rate first, and at a higher rate if threshold is reached for a couple of times.

Say N samples are evaluated, if the fraction of samples which includes knocking are greater (less) than the fraction of samples without knocking, it is safe to say that knocking is present (or not present) in the samples. It might be too late... I'd start retarding immediately, but several samples confirming knock should make retard even more aggressive.

The limits of the knock related ignition adjustment are currently specified by a config-variable knock_max_retard. Other systems such as ecutek uses an entire table for specifying the limits, do we need/want that too?

Is a RPM-table enough? At a minimum, an RPM table is needed. (use h[1] for experiments).

Definitely, lower RPM will allow a smaller window for adjustments (as it is unwise to apply more advance, when the max power is approximately reached).

But does the window consistently contain the base ignadv value? Eg. the subwindow for retard is always 2 * subwindow for advance (window split in 1:2 ratio). Or does this split ratio change randomly across the loadsites? In the worst case, do we need 2*8*8 elements to determine what is allowed in either direction?

That can be packed into 8*8 bytes as the window size should fit in 4 bits. Eg.

Should the n[] table be the

My vote is (as in the code now) max ignadv (Ecutec uses min ignadv, can someone check other ECU-s and summarize? ) as the tuner who forgets to configure knock related stuff will be wrong in the safe direction. With min ignadv he will sorry. We might add valves and pistons to WebShop :-)

Starting (base) ignadv is not a good idea, as hmm.... what do you think, J�gen ?

I have checked the site and I don't think that Subarus ignition control is good for diy'ers. It's built to let a well defined engine adapt to different fuel qualities. There is also a part that adapt freely.

I think that I have a good approach here:

I like the 8X8 knock retard learning table in the Subaru software. Consider an 8X8 table with 1 user defined bit that tell the ecu to allow knock retard on this particular cell, 1 bit that tell the ECU to use this particular cell when calculating the final advance, 1 cell that allow ignition advance for this particular cell. The five remaining bits is used for specifying the learned table (+-15). If the 'don't use this cell when calculating final ignition advance' is false the remaining 6 bits can be used to store a knock count instead. When this knock count reach 63 for any of the cells all cells used for knock count should be shifted right one bit. Also increment a variable that keep track of the total number of right shifts.

I don't see a reason for an 'allowed ignition adjust' table. Using the same 'max dynamic advance' and 'max knock retard' values for all load sites is ok. The three user defined bits in each cell of the 8X8 table above should be enough. -J�gen

Retard might increase exhaust temp

When there is knock, it is a good idea to retard. The maximum retard is limited in configuration. (Much lower than what is used for ALS) This might cause some ExhaustGasTemp increase.

EGT must never prevent knock retard from occurring, knock is more likely to kill an engine then high exhaust temperatures. We could throw a code if EGT is getting too high


there is a good reason to start a bit retarded relative from desired advance

One can configure the desired, best power advance that he can achieve with the best fuel and humidity. However the best fuel and humidity is not always available, so it makes sense to start from a safer, slightly retarded value, and slowly advance to desirable advance if fuel allows (and knocksensor can't hear knock) without stressing engine (instead of starting from the most advance that will likely knock).

I think a new table should be made for knock detection. This table should contains the ignition advance or retards, and it could be saved into the main n-table. This feature could be very usefull for tuning the car. What do you think?

Here's a Texas Instrument knock sensor chip that seems to be a (very good) clone of the HIP9011 part. This one is around 5USD, but TI gives you up to 3 free samples of them so the price is hard to beat:

That is in the WebShop, you can buy with v3, and get the crystal part too. Please only order TI samples if developing a new application (even then play with v3 as a prototype).

[Application note for the hip9011]

TI appnote using a DSP for knock processing:

<Zoltan> The Texas chip has a mode called advanced SPI mode, in which a 10 bit knock value can be read through the SPI interface, making the A/D conversion unnecessary.

SigView? is great, but quite difficult to use.Does anybody has pre-made settings for knock detection with sigview?

See some papers, including IonSense at