From c4d9c4a2c5daa17756f8bb6fdbb4e15362879bef Mon Sep 17 00:00:00 2001 From: Rodrigo Alfonso Date: Tue, 11 Feb 2025 20:58:51 -0300 Subject: [PATCH] FIX: Making IR demodulation more reliable using DEMODULATION_HYSTERESIS_DELAY --- lib/LinkIR.hpp | 1 + lib/iwram_code/LinkIR.cpp | 38 ++++++++++++++++++++++++++------------ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/lib/LinkIR.hpp b/lib/LinkIR.hpp index efe8c24..4410e1a 100644 --- a/lib/LinkIR.hpp +++ b/lib/LinkIR.hpp @@ -71,6 +71,7 @@ class LinkIR { static constexpr int DEMODULATION_SPACE_PERIODS = 3; static constexpr int DEMODULATION_SPACE_THRESHOLD = DEMODULATION_38KHZ_PERIOD * DEMODULATION_SPACE_PERIODS; + static constexpr int DEMODULATION_HYSTERESIS_DELAY = 10; static constexpr int NEC_TOLERANCE_PERCENTAGE = 15; static constexpr int NEC_TOTAL_PULSES = 68; static constexpr int NEC_LEADER_MARK = 9000; diff --git a/lib/iwram_code/LinkIR.cpp b/lib/iwram_code/LinkIR.cpp index 333fa62..c5c5152 100644 --- a/lib/iwram_code/LinkIR.cpp +++ b/lib/iwram_code/LinkIR.cpp @@ -33,6 +33,9 @@ LINK_CODE_IWRAM bool LinkIR::receive(u16 pulses[], u32 pulseIndex = 0; u32 lastTransitionTime = 0; + bool candidateTransitionActive = false; + u32 candidateTransitionStart = 0; + firstLightTime = 0; lastLightTime = 0; transitionCount = 0; @@ -62,18 +65,29 @@ LINK_CODE_IWRAM bool LinkIR::receive(u16 pulses[], hasStarted = true; } - if (hasStarted && isMark && - timeSinceLastLight >= - DEMODULATION_SPACE_THRESHOLD * CYCLES_PER_MICROSECOND) { - // mark -> space - u32 pulseDuration = - (currentLastLightTime - lastTransitionTime) / CYCLES_PER_MICROSECOND; - pulses[pulseIndex++] = pulseDuration; - if (pulseIndex >= maxEntries - 1) - break; - isMark = false; - lastTransitionTime = currentLastLightTime; - transitionCount = 0; + if (hasStarted && isMark) { + if (timeSinceLastLight >= + DEMODULATION_SPACE_THRESHOLD * CYCLES_PER_MICROSECOND) { + // mark -> space? + if (!candidateTransitionActive) { + candidateTransitionActive = true; + candidateTransitionStart = now; + } else if (now - candidateTransitionStart >= + DEMODULATION_HYSTERESIS_DELAY * CYCLES_PER_MICROSECOND) { + // mark -> space (confirmed after hysteresis delay) + u32 pulseDuration = (currentLastLightTime - lastTransitionTime) / + CYCLES_PER_MICROSECOND; + pulses[pulseIndex++] = pulseDuration; + if (pulseIndex >= maxEntries - 1) + break; + isMark = false; + lastTransitionTime = currentLastLightTime; + transitionCount = 0; + candidateTransitionActive = false; + } + } else { + candidateTransitionActive = false; + } } // Timeouts