Ga naar inhoud

De LR2021

ZIJDETECTOREN · IRQ-TIJDSLIMIET · RX-BOOST · TWEE BORDEN

De LR2021 is de zevende radiochip in de firmware en de eerste die het gedeelde patroon uit De LoRa-transceiver op een paar punten doorbreekt. Hij kan op meer dan één spreidingsfactor tegelijk luisteren, hij heeft een eigen afhandeling van blijven hangende interruptvlaggen, en zijn aanwezigheid is buiten src/helpers/radiolib/ merkbaar. Dit hoofdstuk beschrijft wat er anders is.

Opmerking

Bron. Deze pagina is geverifieerd tegen de firmware zelf: MeshCore v1.17.1, commit d929643, 14 augustus 2026 — bestanden src/helpers/radiolib/CustomLR2021.h, src/helpers/radiolib/CustomLR2021Wrapper.h, src/helpers/radiolib/RadioLibWrappers.cpp, src/helpers/CommonCLI.cpp en de buildvlaggen in variants/meshtracker_x1/ en variants/meshnology_w12/.

Twee borden

De chip zit in twee varianten, beide nieuw in v1.17.1:

Bord Variantmap Zendvermogen TCXO
SenseCAP MeshTracker X1 variants/meshtracker_x1/ LORA_TX_POWER=22 1.6f
Meshnology W12 variants/meshnology_w12/ LORA_TX_POWER=4 0.0f

Het verschil in zendvermogen is geen vergissing. De W12 zet daarnaast MAX_LORA_TX_POWER=4, met als toelichting in de platformio.ini dat de GC1109-versterker bij zo'n vier dBm ingangsvermogen al in verzadiging loopt. Het vermogen dat je op dat bord instelt is dus het vermogen vóór de versterker, niet wat de antenne uit gaat. De W12 heeft ook geen TCXO, vandaar LR2021_TCXO_VOLTAGE=0.0f.

De radiovlaggen volgen verder het bekende patroon:

variants/meshtracker_x1/platformio.ini

  -D RADIO_CLASS=CustomLR2021
  -D USE_LR2021
  -D WRAPPER_CLASS=CustomLR2021Wrapper

Eén vlag is nieuw. LR2021_IRQ_DIO benoemt welke DIO-pen van de chip de interrupt voert; op beide borden is dat DIO8. De constructor zet die waarde in irqDioNum, een veld van RadioLibs LR2021 (src/helpers/radiolib/CustomLR2021.h r.14). De andere chips hebben die keuze niet: bij de SX126x-familie ligt DIO1 vast.

Zijdetectoren: luisteren op meer dan één SF

Dit is waarvoor de chip in de firmware is opgenomen. Een LoRa-ontvanger luistert normaal op één spreidingsfactor; wat op een andere SF voorbijkomt, hoort hij niet. De LR2021 kan naast de hoofd-SF nog tot drie zijdetectoren aanzetten, elk op een eigen SF.

De wrapper stelt ze in via setSideDetector() en bewaart de instelling, zodat hij hem na elke parameterwissel opnieuw kan toepassen:

src/helpers/radiolib/CustomLR2021Wrapper.h r.65-69

  int16_t applySideDetectorConfig() {
    int16_t status = ((CustomLR2021 *)_radio)->setSideDetector(_sideDet, _numSideDet);
    RadioLibWrapper::idle(); // trigger startReceive()
    return status;
  }

Er gelden vier eisen, alle vier in configSideDetectors():

Eis Wat er gebeurt als je hem overtreedt
Een SF ligt tussen 5 en 12 de hele instelling wordt geweigerd
Een zij-SF is groter dan de hoofd-SF idem
Het verschil met de hoofd-SF is hoogstens 4 idem
Bij hoofd-SF 10 of hoger: hoogstens één zijdetector idem

De derde en de vierde eis samen betekenen dat de winst het grootst is op een lage hoofd-SF. Draait een node op SF7, dan mag hij er SF8 tot en met SF11 bij nemen. Draait hij op SF10, dan blijft er één zijdetector over.

Opmerking

De lijst wordt als geheel aangenomen of als geheel geweigerd. Er is geen deelresultaat: configSideDetectors() controleert eerst alle opgegeven SF's en roept setSideDetector() pas daarna aan. Slaagt die aanroep niet, dan blijft de vorige instelling staan.

set extra.sf: de instelling van buitenaf

De zijdetectoren zijn het enige radiokenmerk in de firmware dat via de CLI te bedienen is en alleen op één chipfamilie bestaat. Het commando staat achter #if defined(USE_LR2021) en is op elk ander bord onbekend:

