Skip to content

ButtonService

Source: ButtonService.h

Row

struct Row
src/core/services/ButtonService.h:168

One button: its wiring, its target, and the debounce state it carries between polls.

Public Attributes

uint32_t id = 0

int8_t pin = -1

bool activeLow = true : a switch to ground with a pull-up: the usual wiring

InputAction action {}

bool open = false : the pin was accepted by the seam, so it is worth polling

bool pressed = false : the settled state

bool candidate = false : the level being timed

uint16_t sinceChange = 0 : ms the candidate has held

ButtonService

class ButtonService
src/core/services/ButtonService.h:40

Inherits: MoonModule, ListSource

A list of push buttons, each on its own GPIO, each driving a control.

The physical twin of a UI click, and the same shape as the infrared service. A list because boards have more than one, and a single pin did not survive the second board.

ButtonService card

Public Methods

virtual inline ModuleRole role() const override : A service, so the container accepts it as a child.

virtual inline void defineControls() override : Declare the shared debounce and the list of button rows.

virtual inline void setup() override : Open every pin the restored rows name.

virtual inline void tick20ms() override : Poll every configured button, which 50 Hz catches comfortably.

virtual inline bool isEditableList() const override : Editable, since the rows are the whole point of this module.

virtual inline uint8_t listRowCount() const override : How many rows are configured.

virtual inline void writeListRow(JsonSink & sink, uint8_t row) const override : Append one row's summary, ending with the live state so a button can be seen working.

virtual inline void writeListRowDetail(JsonSink & sink, uint8_t row) const override : The row's editable fields, so a button is retargeted on the card rather than through the API.

virtual inline void writeListOptionSets(JsonSink & sink) const override : The target-type options, shared across every row rather than repeated in each.

virtual inline bool addListRow(uint32_t & outId) override : Append a row with default values.

virtual inline bool deleteListRow(uint32_t id) override : Remove one row by id.

virtual inline bool setListRowField(uint32_t id, const char * field, const char * valueJson) override : Set one field of one row, the shared action fields first and this module's own after.

virtual inline bool restoreList(const char * json, const char * key) override : Rebuild the rows from the persisted list, then open every pin they name.

More info

How a press acts

Through the one control-set primitive every transport uses. So a press and a message are indistinguishable to whatever they drive. A row names its target as a module and a control. Pointing one at the surface puts the button where every transport reaches it. Pointing it at a driver drives that control directly, by the same mechanism.

Momentary against latching

A wall switch and a stage pedal want opposite things. A toggle row flips its target on each press and ignores the release. A set row writes while held and clears on release, which is what a pedal needs. So a foot pedal needs no module of its own, being electrically a momentary switch.

Debounced here, not in the platform

A bouncing contact is a property of the switch, so this module owns the time constant. Polled at 50 Hz, since a press lasts tens of milliseconds.