De LoRa-transceiver¶
ZES WRAPPERS · STD_INIT · TCXO-TERUGVAL · REGISTERPATCH · RUISVLOER
De radio is het enige onderdeel dat een node tot node maakt. In de firmware
is dat geen chip maar een klasse: RADIO_CLASS, per bord ingevuld met één
van zes wrappers rond RadioLib. Dit hoofdstuk beschrijft wat die wrapper
extra doet bovenop RadioLib — de initialisatie met terugval, de optionele
vlaggen per bord, de registerpatch voor drie borden, en het feit dat de
radio zijn eigen ruisvloer meet.
[!NOTE] Bron. Deze pagina is geverifieerd tegen de firmware zelf:
MeshCorev1.16.0, commit03b6ef4, 28 juli 2026 — bestandensrc/helpers/radiolib/CustomSX1262.h,src/helpers/radiolib/RadioLibWrappers.cpp, de overige wrappers insrc/helpers/radiolib/en de radiovlaggen invariants/.
Zes chips, één patroon¶
src/helpers/radiolib/ bevat zes wrappers, elk met een bijbehorende
…Wrapper.h:
| Wrapper | Chip | Opvallend |
|---|---|---|
CustomSX1262.h |
SX1262 | de meest voorkomende; 868 MHz |
CustomSX1268.h |
SX1268 | zelfde familie, 433 MHz-variant |
CustomLLCC68.h |
LLCC68 | SX126x-familie, beperkte SF-reeks |
CustomSX1276.h |
SX1276 | oudere SX127x-familie, andere registers |
CustomLR1110.h |
LR1110 | met eigen resetroutine in LR11x0Reset.h |
CustomSTM32WLx.h |
STM32WL | radio zit ín de SoC, geen SPI |
Welk bord welke chip heeft staat in Nodematrix en wordt hier niet herhaald. De keuze valt in de buildvlaggen:
variants/lilygo_tbeam_1w/platformio.ini
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
De rest van de firmware kent alleen RADIO_CLASS en WRAPPER_CLASS. Dat
is de reden dat er zes chipfamilies naast elkaar bestaan zonder dat er
ergens buiten deze map een #ifdef op chiptype staat.
std_init(): de initialisatie met terugval¶
Elke wrapper heeft een std_init(). Die zet eerst de SPI-pinnen goed —
per platform anders, zie De SPI-bus — en roept dan
begin() van RadioLib aan.
src/helpers/radiolib/CustomSX1262.h r.45-55
int status = begin(LORA_FREQ, LORA_BW, LORA_SF, cr, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 16, tcxo);
// if radio init fails with -707/-706, try again with tcxo voltage set to 0.0f
if (status == RADIOLIB_ERR_SPI_CMD_FAILED || status == RADIOLIB_ERR_SPI_CMD_INVALID) {
tcxo = 0.0f;
status = begin(LORA_FREQ, LORA_BW, LORA_SF, cr, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 16, tcxo);
}
if (status != RADIOLIB_ERR_NONE) {
Serial.print("ERROR: radio init failed: ");
Serial.println(status);
return false; // fail
}
De terugval is het interessante deel. De TCXO-spanning staat standaard op
1.6f en wordt door SX126X_DIO3_TCXO_VOLTAGE overschreven. Faalt de
initialisatie met -706 (RADIOLIB_ERR_SPI_CMD_INVALID) of -707
(RADIOLIB_ERR_SPI_CMD_FAILED), dan probeert de firmware het nog één keer
met de TCXO-spanning op nul.
[!NOTE] Dat is precies het gedrag van een bord met een gewoon kristal in plaats van een TCXO: DIO3 stuurt dan niets aan en de chip weigert de opdracht. De firmware raadt dat niet vooraf uit de buildvlaggen, maar leidt het af uit de foutcode.
De drie vaste getallen in die aanroep komen uit de wortel-platformio.ini
en zijn voor elk bord gelijk tenzij een variant ze overschrijft:
LORA_FREQ=869.618, LORA_BW=62.5, LORA_SF=8. De coderatio is LORA_CR
of anders 5, de preamblelengte is 16, en het syncwoord is het private
syncwoord van de SX126x-familie.
[!NOTE] Dit zijn buildwaarden, geen netwerkinstellingen.
LORA_SF=8staat als default inplatformio.ini; het Nederlandse netwerk draait op SF7, dat de node-configuratie er na het flashen overheen zet. Zie Aan de Slag.
Vier optionele vlaggen¶
Ná een geslaagde begin() staat CRC altijd aan en volgen vier blokken die
alleen worden gecompileerd als de variant de bijbehorende vlag zet.
| Vlag | Doet | Variantmappen |
|---|---|---|
SX126X_CURRENT_LIMIT |
stroombegrenzing van de eindtrap | 66 |
SX126X_DIO2_AS_RF_SWITCH |
DIO2 stuurt de RF-schakelaar | 60 |
SX126X_RX_BOOSTED_GAIN |
gevoeliger ontvangst, meer stroom | 64 |
SX126X_RXEN · SX126X_TXEN |
losse schakelpinnen | 24 |
De telling is per variantmap en telt zowel -D-vlaggen in
platformio.ini als #define-regels in een header binnen die map;
uitgecommentarieerde regels tellen niet mee. Van de 79 variantmappen zetten
er 60 de DIO2-vlag: 45 in platformio.ini, 22 in een header, 7 op beide
plaatsen. Wat die schakelaar doet staat in Antenne.
Ontbreekt bij de losse schakelpinnen één van de twee, dan vult de wrapper hem zelf aan:
src/helpers/radiolib/CustomSX1262.h r.68-76
#if defined(SX126X_RXEN) || defined(SX126X_TXEN)
#ifndef SX126X_RXEN
#define SX126X_RXEN RADIOLIB_NC
#endif
#ifndef SX126X_TXEN
#define SX126X_TXEN RADIOLIB_NC
#endif
setRfSwitchPins(SX126X_RXEN, SX126X_TXEN);
#endif
RADIOLIB_NC betekent niet aangesloten. Een bord dat alleen SX126X_RXEN
zet krijgt dus wél setRfSwitchPins(), met de TX-pin als niet-aangesloten —
dat is geen fout maar het normale patroon bij een bord waar DIO2 het
TX-pad schakelt en een losse pin het RX-pad.
Een registerpatch voor drie borden¶
Als laatste stap in std_init() staat een patch die alleen wordt
gecompileerd achter SX126X_REGISTER_PATCH:
src/helpers/radiolib/CustomSX1262.h r.78-84
// for improved RX with Heltec v4
#ifdef SX126X_REGISTER_PATCH
uint8_t r_data = 0;
readRegister(0x8B5, &r_data, 1);
r_data |= 0x01;
writeRegister(0x8B5, &r_data, 1);
#endif
Bit 0 van register 0x8B5 wordt gezet. Het commentaar noemt alleen de
Heltec V4, maar drie variantmappen zetten de vlag: heltec_v4,
heltec_tracker_v2 en rak3401 — de laatste met de aantekening dat het om
de SKY66122-frontendmodule gaat. Het commentaar in de wrapper is dus
smaller dan het gebruik. Zulke patches horen bij een bord en niet bij een
chip; ze staan er omdat de fabrikant iets anders deed dan het
referentieontwerp.
De radio meet zijn eigen ruisvloer¶
De laag boven de wrapper doet meer dan doorgeven. Tijdens ontvangst
bemonstert RadioLibWrapper de RSSI om een ruisvloer te bepalen.
src/helpers/radiolib/RadioLibWrappers.cpp r.87-99
if (state == STATE_RX && _num_floor_samples < NUM_NOISE_FLOOR_SAMPLES) {
int rssi = getCurrentRSSI();
if (rssi < _noise_floor + SAMPLING_THRESHOLD) { // only consider samples below current floor + sampling THRESHOLD
_num_floor_samples++;
_floor_sample_sum += rssi;
}
} else if (_num_floor_samples >= NUM_NOISE_FLOOR_SAMPLES && _floor_sample_sum != 0) {
_noise_floor = _floor_sample_sum / NUM_NOISE_FLOOR_SAMPLES;
if (_noise_floor < -120) {
_noise_floor = -120; // clamp to lower bound of -120dBi
}
Drie dingen vallen op. Er worden 64 monsters gemiddeld
(NUM_NOISE_FLOOR_SAMPLES). Een monster telt alleen mee als het onder de
huidige vloer plus 14 dB ligt (SAMPLING_THRESHOLD), zodat een passerend
pakket de meting niet omhoog trekt. En het resultaat wordt afgekapt op
−120 dBm: lager dan dat rapporteert de firmware niet, ook niet als de
omgeving stiller is.
Die vloer is geen statistiek voor de logs. Het kanaal geldt als bezet zodra de actuele RSSI boven vloer plus drempel uitkomt. Wat de vloer betekent voor haalbare afstand staat in Linkbudget.
Bronnen¶
Firmware, commit 03b6ef4 (v1.16.0, 28 juli 2026):
src/helpers/radiolib/CustomSX1262.h—std_init(), de TCXO-terugval, de optionele vlaggen en de registerpatchsrc/helpers/radiolib/— de zes wrapperssrc/helpers/radiolib/RadioLibWrappers.cpp— de gemeten ruisvloer en de bezetdrempelvariants/lilygo_tbeam_1w/platformio.ini— de radiovlaggen van één bord
Verwante hoofdstukken:
- De SPI-bus — hoe de chip aan de SoC hangt
- Antenne — wat er aan de RF-poort zit
- Linkbudget — wat het zendvermogen waard is
- RadioLib — de library zelf
- LoRa Modulatie — wat er met die bits gebeurt