rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Public Member Functions | Data Fields
TriggerAdcDetector Class Reference

#include <trigger_input_adc.h>

Collaboration diagram for TriggerAdcDetector:
Collaboration graph
[legend]

Public Member Functions

void init ()
 
void reset ()
 
void digitalCallback (efitick_t stamp, bool isPrimary, bool rise)
 
void analogCallback (efitick_t stamp, triggerAdcSample_t value)
 
void setWeakSignal (bool isWeak)
 

Data Fields

triggerAdcSample_t adcDefaultThreshold {}
 
triggerAdcSample_t adcMinThreshold {}
 
triggerAdcSample_t adcMaxThreshold {}
 
float triggerInputDividerCoefficient {}
 
float triggerAdcITermCoef = 1600.0f
 
float triggerAdcITermMin = 3.125e-8f
 
int transitionCooldown = 5
 
int analogToDigitalTransitionCnt {}
 
int digitalToAnalogTransitionCnt {}
 
triggerAdcMode_t curAdcMode = TRIGGER_ADC_NONE
 
float adcThreshold = adcDefaultThreshold
 
float triggerAdcITerm = triggerAdcITermMin
 
triggerAdcSample_t switchingThresholdLow = 0
 
triggerAdcSample_t switchingThresholdHigh = 0
 
efidur_t minDeltaTimeForStableAdcDetectionNt = 0
 
efidur_t stampCorrectionForAdc = 0
 
int switchingCnt = 0
 
int switchingTeethCnt = 0
 
int prevValue = 0
 
efitick_t prevStamp = 0
 
bool isSignalWeak = true
 
int zeroThreshold = 0
 
int minDeltaThresholdWeakSignal = 0
 
int minDeltaThresholdStrongSignal = 0
 
int minDeltaThresholdCntPos = 0
 
int minDeltaThresholdCntNeg = 0
 
int integralSum = 0
 
int transitionCooldownCnt = 0
 
int modeSwitchCnt = 0
 

Detailed Description

Definition at line 15 of file trigger_input_adc.h.

Member Function Documentation

◆ analogCallback()

void TriggerAdcDetector::analogCallback ( efitick_t  stamp,
triggerAdcSample_t  value 
)

Definition at line 278 of file trigger_input_adc.cpp.

