Skip to content

Rework of begin methods #1620

@jgromes

Description

@jgromes

Currently, all the begin* methods for all modules have a rather extensive list of arguments, which set basic radio properties like carrier frequency, LoRa spreading factor, FSK bit rate etc. This is unwieldy, leads to the default values being copy-pasted everywhere, is not futureproof as changing the order of arguments can cause silent failures, and overall just not being used as a lot of users will instead opt into calling the default no-argument version and then modifying whatever actually interests them.

I have written down the options discussed so far with examples of the API calls. Fruther proposals can be added.

  1. Named arguments - proposed by @cleishm in [SX1262] Use named arguments for SX1262::begin* methods #1607. This approach uses a flat config structure as the only argument of the begin methods. Values for this structure can be provided by designated initialization directly in the begin method call, so from the perspective of most users, the only thing that changes is that now they can specify just a single argument in a very clean way.

    int state = radio.begin({.spreadingFactor = 9});
  2. Config structs with inheritance - proposed by @jgromes. This approach is similar to the one above, except that the configuration structure is no longer flat and inherits from a base struct which contains all the common configuration. This limits the copy-paste, connects the configuration to existing config structures like DataRate_t and would allow us to get rid of the different variants of begin, like beginFSK or beginLRFHSS. It also allows more advanced users to easily switch between different modems and configurations. The downside is that the user API is more complicated.

    SX126xConfig_t cfg(RADIOLIB_MODEM_LORA);
    cfg.dataRate.lora.spreadingFactor = 9;
    int state = radio.begin(&cfg);
  3. Removing unnecessary configuration from begin - most of the configuration arguments in begin calls are not actually needed to start the module. There are exceptions (for example TCXO on SX126x), but the list of arguments in begin can be actually removed most of the time. This would necessitate the user to configure the arguments themselves, which some already do anyway. The advantage here that this is the simplest solution, the clear disadvantage is that it pushes all the configuration onto the user, leaving the radio in a weird semi-configured state between the end of begin and completed initialization. It will also discourage users from checking all of the error codes, as every call to config method will need to be checked, which is currently done by the library.

    int state = radio.begin();
    RADIOLIB_ASSERT(state);
    state = radio.setFrequency(434);
    RADIOLIB_ASSERT(state);
    state = radio.setSpreadingFactor(9);
  4. Configure modem and use named arguments - proposed by @StevenCellist. This proposal uses the existing setModem() (possibly renamed) followed by approach 1 above with named arguments. The user must first (re)set the module to a specific modem (LoRa, FSK, ..) which does the usual findChip() stuff to make sure that the radio is connected properly. After that, the user calls begin() with named arguments with possible default values as in the proposal by @cleishm. This argument list is selectively interpreted based on the configured modem.
    As a side-effect, this also tackles the 'wake-up from deepsleeping ESP32'-problem as then the user can skip the call to setModem().

    int state = radio.setModem(RADIOLIB_MODEM_LORA);
    RADIOLIB_ASSERT(state);
    state = radio.begin({.spreadingFactor = 9});

As this is a major breaking change, it will be rolled out gradually over the next library releases. The original list of arguments will be removed in 8.0.0, breaking backwards compatibility there.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions