Add ADC resistor-ladder binary inputs (analog buttons)#35
Conversation
|
Added another commit to do more validation / give feedback on invalid configs, based on testing I was doing with the py-opendisplay side of this. |
|
Thank you for your work. BinaryInputs input_type == 2 is reserved for switches already, please use BinaryInputs input_type == 3. Also, please try to use the existing struct(we can use alternative names for each element) so we dont need to change py-opendisplay. |
BinaryInputs input_type == 2: several buttons share one ADC pin, distinguished by voltage. Polled (no edge interrupt) and reported through the same MSD button byte as digital buttons, so hosts decode one uniform contract. Wire layout (num_buttons, id_base, N+1 LE uint16 descending thresholds in reserved[]) is documented in structs.h. device_control.cpp adds classify/register/poll with sample debounce, per-pin ADC attenuation, a static_assert guarding reserved[] capacity, and rejection of non-descending thresholds from any host. ESP32 only; NRF gets an empty poll stub. Verified on an ESP32-C3 (XTEINK X4): valid ladders register and report presses; a malformed (non-descending) config is skipped at init with a diagnostic while a valid ladder beside it still works. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
registerAdcLadder stored id_base raw and the poll path masked the
reported id with & 0x07. A host sending id_base + count > 8 (3-bit id
field) produced wrapped, colliding button ids that HA cannot
disambiguate — silently, with no feedback. The firmware is the
validation boundary for any host, not just py-opendisplay, so reject it.
Also give the existing count and byte_index guards the same diagnostic
the descending-threshold check already emits; previously they dropped a
malformed config silently.
Hardware-verified on XTEINK X4: a GPIO2 ladder with id_base=6, N=4 is
now rejected ("exceeds 3-bit id space ... skipping") while a valid GPIO1
ladder registers.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per maintainer review on OpenDisplay#35: BinaryInputs input_type == 2 is reserved for the host-side switch feature. Renumber the ADC resistor-ladder type to 3 and document 2 = switch in the struct contract. Wire layout and the reused reserved[] fields are unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
57002ec to
50da667
Compare
|
I rebased to pull in the other changes in main, but I still didn't see where 2 was reserved, sorry. :-/ I added a comment and used 3, no problem, just more wondering what I'm missing. I updated the matching py-opendisplay PR as well, which I think is still necessary? OpenDisplay/py-opendisplay#78 The one PR I haven't opened yet is the one to the HA integration, where I was planning on exposing these buttons as entities. I'm not as familiar with HACS and whatnot, and didn't want to submit anything I haven't tested myself in the real world. |
I was thinking about what I could do with the button on my XTEINK X4 when I realized that they are analog and not supported just via a config change. So I added support for analog buttons, fully tested on my X4 (I'll have a py-opendisplay PR open to match shortly). I tried to make it a generic feature, not just for the X4, but am very happy to tweak things / restructure / whatever if this approach isn't copacetic.
Robot commit message:
BinaryInputs input_type == 2: several buttons share one ADC pin, distinguished by voltage. Polled (no edge interrupt) and reported through the same MSD button byte as digital buttons, so hosts decode one uniform contract. Wire layout (num_buttons, id_base, N+1 LE uint16 descending thresholds in reserved[]) is documented in structs.h.
device_control.cpp adds classify/register/poll with sample debounce, per-pin ADC attenuation, a static_assert guarding reserved[] capacity, and rejection of non-descending thresholds from any host. ESP32 only; NRF gets an empty poll stub.
Verified on an ESP32-C3 (XTEINK X4): valid ladders register and report presses; a malformed (non-descending) config is skipped at init with a diagnostic while a valid ladder beside it still works.