278 {
279#if ! EFI_SIMULATOR && ((HAL_TRIGGER_USE_ADC && HAL_USE_ADC) || EFI_UNIT_TEST)
281 return;
282 }
283
284#ifdef TRIGGER_ADC_DUMP_BUF
285 dumpBuf[dumpBufCnt] = value;
287#endif /* TRIGGER_ADC_DUMP_BUF */
288
289 // <1V or >4V?
290 if (value >= switchingThresholdHigh || value <= switchingThresholdLow) {
291 switchingCnt++;
292 } else {
293 //switchingCnt = 0;
294 switchingCnt = maxI(switchingCnt - 1, 0);
295 }
296
297 int delta = value - adcThreshold;
298 int aDelta = absI(delta);
299 if (isSignalWeak) {
300 // todo: detect if the sensor is disconnected (where the signal is always near 'ADC_MAX_VALUE')
301
302 // filter out low signals (noise)
303 if (delta >= minDeltaThresholdWeakSignal) {
305 }
306 if (delta <= -minDeltaThresholdWeakSignal) {
308 }
309 } else {
310 // we just had a strong signal, let's reset the counter
311 if (delta >= minDeltaThresholdWeakSignal) {
312 minDeltaThresholdCntPos = DELTA_THRESHOLD_CNT_HIGH;
313 }
314 if (delta <= -minDeltaThresholdWeakSignal) {
315 minDeltaThresholdCntNeg = DELTA_THRESHOLD_CNT_HIGH;
316 }
319 // we haven't seen the strong signal (pos or neg) for too long, maybe it's lost or too weak?
321 // reset to the weak signal mode
322 reset();
323 return;
324 }
325 }
326
327 // the threshold should always correspond to the averaged signal.
328 integralSum += delta;
329 // we need some limits for the integral sum
330 // we use a simple I-regulator to move the threshold
332 // limit the threshold for safety
334
335 // now to the transition part... First, we need a cooldown to pre-filter the transition noise
336 if (transitionCooldownCnt-- < 0)
338
339 // we need at least 2 different measurements to detect a transition
340 if (prevValue == 0) {
341 // we can take the measurement only from outside the dead-zone
342 if (aDelta > minDeltaThresholdWeakSignal) {
343 prevValue = (delta > 0) ? 1 : -1;
344 } else {
345 return;
346 }
347 }
348
349 if (isSignalWeak) {
350 if (minDeltaThresholdCntPos >= DELTA_THRESHOLD_CNT_LOW && minDeltaThresholdCntNeg >= DELTA_THRESHOLD_CNT_LOW) {
351 // ok, now we have a legit strong signal, let's restore the threshold
352 isSignalWeak = false;
353 integralSum = 0;
355 } else {
356 // we cannot trust the weak signal!
357 return;
358 }
359 }
360
361 if (transitionCooldownCnt <= 0) {
362 // detect the edge
363 int transition = 0;
364 if (delta > zeroThreshold && prevValue == -1) {
365 // a rising transition found!
366 transition = 1;
367 }
368 else if (delta <= -zeroThreshold && prevValue == 1) {
369 // a falling transition found!
370 transition = -1;
371 }
372 else {
373 return; // both are positive/negative/zero: not interested!
374 }
375
376 onTriggerChanged(stamp - stampCorrectionForAdc, true, transition == 1);
377 // let's skip some nearest possible measurements:
378 // the transition cannot be SO fast, but the jitter can!
380
381 // it should not accumulate too much
382 integralSum = 0;
383#if 0
384 // update triggerAdcITerm
385 efitimeus_t deltaTimeUs = NT2US(stamp - prevStamp);
386 if (deltaTimeUs > 200) { // 200 us = ~2500 RPM (we don't need this correction for large RPM)
387 triggerAdcITerm = 1.0f / (triggerAdcITermCoef * deltaTimeUs);
389 }
390#endif // 0
391
392 prevValue = transition;
393 }
394
395#ifdef EFI_SHAFT_POSITION_INPUT
397 switchingCnt = 0;
398 // we need at least 3 high-signal teeth to be certain!
399 if (switchingTeethCnt++ > 3) {
401
403
404 // we don't want to loose the signal on return
405 minDeltaThresholdCntPos = DELTA_THRESHOLD_CNT_HIGH;
406 minDeltaThresholdCntNeg = DELTA_THRESHOLD_CNT_HIGH;
407 // we want to reset the thresholds on return
410 // reset integrator
412 integralSum = 0;
414 return;
415 }
416 } else {
417 // we don't see "big teeth" anymore
419 }
420#endif // EFI_SHAFT_POSITION_INPUT
421
422 prevStamp = stamp;
423#else
424 UNUSED(stamp); UNUSED(value);
425#endif // ! EFI_SIMULATOR && ((HAL_TRIGGER_USE_ADC && HAL_USE_ADC) || EFI_UNIT_TEST)
426}
triggerAdcSample_t switchingThresholdHigh
triggerAdcSample_t switchingThresholdLow
triggerAdcSample_t adcMaxThreshold
triggerAdcSample_t adcMinThreshold
triggerAdcMode_t curAdcMode
triggerAdcSample_t adcDefaultThreshold
UNUSED(samplingTimeSeconds)
void setTriggerAdcMode(triggerAdcMode_t adcMode)
@ TRIGGER_ADC_ADC
@ TRIGGER_ADC_EXTI
void onTriggerChanged(efitick_t stamp, bool isPrimary, bool isRising)
static const int dumpBufNum
static triggerAdcSample_t dumpBuf[dumpBufNum]
static int dumpBufCnt

Referenced by triggerAdcCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ digitalCallback()

void TriggerAdcDetector::digitalCallback ( efitick_t  stamp,
bool  isPrimary,
bool  rise 
)

Definition at line 244 of file trigger_input_adc.cpp.

244 {
245#if !EFI_SIMULATOR && EFI_SHAFT_POSITION_INPUT
247 return;
248 }
249
250 UNUSED(isPrimary);
251
252 onTriggerChanged(stamp, isPrimary, rise);
253
254#if (HAL_TRIGGER_USE_ADC && HAL_USE_ADC) || EFI_UNIT_TEST
256 switchingCnt++;
257 } else {
258 switchingCnt = 0;
260 }
261
263 switchingCnt = 0;
264 // we need at least 3 wide teeth to be certain!
265 // we don't want to confuse them with a sync.gap
266 if (switchingTeethCnt++ > 3) {
268 prevValue = rise ? 1: -1;
270 }
271 }
272#endif // (HAL_TRIGGER_USE_ADC && HAL_USE_ADC) || EFI_UNIT_TEST
273
274 prevStamp = stamp;
275#endif // !EFI_SIMULATOR && EFI_SHAFT_POSITION_INPUT
276}
efidur_t minDeltaTimeForStableAdcDetectionNt

Referenced by shaft_callback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init()

void TriggerAdcDetector::init ( )

Definition at line 182 of file trigger_input_adc.cpp.

