Skip to content

adc.multiplier get/set not accessible via BLE/USB Companion protocol (only works on Repeater/Room Server text CLI) #2909

Description

@qlikwer

Problem

CommonCLI.cpp already supports get/set adc.multiplier as a generic text
command (see handleCommand(), ~line 749-761 and ~895-901), and several board
classes (e.g. PromicroBoard, HeltecV4Board) already implement
setAdcMultiplier() / getAdcMultiplier() overrides.

However, this only actually works over the raw-text serial CLI used by
Repeater / Room Server firmware, where meshcore-cli sends the literal
string "set adc.multiplier <value>" down the wire and the firmware parses
it directly.

Companion firmware (BLE / USB, used by the mobile app and by meshcore-cli
in companion mode) uses a structured binary protocol with a fixed opcode per
setting instead of a free-text CLI passthrough. For example:

  • GET_TUNING_PARAMS (0x2b) returns a fixed 9-byte struct containing only
    rx_delay (4 bytes) and airtime_factor (4 bytes) — no room for an ADC
    multiplier.
  • There is no generic "send raw CLI string over BLE" opcode that would let a
    companion client reach the existing CommonCLI.cpp text handler.

As a result, meshcli get/set adc.multiplier against a Companion device
falls through to the case _: default in meshcore_cli.py, which treats it
as a user-defined "custom var" (GET_CUSTOM_VARS / SET_CUSTOM_VAR,
0x28/0x29) — a completely different mechanism intended for
set_custom_var(key, value). This produces Unknown var adc.multiplier
even though the firmware itself fully supports the setting.

Impact

DIY / community boards with hand-soldered voltage dividers (e.g. fakeTec /
ProMicro, and presumably others without a factory-calibrated divider) have
no way to runtime-calibrate battery voltage reading while running
Companion firmware
. The only workaround today is a full firmware rebuild
with a hardcoded #define ADC_MULTIPLIER, reflash via DFU, and repeat for
every recalibration.

Suggested fix (open to alternatives)

Extend the existing tuning-params opcode pair (GET_TUNING_PARAMS /
SET_TUNING_PARAMS, 0x2b / 0x15) to include a 4-byte float adc_multiplier
field alongside rx_delay and airtime_factor, wire it through to
board->getAdcMultiplier() / setAdcMultiplier() in the companion firmware
command handler, and bump RESP_CODE_TUNING_PARAMS payload size accordingly
(with a length/version check for backward compatibility with older
companion apps).

Alternatively, a new dedicated opcode pair could be added instead of
extending an existing struct, if that's preferred for protocol
compatibility reasons.

Companion library/CLI side changes would follow once the firmware protocol
is agreed (tracked separately in meshcore_py / meshcore-cli).

Reproduction

  1. Flash any Companion firmware to a board with setAdcMultiplier()
    implemented (e.g. ProMicro_companion_radio_ble).
  2. Connect via meshcore-cli over BLE.
  3. Run get adc.multiplierUnknown var adc.multiplier.
  4. Compare with a Repeater build of the same board: get adc.multiplier
    works correctly there.

Happy to help test on ProMicro/fakeTec hardware, and to help implement once
the approach is agreed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions