OXRecorder::OXSwitchManager

GPIO switch monitoring — debounced state + long-press detection

Overview

OXSwitchManager watches one or more switches on GPIO pins and reports two things: debounced press/release transitions (for on/off behavior) and long-press events (a button held for a configurable duration, e.g. 5 or 10 seconds). Callbacks receive the GPIO pin, so one handler can serve several switches.

Declared in include/OXSwitchManager.h; portable core in src/OXSwitchManager.cpp; the GPIO backend in src/gpio/EspGpioInput.cpp. This is the detection engine behind OXConfigManager's reset feature.

SwitchConfig

Describes one monitored switch. The addSwitch(pin, longPressMs) convenience overload fills these with active-low + pull-up defaults (a button to GND).

FieldTypeDefaultMeaning
pinint0GPIO to monitor.
activeHighbooltrueLevel that means "pressed". true = switch to 3V3; false = switch to GND.
usePullupboolfalseEnable the MCU internal pull-up (typical for an active-low switch to GND).
longPressMsuint32_t5000Hold time that counts as a long press.
debounceMsuint32_t30Contact debounce window; the level must be stable this long to register.

API reference

bool begin()

Brings up the manager (obtains the default GPIO input on-device). Returns false if no input device is available. Call before addSwitch().

bool addSwitch(const SwitchConfig &cfg)

bool addSwitch(int pin, uint32_t longPressMs)

Starts monitoring a switch. The convenience overload assumes a momentary button to GND (active-low, pull-up). Returns false if the table is full (max 8) or no input device is set. Re-adding the same pin replaces its config.

ParameterTypeMeaning
pinintGPIO to monitor.
longPressMsuint32_tHold time for the long-press event, e.g. 5000 or 10000.

void onLongPress(SwitchLongPressCallback cb, void *ctx = nullptr)

Registers the long-press handler void(int pin, void *ctx), fired once when any tracked switch reaches its longPressMs. This is the switchLongPressDetected(pin) hook.

void onStateChange(SwitchStateCallback cb, void *ctx = nullptr)

Registers the state handler void(int pin, bool pressed, void *ctx), fired on every debounced press/release transition — use it for on/off switches.

size_t poll(uint32_t nowMs)

Samples all switches, runs debounce, and fires callbacks. Call regularly from loop() with millis(). Returns the number of switches whose debounced state changed this call.

bool isPressed(int pin) const

Current debounced state of a tracked pin (false if untracked).

uint32_t heldMs(int pin, uint32_t nowMs) const

How long the pin has been continuously pressed, in ms (0 if released/untracked) — handy for a long-press progress indicator.

Examples

Try it

Flash with pio run -e esp32-s3-super-mini -t upload && pio device monitor. The debounce + long-press logic is covered on the host by pio test -e native (via a fake GPIO input) — no hardware needed for logic changes.

1. Long-press action

#include <Arduino.h>
#include "OXSwitchManager.h"
#include "OXLog.h"

using namespace OXRecorder;

OXSwitchManager switches;

void onLongPress(int pin, void *ctx) {
  OXLog::info("long press on GPIO%d", pin);
}

void setup() {
  OXLog::begin(115200);
  switches.begin();
  switches.addSwitch(5, 5000);    // GPIO5, 5 s — button to GND
  switches.onLongPress(onLongPress);
}

void loop() {
  switches.poll(millis());
  delay(10);
}

2. On/off switch

void onState(int pin, bool pressed, void *ctx) {
  OXLog::info("GPIO%d is now %s", pin, pressed ? "ON" : "OFF");
}
// ... in setup(): switches.onStateChange(onState);

3. Custom polarity (button to 3V3)

SwitchConfig cfg;
cfg.pin = 7;
cfg.activeHigh = true;     // pressed = HIGH
cfg.usePullup = false;    // external pull-down on the board
cfg.longPressMs = 10000;  // 10 s
switches.addSwitch(cfg);

Notes