-
Notifications
You must be signed in to change notification settings - Fork 0
Radio and Regions
src/radio/DuckLoRa.h/.cpp wraps RadioLib's SX127x/SX126x interrupt-driven driver classes to talk to the external LoRa transceiver chips used by all currently supported boards (see Supported Boards). Configuration (frequency, spreading factor, bandwidth, etc.) comes from src/include/cdpcfg.h and the per-board headers under src/include/boards/.
src/radio/RadioRegionConfig.h/.cpp lets a single firmware build be field-provisioned for the regulatory frequency band of the country it's deployed in, instead of requiring a separate firmware build per country.
enum class RadioRegion : uint8_t { MY = 0, SG = 1, PH = 2, ID = 3, US = 4, UK = 5 };-
begin()— loads a previously field-provisioned region from flash (falls back to theMYpreset, which matches this repo's long-standing hardcoded defaults, if none was ever set or storage fails an integrity check). Called duringsetupWithDefaults(), before the radio is initialized. -
setRegion(region)— applies and persists a region, updating the default radio band and uplink channel pool for the next boot. Does not retune an already-initialized radio, so callers reboot shortly after a successful call. -
regionName()/regionFromName()— convert between the enum and short string codes ("MY","US", etc.), shared by the serial provisioning command below and any future BLE/app-based settings screen. - Field provisioning over USB serial:
AT+RADIOREGION=<code>(region choice isn't secret, so unlike other provisioning commands this can be re-sent at any time, no reset step required first).
Regulatory note: selecting a region only changes which frequencies are used — it does not enforce that region's duty-cycle or dwell-time rules (e.g. EU868/UK's ~1% duty cycle, US915 dwell-time/frequency-hopping requirements). This is called out explicitly in the source and is a real compliance gap to close before fielding devices in a region with such rules.
When a MamaDuck sends a packet it originated (not one it's relaying) directly to a PapaDuck, it picks a random channel from an 8-channel pool (921.4–922.8 MHz, 200 kHz spacing, all AS923 channels) before transmitting, instead of always using the shared mesh channel. This spreads uplink traffic across all the demodulators on a multi-channel SX1302 LoRa concentrator gateway, reducing last-hop collisions when many nodes are within direct range of the gateway.
Rules:
- Channel switching applies only when the packet is addressed to
PAPADUCK_DUIDand this device is the original sender (sduid == this->duid). - Any relayed packet (
sduid != this->duid), regardless of destination, stays on the shared mesh channel (922.8 MHz) so the next hop can hear it. - The mesh channel is automatically restored after each transmission (in the radio's TX-done interrupt handler), so a node always listens on the shared channel between sends.
| File | Symbol | Role |
|---|---|---|
src/Ducks/Duck.h |
sendToRadio() |
Decides whether to apply the channel switch |
src/radio/DuckLoRa.h/.cpp
|
setUplinkFrequency() |
Retunes the radio via RadioLib |
src/radio/DuckLoRa.h/.cpp
|
getRandomUplinkChannel() |
Picks uniformly from the pool |
src/include/cdpcfg.h |
CDPCFG_UPLINK_CHANNEL_POOL |
Defines the 8-channel pool |
See docs/uplink-channel-spreading.md in the repository for the full write-up with packet-flow diagrams.