Multiple Filters Example

examples/Advanced/MultipleFilters/MultipleFilters.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
125
126
/**
 * SPDX-FileCopyrightText: 2026 Maximiliano Ramirez <maximiliano.ramirezbravo@gmail.com>
 *
 * SPDX-License-Identifier: MIT
 */

/**
 * ReactiveESP32 Example Overview:
 * - This example demonstrates the use of signals with a combination of filters.
 * - The library has +50 built-in filters, and users can define custom filters as well (see
 *   documentation for more details).
 * - A Signal<uint8_t> named 'number' is defined, with a WithinRange filter that only allows values
 *   between 10 and 20 (inclusive), and an IsOdd filter that only allows odd numbers.
 * - A Computed<uint8_t> named 'odd_doubled' is defined, which computes double the value of
 *   'number'. It has skip_filter_check enabled to ensure it recalculates even if 'number' is set to
 *   the same value.
 *
 * - The Serial interface is used to interact with the program:
 *   - 'g': Get the current value of the signal and computed.
 *   - 'y': Set the signal to a new value that would probably pass the filter (between 10 and 20).
 *   - 'n': Set the signal to a new value that would fail the filter (outside 10 to 20).
 *
 * - Pressing '0' restarts the ESP32.
 */

#include <ReactiveESP32.h>
using namespace RxESP32;

/* ---------------------------------------------------------------------------------------------- */
// Define a signal with the WithinRange and IsOdd filters
// This is possible by using Logical Filters. In this case we use 'And' to combine both filters.
// This will only allow values between 10 and 20 (inclusive), and only odd numbers
Signal<uint8_t, 1,
  Filters::Logical::And<Filters::Numerical::WithinRange<uint8_t, 10, 20>,
    Filters::Numerical::IsOdd<uint8_t>>>
  number(0);

// Define a computed that doubles the signal value, with skip_filter_check enabled to recompute even
// if 'number' was set to the same value
Computed<uint8_t, 1> odd_doubled(
  []() {
    uint8_t val         = number.get();
    uint8_t doubled_val = val * 2;
    Serial.printf("\tComputed odd_doubled recalculated: %u\n", doubled_val);
    return doubled_val;
  },
  {.skip_filter_check = true});

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

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

  Serial.println("=======================================");
  Serial.println("ReactiveESP32 - MultipleFilters 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 signal and computed
      uint8_t value_number   = number.get();
      uint16_t value_doubled = odd_doubled.get();
      Serial.printf("Number - Doubled: %u - %u\n", value_number, value_doubled);
    } break;

    case 'y':
    {
      // Set the signal to a random value within the filter range
      uint8_t new_value = random(10, 21); // 10 to 20 inclusive
      Serial.printf("Setting number to %u (within range)\n", new_value);

      Status status = number.set(new_value);

      switch (status) {
        case Status::Ok: Serial.println("Signal updated successfully"); break;
        case Status::Unchanged: Serial.println("Signal value unchanged (filtered out)"); break;
        default: Serial.printf("Error updating signal: %d\n", static_cast<int>(status)); break;
      }
    } break;

    case 'n':
    {
      // Set the signal to a random value outside the filter range
      uint8_t new_value = random(0, 10); // 0 to 9
      Serial.printf("Setting number to %u (outside range)\n", new_value);

      Status status = number.set(new_value);

      switch (status) {
        case Status::Ok: Serial.println("Signal updated successfully"); break;
        case Status::Unchanged: Serial.println("Signal value unchanged (filtered out)"); break;
        default: Serial.printf("Error updating signal: %d\n", static_cast<int>(status)); break;
      }
    } break;
  }
}

See Also

  • Core - Core API Reference

  • Filters - Filters API Reference

  • Helpers - Helpers API Reference