From 9236f8f3139cd7a661363c50a7322e33f049b5bb Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 1 Nov 2026 19:11:27 +0000 Subject: [PATCH] debounce updates --- include/etl/debounce_value.h | 56 ++----------- test/test_debounce_value.cpp | 144 +++++++++++++++++++++++++++++++- test/vs2022/etl.vcxproj | 1 - test/vs2022/etl.vcxproj.filters | 9 ++ 4 files changed, 155 insertions(+), 55 deletions(-) diff --git a/include/etl/debounce_value.h b/include/etl/debounce_value.h index 515a2388..e8bd82eb 100644 --- a/include/etl/debounce_value.h +++ b/include/etl/debounce_value.h @@ -60,8 +60,7 @@ namespace etl /// Constructor. //************************************************************************* debounce_value_base(value_type initial_value) - : value(initial_value) - , last_value(initial_value) + : last_value(initial_value) , count(0) , state(Unstable) , notification(nullptr) @@ -71,7 +70,7 @@ namespace etl //************************************************************************* /// Adds a new value. /// If the value has changed, the counter is reset and the value is marked as unstable. - /// Returns 'true' if the value is stable. + /// Returns 'true' if the value has changed. //************************************************************************* bool add(value_type value, count_type stable_count) { @@ -108,7 +107,7 @@ namespace etl last_value = value; - return is_stable(); + return has_changed(); } //************************************************************************* @@ -133,7 +132,7 @@ namespace etl //************************************************************************* value_type get() const { - return value; + return last_value; } //************************************************************************* @@ -163,7 +162,6 @@ namespace etl Changed = 2 }; - value_type value; value_type last_value; count_type count; notification_type* notification; @@ -171,51 +169,7 @@ namespace etl }; } // namespace private_debounce_value - template - class debounce_value; - - //************************************************************************* - /// A debounced for a value. - /// The debounced will only change its value if the new value has been stable for a given number of calls. - /// Compile-time stable count. - //************************************************************************* - template - class debounce_value> // (2) compile-time specialization - : public private_debounce_value::debounce_value_base - { - public: - - using value_type = typename private_debounce_value::debounce_value_base::value_type; - using count_type = typename private_debounce_value::debounce_value_base::count_type; - - //************************************************************************* - /// Constructor. - //************************************************************************* - explicit debounce_value(value_type initial_value) - : private_debounce_value::debounce_value_base(initial_value) - { - } - - //************************************************************************* - /// Adds a new value to the debounced. - /// If the value has changed, the counter is reset and the debounced is marked as unstable. - //************************************************************************* - bool add(value_type value) - { - return private_debounce_value::debounce_value_base::add(value, Stable_Count); - } - }; - - //************************************************************************* - /// A debounced for a value. - /// The debounced will only change its value if the new value has been stable for a given number of calls. - /// Runtime stable count. - //************************************************************************* - struct debounce_runtime_tag - { - }; - - template + template class debounce_value : public private_debounce_value::debounce_value_base { public: diff --git a/test/test_debounce_value.cpp b/test/test_debounce_value.cpp index d13a50b0..f3f87e03 100644 --- a/test/test_debounce_value.cpp +++ b/test/test_debounce_value.cpp @@ -30,6 +30,8 @@ SOFTWARE. #include "etl/debounce_value.h" +#include + namespace { uint8_t notification_value = 0; @@ -46,7 +48,8 @@ namespace SUITE(test_debounce) { - TEST(test_debounce_value_runtime) + //************************************************************************* + TEST(test_debounce_value) { const uint8_t Initial_Value = 1; const uint8_t Stable_Count = 4; @@ -81,12 +84,13 @@ namespace CHECK_TRUE(value.add(2)); CHECK_TRUE(value.is_stable()); CHECK_TRUE(value.has_changed()); + CHECK_EQUAL(2, value.get()); // Notified. CHECK_EQUAL(2, notification_value); // Still stable. - CHECK_TRUE(value.add(2)); + CHECK_FALSE(value.add(2)); CHECK_TRUE(value.is_stable()); CHECK_FALSE(value.has_changed()); @@ -112,14 +116,148 @@ namespace CHECK_TRUE(value.add(3)); CHECK_TRUE(value.is_stable()); CHECK_TRUE(value.has_changed()); + CHECK_EQUAL(3, value.get()); // Notified. CHECK_EQUAL(3, notification_value); // Stable. - CHECK_TRUE(value.add(3)); + CHECK_FALSE(value.add(3)); CHECK_TRUE(value.is_stable()); CHECK_FALSE(value.has_changed()); } + + //************************************************************************* + TEST(test_debounce_value_modify_stable_count) + { + const uint8_t Initial_Value = 1; + const uint8_t Stable_Count = 4; + + etl::debounce_value value(Initial_Value, Stable_Count); + + value.set_notification(notification); + + notification_value = 0; + + CHECK_FALSE(value.is_stable()); + CHECK_FALSE(value.has_changed()); + + //******************************* + // Transition from unstable to stable. + CHECK_FALSE(value.add(2)); + CHECK_FALSE(value.is_stable()); + CHECK_FALSE(value.has_changed()); + + CHECK_FALSE(value.add(2)); + CHECK_FALSE(value.is_stable()); + CHECK_FALSE(value.has_changed()); + + CHECK_FALSE(value.add(2)); + CHECK_FALSE(value.is_stable()); + CHECK_FALSE(value.has_changed()); + + // Not notified yet. + CHECK_EQUAL(0, notification_value); + + // Stable & changed. + CHECK_TRUE(value.add(2)); + CHECK_TRUE(value.is_stable()); + CHECK_TRUE(value.has_changed()); + CHECK_EQUAL(2, value.get()); + + // Notified. + CHECK_EQUAL(2, notification_value); + + // Still stable. + CHECK_FALSE(value.add(2)); + CHECK_TRUE(value.is_stable()); + CHECK_FALSE(value.has_changed()); + + //******************************* + // Change the stable count. + value.set_stable_count(2); + + //******************************* + // Transition from unstable to stable. + // Unstable. + CHECK_FALSE(value.add(3)); + CHECK_FALSE(value.is_stable()); + CHECK_FALSE(value.has_changed()); + + // Not notified yet. + CHECK_EQUAL(2, notification_value); + + // Stable & changed. + CHECK_TRUE(value.add(3)); + CHECK_TRUE(value.is_stable()); + CHECK_TRUE(value.has_changed()); + CHECK_EQUAL(3, value.get()); + + // Notified. + CHECK_EQUAL(3, notification_value); + + // Stable. + CHECK_FALSE(value.add(3)); + CHECK_TRUE(value.is_stable()); + CHECK_FALSE(value.has_changed()); + } + + //************************************************************************* + TEST(test_debounce_value_modify_notification) + { + const uint8_t Initial_Value = 1; + const uint8_t Stable_Count = 4; + + etl::debounce_value value(Initial_Value, Stable_Count); + + value.set_notification(notification); + + notification_value = 0; + + //******************************* + // Transition from unstable to stable. + CHECK_FALSE(value.add(2)); + CHECK_FALSE(value.add(2)); + CHECK_FALSE(value.add(2)); + CHECK_TRUE(value.add(2)); + + // Notified. + CHECK_EQUAL(2, notification_value); + + value.clear_notification(); + + //******************************* + // Transition from unstable to stable. + // Unstable. + CHECK_FALSE(value.add(3)); + CHECK_FALSE(value.add(3)); + CHECK_FALSE(value.add(3)); + CHECK_TRUE(value.add(3)); + + // Not notified, so the value remains the same. + CHECK_EQUAL(2, notification_value); + } + + //************************************************************************* + TEST(test_debounce_values_from_an_input) + { + std::vector input = { 1, 2, 3, 3, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6 }; + std::vector output; + std::vector expected = { 2, 3, 4, 6 }; + + const uint8_t Stable_Count = 3; + etl::debounce_value value(0, Stable_Count); + + for (uint8_t v : input) + { + if (value.add(v)) + { + output.push_back(value.get()); + } + } + + CHECK_EQUAL(expected.size(), output.size()); + CHECK_ARRAY_EQUAL(expected.data(), output.data(), expected.size()); + } } } // namespace diff --git a/test/vs2022/etl.vcxproj b/test/vs2022/etl.vcxproj index e0e4fc2d..6ebafcc4 100644 --- a/test/vs2022/etl.vcxproj +++ b/test/vs2022/etl.vcxproj @@ -10411,7 +10411,6 @@ - diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index 1ac2027d..d53a1889 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -1566,6 +1566,12 @@ UnitTest++\Header Files + + UnitTest++\Header Files + + + UnitTest++\Header Files + @@ -3839,6 +3845,9 @@ Tests\Containers + + Tests\Misc +