Debounce Helper Example

examples/Advanced/DebounceHelper/DebounceHelper.ino
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/**
 * SPDX-FileCopyrightText: 2026 Maximiliano Ramirez <maximiliano.ramirezbravo@gmail.com>
 *
 * SPDX-License-Identifier: MIT
 */

/**
 * ReactiveESP32 Example Overview:
 * - This example demonstrates the usage of the DebounceHelper to debounce high-frequency updates.
 * - The library has +30 built-in helpers, and users can define custom helpers for common patterns
 *   (see documentation for more details).
 * - A Signal<uint8_t> named 'number' is defined to hold a number that will be updated rapidly.
 * - Another Signal<uint8_t> named 'debounced_number' is defined to hold the debounced value of
 *   'number'.
 * - The debounce helper is used to link 'number' to 'debounced_number' with a 500ms debounce
 *   interval.
 * - An Effect is defined to print the value of 'debounced_number' whenever it changes.
 *
 * - The Serial interface is used to interact with the program:
 *   - 'g': Get the current value of both signals.
 *   - 's': Set the signal to random values rapidly (100 updates with 10ms delay).
 *
 * - Pressing '0' restarts the ESP32.
 */

#include <ReactiveESP32.h>
using namespace RxESP32;

/* ---------------------------------------------------------------------------------------------- */
// Define a simple signal to hold a number. We will update this signal with high frequency updates.
// For this example, skip_filter_check is enabled to ensure all updates are propagated.
Signal<uint8_t> number(0, {.skip_filter_check = true});

// Define another signal to hold the value of 'number'. A debouncer will be applied to this signal
// to limit update frequency.
// For this example, skip_filter_check is enabled to ensure all updates are propagated.
Signal<uint8_t> debounced_number(0, {.skip_filter_check = true});

// Use the debounce() helper to link 'number' to 'debounced_number' with a 500ms debounce interval.
// It will only update 'debounced_number' if 'number' has been stable for 500ms.
// It will run for the first time after setting the 'number' for the first time.
auto debouncer = Helpers::Temporal::debounce(number, debounced_number, 500);

// Define an effect that prints the debounced number whenever it changes.
Effect<> print_effect([]() {
  uint8_t value = debounced_number.get();
  Serial.printf("\tDebounced Number: %u\n", value);
  return nullptr; // No cleanup needed
});

// Read Serial input and process commands
void serialRead();
/* ---------------------------------------------------------------------------------------------- */

void setup() {
  Serial.begin(115200);
  delay(1000);

  Serial.println("======================================");
  Serial.println("ReactiveESP32 - DebounceHelper Example");
  Serial.println("======================================");

  // Start the ReactiveESP32 dispatcher
  if (!Dispatcher::start()) {
    Serial.println("Failed to start ReactiveESP32 Dispatcher!");
    while (true) {
      delay(1000);
    }
  }
}

void loop() { serialRead(); }

void serialRead() {
  if (!Serial.available()) return;

  char c = Serial.read();

  if (c == '\r') return;
  if (c == '\n') c = ' ';
  Serial.printf("> %c\n", c);

  switch (c) {
    case '0':
    {
      // Restart the ESP32
      ESP.restart();
    } break;

    case 'g':
    {
      // Get the current value of both signals
      uint8_t value_number    = number.get();
      uint8_t value_debounced = debounced_number.get();
      Serial.printf("Number - Debounced: %u - %u\n", value_number, value_debounced);
    } break;

    case 's':
    {
      // Update the signal to a random value between 0 and 255
      // 100 times with a 10ms delay between updates
      Serial.printf("Updating 'number' signal 100 times rapidly...\n");

      uint8_t update_count = 0;

      for (int i = 0; i < 100; ++i) {
        uint8_t new_value = random(0, 256);

        if (number.set(new_value) == Status::Ok) {
          update_count++;
        }

        delay(10);
      }

      if (update_count == 100) {
        Serial.printf("All updates applied successfully! Last value applied: %u\n", number.get());
      } else {
        Serial.printf("Something went wrong! Only %u updates applied\n", update_count);
      }

    } break;
  }
}

See Also

  • Core - Core API Reference

  • Filters - Filters API Reference

  • Helpers - Helpers API Reference