Conditional Nodes Example

examples/Intermediate/ConditionalNodes/ConditionalNodes.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
127
128
129
130
131
132
133
134
135
136
137
/**
 * SPDX-FileCopyrightText: 2026 Maximiliano Ramirez <maximiliano.ramirezbravo@gmail.com>
 *
 * SPDX-License-Identifier: MIT
 */

/**
 * ReactiveESP32 Example Overview:
 * - This example demonstrates conditional nodes using multiple sources.
 * - A Signal<bool> named 'use_fahrenheit' determines whether to display temperature in Celsius or
 *   Fahrenheit.
 * - Two Signal<uint16_t> represent temperature sensors in Celsius and Fahrenheit.
 * - A Computed<float> named 'displayed_temperature' selects which sensor to read based on
 *   'use_fahrenheit'.
 * - Changing 'use_fahrenheit' dynamically updates dependencies, demonstrating conditional tracking.
 *
 * - The Serial interface is used to read commands:
 *   - 'g': Get current values.
 *   - 't': Toggle between Celsius and Fahrenheit display.
 *   - 'c': Update Celsius temperature sensor.
 *   - 'f': Update Fahrenheit temperature sensor.
 *
 * - Pressing '0' restarts the ESP32.
 */

#include <ReactiveESP32.h>
using namespace RxESP32;

/* ---------------------------------------------------------------------------------------------- */
// Define a signal which will be used as the condition
Signal<bool> use_fahrenheit(false);

// Example signal representing a temperature sensor in celsius, range 0-100°C (0-1023 ADC)
Signal<uint16_t> temp_sensor_celsius(255);

// Example signal representing a temperature sensor in fahrenheit, range 32-212°F (0-1023 ADC)
Signal<uint16_t> temp_sensor_fahrenheit(511);

// Define a computed value that selects between celsius and fahrenheit based on the condition signal
Computed<float> displayed_temperature([]() {
  // Dynamically track dependencies based on the condition
  if (use_fahrenheit.get()) {
    float fahrenheit = temp_sensor_fahrenheit.get() * (180.0f / 1023.0f) + 32.0f;
    Serial.printf("\tDisplaying temperature in Fahrenheit: %.2f°F\n", fahrenheit);
    return fahrenheit;
  } else {
    float celsius = temp_sensor_celsius.get() * (100.0f / 1023.0f);
    Serial.printf("\tDisplaying temperature in Celsius: %.2f°C\n", celsius);
    return celsius;
  }
});

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

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

  Serial.println("========================================");
  Serial.println("ReactiveESP32 - ConditionalNodes 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 't':
    {
      // Toggle between celsius and fahrenheit display
      bool using_fahrenheit = use_fahrenheit.get();
      use_fahrenheit.set(!using_fahrenheit);
      Serial.printf("Display mode toggled to %s\n", using_fahrenheit ? "Celsius" : "Fahrenheit");
    } break;

    case 'c':
    {
      // Randomly update celsius temperature sensor
      uint16_t new_celsius = random(0, 1024);

      if (!temp_sensor_celsius.set(new_celsius)) {
        Serial.printf("Celsius sensor unchanged: %u\n", new_celsius);
      } else {
        Serial.printf("Celsius sensor updated to raw value: %u\n", new_celsius);
      }
    } break;

    case 'f':
    {
      // Randomly update fahrenheit temperature sensor
      uint16_t new_fahrenheit = random(0, 1024);

      if (!temp_sensor_fahrenheit.set(new_fahrenheit)) {
        Serial.printf("Fahrenheit sensor unchanged: %u\n", new_fahrenheit);
      } else {
        Serial.printf("Fahrenheit sensor updated to raw value: %u\n", new_fahrenheit);
      }
    } break;

    case 'g':
    {
      // Get the current value of sensors and displayed temperature
      uint16_t value_celsius    = temp_sensor_celsius.get();
      uint16_t value_fahrenheit = temp_sensor_fahrenheit.get();
      float value_displayed     = displayed_temperature.get();
      Serial.printf("Celsius raw: %u - Fahrenheit raw: %u - Displayed Temperature: %.2f°%c\n",
        value_celsius,
        value_fahrenheit,
        value_displayed,
        use_fahrenheit.get() ? 'F' : 'C');
    } break;
  }
}

See Also

  • Core - Core API Reference

  • Filters - Filters API Reference

  • Helpers - Helpers API Reference