182 {
183#if ! EFI_SIMULATOR
184
185 // todo: move some of these to config
186
187#if HAL_USE_ADC || EFI_UNIT_TEST
188 // 4.7k||5.1k + 4.7k
189 triggerInputDividerCoefficient = 1.52f; // = analogInputDividerCoefficient
190
191 // we need to make at least minNumAdcMeasurementsPerTooth for 1 tooth (i.e. between two consequent events)
192 const int minNumAdcMeasurementsPerTooth = 10; // for 60-2 wheel: 1/(10*2*60/10000/60) = 500 RPM
193 minDeltaTimeForStableAdcDetectionNt = US2NT(US_PER_SECOND_LL * minNumAdcMeasurementsPerTooth * GPT_PERIOD_FAST / GPT_FREQ_FAST);
194 // we assume that the transition occurs somewhere in the middle of the measurement period, so we take the half of it
195 stampCorrectionForAdc = US2NT(US_PER_SECOND_LL * GPT_PERIOD_FAST / GPT_FREQ_FAST / 2);
196
199
200 // used to filter out low signals
201 minDeltaThresholdWeakSignal = triggerVoltsToAdcDivided(0.05f); // 50mV
202 // we need to shift the default threshold even for strong signals because of the possible loss of the first tooth (after the sync)
203 minDeltaThresholdStrongSignal = triggerVoltsToAdcDivided(0.04f); // 5mV
204
205 const triggerAdcSample_t adcDeltaThreshold = triggerVoltsToAdcDivided(0.25f);
206 adcDefaultThreshold = triggerVoltsToAdcDivided(2.5f); // this corresponds to VREF1 on Hellen boards
207 adcMinThreshold = adcDefaultThreshold - adcDeltaThreshold;
208 adcMaxThreshold = adcDefaultThreshold + adcDeltaThreshold;
209
210 // these thresholds allow to switch from ADC mode to EXTI mode, indicating the clamping of the signal
211 // they should exceed the MCU schmitt trigger thresholds (usually 0.3*Vdd and 0.7*Vdd)
212 switchingThresholdLow = triggerVoltsToAdcDivided(1.0f); // = 0.2*Vdd (<0.3*Vdd)
213 switchingThresholdHigh = triggerVoltsToAdcDivided(4.0f); // = 0.8*Vdd (>0.7*Vdd)
214#endif // HAL_USE_ADC || EFI_UNIT_TEST
215
216 modeSwitchCnt = 0;
217
218 reset();
219#endif // ! EFI_SIMULATOR
220}
adcsample_t triggerAdcSample_t

Referenced by adcTriggerTurnOnInputPin().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reset()

void TriggerAdcDetector::reset ( )

Definition at line 222 of file trigger_input_adc.cpp.

222 {
223 switchingCnt = 0;
225#if HAL_USE_ADC || EFI_UNIT_TEST
226 // when the strong signal becomes weak, we want to ignore the increased noise
227 // so we create a dead-zone between the pos. and neg. thresholds
230
232
233 isSignalWeak = true;
234 integralSum = 0;
238#endif // HAL_USE_ADC || EFI_UNIT_TEST
239
240 prevValue = 0; // not set
241 prevStamp = 0;
242}

Referenced by analogCallback(), and init().

Here is the caller graph for this function:

◆ setWeakSignal()

void TriggerAdcDetector::setWeakSignal ( bool  isWeak)

Definition at line 428 of file trigger_input_adc.cpp.

428 {
429#if HAL_USE_ADC || EFI_UNIT_TEST
430 isSignalWeak = isWeak;
431 if (!isSignalWeak) {
432 minDeltaThresholdCntPos = minDeltaThresholdCntNeg = DELTA_THRESHOLD_CNT_LOW;
433 } else {
435 }
436#endif // HAL_USE_ADC || EFI_UNIT_TEST
437}

Field Documentation

◆ adcDefaultThreshold

triggerAdcSample_t TriggerAdcDetector::adcDefaultThreshold {}

Definition at line 26 of file trigger_input_adc.h.

26{};

Referenced by analogCallback(), init(), and reset().

◆ adcMaxThreshold

triggerAdcSample_t TriggerAdcDetector::adcMaxThreshold {}

Definition at line 28 of file trigger_input_adc.h.

28{};

Referenced by analogCallback(), and init().

◆ adcMinThreshold

triggerAdcSample_t TriggerAdcDetector::adcMinThreshold {}

Definition at line 27 of file trigger_input_adc.h.

27{};

Referenced by analogCallback(), and init().

◆ adcThreshold

float TriggerAdcDetector::adcThreshold = adcDefaultThreshold

Definition at line 41 of file trigger_input_adc.h.

Referenced by analogCallback(), getTriggerAdcThreshold(), and reset().

◆ analogToDigitalTransitionCnt

int TriggerAdcDetector::analogToDigitalTransitionCnt {}

Definition at line 37 of file trigger_input_adc.h.

37{};

Referenced by analogCallback(), and init().

◆ curAdcMode

triggerAdcMode_t TriggerAdcDetector::curAdcMode = TRIGGER_ADC_NONE

◆ digitalToAnalogTransitionCnt

int TriggerAdcDetector::digitalToAnalogTransitionCnt {}

Definition at line 38 of file trigger_input_adc.h.

38{};

Referenced by digitalCallback(), and init().

◆ integralSum

int TriggerAdcDetector::integralSum = 0

Definition at line 61 of file trigger_input_adc.h.

Referenced by analogCallback(), and reset().

◆ isSignalWeak

bool TriggerAdcDetector::isSignalWeak = true

Definition at line 53 of file trigger_input_adc.h.

Referenced by analogCallback(), reset(), and setWeakSignal().

◆ minDeltaThresholdCntNeg

int TriggerAdcDetector::minDeltaThresholdCntNeg = 0

Definition at line 60 of file trigger_input_adc.h.

Referenced by analogCallback(), reset(), and setWeakSignal().

◆ minDeltaThresholdCntPos

int TriggerAdcDetector::minDeltaThresholdCntPos = 0

Definition at line 60 of file trigger_input_adc.h.

Referenced by analogCallback(), reset(), and setWeakSignal().

◆ minDeltaThresholdStrongSignal

int TriggerAdcDetector::minDeltaThresholdStrongSignal = 0

Definition at line 57 of file trigger_input_adc.h.

Referenced by analogCallback(), and init().

◆ minDeltaThresholdWeakSignal

int TriggerAdcDetector::minDeltaThresholdWeakSignal = 0

Definition at line 57 of file trigger_input_adc.h.

Referenced by analogCallback(), init(), and reset().

◆ minDeltaTimeForStableAdcDetectionNt

efidur_t TriggerAdcDetector::minDeltaTimeForStableAdcDetectionNt = 0

Definition at line 46 of file trigger_input_adc.h.

Referenced by digitalCallback(), and init().

◆ modeSwitchCnt

int TriggerAdcDetector::modeSwitchCnt = 0

Definition at line 64 of file trigger_input_adc.h.

Referenced by getTriggerAdcModeCnt(), init(), and setTriggerAdcMode().

◆ prevStamp

efitick_t TriggerAdcDetector::prevStamp = 0

Definition at line 50 of file trigger_input_adc.h.

Referenced by analogCallback(), digitalCallback(), and reset().

◆ prevValue

int TriggerAdcDetector::prevValue = 0

Definition at line 49 of file trigger_input_adc.h.

Referenced by analogCallback(), digitalCallback(), and reset().

◆ stampCorrectionForAdc

efidur_t TriggerAdcDetector::stampCorrectionForAdc = 0

Definition at line 47 of file trigger_input_adc.h.

Referenced by analogCallback(), and init().

◆ switchingCnt

int TriggerAdcDetector::switchingCnt = 0

Definition at line 48 of file trigger_input_adc.h.

Referenced by analogCallback(), digitalCallback(), and reset().

◆ switchingTeethCnt

int TriggerAdcDetector::switchingTeethCnt = 0

Definition at line 48 of file trigger_input_adc.h.

Referenced by analogCallback(), digitalCallback(), and reset().

◆ switchingThresholdHigh

triggerAdcSample_t TriggerAdcDetector::switchingThresholdHigh = 0

Definition at line 45 of file trigger_input_adc.h.

Referenced by analogCallback(), and init().

◆ switchingThresholdLow

triggerAdcSample_t TriggerAdcDetector::switchingThresholdLow = 0

Definition at line 45 of file trigger_input_adc.h.

Referenced by analogCallback(), and init().

◆ transitionCooldown

int TriggerAdcDetector::transitionCooldown = 5

Definition at line 35 of file trigger_input_adc.h.

Referenced by analogCallback().

◆ transitionCooldownCnt

int TriggerAdcDetector::transitionCooldownCnt = 0

Definition at line 62 of file trigger_input_adc.h.

Referenced by analogCallback(), and reset().

◆ triggerAdcITerm

float TriggerAdcDetector::triggerAdcITerm = triggerAdcITermMin

Definition at line 42 of file trigger_input_adc.h.

Referenced by analogCallback(), and reset().

◆ triggerAdcITermCoef

float TriggerAdcDetector::triggerAdcITermCoef = 1600.0f

Definition at line 32 of file trigger_input_adc.h.

Referenced by analogCallback().

◆ triggerAdcITermMin

float TriggerAdcDetector::triggerAdcITermMin = 3.125e-8f

Definition at line 33 of file trigger_input_adc.h.

Referenced by analogCallback(), and reset().

◆ triggerInputDividerCoefficient

float TriggerAdcDetector::triggerInputDividerCoefficient {}

Definition at line 30 of file trigger_input_adc.h.

30{};

Referenced by init().

◆ zeroThreshold

int TriggerAdcDetector::zeroThreshold = 0

Definition at line 54 of file trigger_input_adc.h.

Referenced by analogCallback(), and reset().


The documentation for this class was generated from the following files: