ButtonService
Source:
ButtonService.h
Row¶
src/core/services/ButtonService.h:168One 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¶
src/core/services/ButtonService.h:40Inherits:
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.

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.