mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2026-09-18 19:13:58 +00:00
fix(rx): после обрыва кадра не требовать 30 мс тишины перед новым кандидатом преамбулы (releasePreambleGuard)
prevRise (последний декодированный фронт) не сбрасывался при abortFrame, а отброшенные гвардом фронты его не двигают — валидный кадр, начавшийся через <30 мс после обрыва мусора, проглатывался целиком без счётчика. Стенд 09.09: КУ теряла пинг машинки после обрывков чужого заднего и всплеска её дальномера за 24 мс до пинга (V-серия 75–83 %, после правки 100 %). Хост-тест (настоящий IR_DecoderRaw.cpp + шим Arduino): после abort кадр через 5…28 мс — терялся, теперь принимается; чистый конец кадра не тронут (мин. пауза 26.25 мс), хвост оборванного кадра ложных захватов не даёт, 200/200 валидных среди мусора, стресс 166→176/200. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AeA1K5dBUKrnoXVwyoVjzq
This commit is contained in:
@ -440,6 +440,19 @@ void IR_DecoderRaw::abortFrame(uint32_t tUs)
|
||||
isReciveRaw = false;
|
||||
msgTypeReceive = 0;
|
||||
firstRX();
|
||||
releasePreambleGuard(tUs);
|
||||
}
|
||||
|
||||
// После обрыва кадра «длинная тишина» (IR_timeout × 2 ≈ 30 мс) перед новым кандидатом преамбулы не требуется.
|
||||
// prevRise — последний ДЕКОДИРОВАННЫЙ фронт; после abort он свежий, а фронты, отброшенные гвардом, его не двигают,
|
||||
// поэтому валидный кадр, начавшийся через <30 мс после обрыва мусора, проглатывался целиком без счётчика
|
||||
// (стенд 09.09: КУ теряла пинг машинки после обрывков чужого заднего и всплеска её дальномера за 24 мс до пинга).
|
||||
// Ложных захватов это не добавляет: хвост оборванного кадра (период фронтов 962 мкс, синхробиты ~1100) не проходит
|
||||
// грубый фильтр периода преамбулы (2116…3270 мкс), а настоящая преамбула перезапускает кандидата по паузе > IR_timeout.
|
||||
// После чистого конца кадра гвард остаётся: там он отсекает хвост синхробитов.
|
||||
void IR_DecoderRaw::releasePreambleGuard(uint32_t tUs)
|
||||
{
|
||||
prevRise = tUs - IR_timeout * 2U - 1U; // «тишина уже была»: (front.time - prevRise) > longSilence для следующего фронта
|
||||
}
|
||||
|
||||
void IR_DecoderRaw::expirePreambleCandidate()
|
||||
|
||||
@ -186,6 +186,7 @@ private:
|
||||
RxEndInfo rxEnd;
|
||||
void noteRxEnd(RxEndReason reason, uint32_t tUs); // терминал: фиксирует тип/длину/расчётный конец
|
||||
void abortFrame(uint32_t tUs); // немедленный сброс битого кадра (sync/длина/overflow)
|
||||
void releasePreambleGuard(uint32_t tUs); // после abort: новый кандидат преамбулы без ожидания длинной тишины
|
||||
void expirePreambleCandidate(); // кандидат без фронтов дольше таймаута → Idle
|
||||
uint8_t preambleGoodPeriods = 0;
|
||||
uint16_t preambleMeanPeriod = 0;
|
||||
|
||||
Reference in New Issue
Block a user