src/helpers/CommonCLI.cpp r.779-785

  #if defined(USE_LR2021)
  } else if (memcmp(config, "extra.sf ", 9) == 0) {
    strcpy(tmp, &config[9]);
    const char *parts[4];
    uint8_t sideDetSFs[4];
    int num = mesh::Utils::parseTextParts(tmp, parts, 4);
    if (num > 3) {

Gebruik: set extra.sf 8 9 10, met hoogstens drie getallen. Het antwoord is OK - extra SFs set of Invalid extra SF config. De gekozen SF's worden in extra_sf[4] in de instellingen bewaard en overleven een herstart (src/helpers/CommonCLI.h r.72).

De weg van commando naar chip loopt via het contract: CommonCLI roept configSideDetectors() aan op CommonCLICallbacks, de applicatie geeft dat door aan de radiowrapper. RadioLibWrapper heeft een standaardantwoord dat false teruggeeft, zodat een bord zonder LR2021 niets hoeft te doen (src/helpers/radiolib/RadioLibWrappers.h r.81). Zie Het klassenmodel.

Opmerking

Alleen de repeater geeft het commando door. examples/simple_repeater/ implementeert configSideDetectors(); de companion- en room server-applicaties doen dat niet en vallen op het standaardantwoord terug. Op een MeshTracker X1 met companionfirmware bestaat set extra.sf dus wel, maar het antwoordt altijd Invalid extra SF config.

Blijven hangende interruptvlaggen

De LR2021 meldt een preambule en een geldige header als losse interruptvlaggen. Die vlaggen blijven staan tot iets ze wist, en als het pakket waar ze bij hoorden nooit binnenkomt, blijft de chip voor de firmware "aan het ontvangen". Dat is geen theoretisch geval: isReceivingPacket() bepaalt of er ruisvloermonsters worden genomen en of het kanaal als bezet geldt.

CustomLR2021::isReceiving() lost dat op met een tijdslimiet per vlag. Een preambule mag _preambleMillis blijven staan, een header _maxPayloadMillis; daarna worden de vlaggen gewist en de toestand teruggezet. De twee grenzen worden bij elke parameterwissel opnieuw berekend uit SF, bandbreedte en coderatio, door calcMaxPacketMillis(). De standaardwaarden zijn 66 en 3934 milliseconden (src/helpers/radiolib/CustomLR2021.h r.7-8).

Een header-CRC-fout wist alle drie de vlaggen ineens en zet de toestand terug. Datzelfde gebeurt als de headervlag verdwijnt terwijl de firmware hem wél had gezien — dat betekent dat iets anders hem heeft gewist.

Er is nog een tweede omweg. RadioLibWrapper::startRecv() zet de chip eerst in stand-by, maar alleen voor deze chip:

src/helpers/radiolib/RadioLibWrappers.cpp r.109-112

void RadioLibWrapper::startRecv() {
  #if defined(USE_LR2021)
  _radio->standby(); // without this LR2021 can throw -706 when calling startReceive after hardware CAD when side detectors are enabled
  #endif

De toelichting in de broncode benoemt de aanleiding: zonder die stand-by kan startReceive() na een hardwarematige kanaalmeting fout −706 geven zodra er zijdetectoren aanstaan.

RX-boost en de overige afwijkingen

setRxBoostedGainMode() bestaat op de SX126x-familie ook, maar de LR2021 eist stand-by voordat hij de instelling aanneemt, en het niveau is een getal in plaats van aan of uit. LR2021_RX_BOOST_LEVEL staat standaard op 7 en wordt bij uitzetten op 0 gezet (src/helpers/radiolib/CustomLR2021Wrapper.h r.10-12).

Drie kleinere verschillen met CustomSX1262:

  • setCRC(2) in plaats van setCRC(1), en daarnaast explicitHeader().
  • startReceive() is overschreven om de preambulevlag in de gemelde interruptvlaggen mee te nemen; zonder die overschrijving zou isReceiving() de preambule nooit zien.
  • onSendFinished() zet de preambulelengte opnieuw, met in de broncode de toelichting dat dit vreemde verschijnselen bij afwisselend kleine en grote pakketten wegneemt.

De TCXO-terugval werkt hetzelfde als bij de SX1262: faalt begin() met −707 of −706, dan volgt een tweede poging met de TCXO-spanning op nul. Het verschil is dat de LR2021-versie geen foutregel op de console zet waar de SX1262-versie dat sinds v1.17.1 wel doet.

Narekenen

De twee borden met een LR2021 zijn te vinden met:

grep -rl "RADIO_CLASS=CustomLR2021" variants/

De klassen en hun plek staan in Het klassenmodel; tools/class-groups.py toont ze met:

python3 tools/class-groups.py /pad/naar/MeshCore --groep 3 | grep LR2021
python3 tools/class-groups.py /pad/naar/MeshCore --groep 2 | grep LR2021

CustomLR2021 staat in groep 3 en CustomLR2021Wrapper in groep 2 — hetzelfde paar als bij elke andere chip, en om dezelfde reden: de eerste past de chipdriver aan, de tweede giet het resultaat in het radiocontract.

Bronnen

Firmware, commit d929643 (v1.17.1, 14 augustus 2026):

Verwante hoofdstukken: