ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
LoRaGateway - a real LoRa radio bridged to the gateway

Layer: Foundation ยท Build flags: PROTOCORE_ENABLE_LORA, PROTOCORE_ENABLE_GATEWAY

What this example teaches

The radio-plugin half of RadioGateway: instead of a simulated feed, this drives an actual Semtech SX127x / RFM95-96 over SPI and bridges its frames to the gateway.

RFM95 RX --SPI--> protocore_lora_recv() --> protocore_lora_frame_parse() --> protocore_gateway_uplink()
|
envelope + topic lora/0/<from>
|
northbound publish (MQTT/HTTP/WS)

The services/lora module has two layers, and only the first is hardware-specific:

  • Driver - the SX127x register protocol over a protocore_lora_bus (two callbacks that read / write a chip register). Here they are a few SPI transfers; that is the only code tied to your board.
  • Codec - protocore_lora_frame_parse / protocore_lora_frame_build handle the RadioHead 4-byte header (to / from / id / flags) that sits on top of the header-less LoRa PHY.
protocore_lora_config cfg = {}; cfg.freq_hz = 915000000; cfg.spreading = 7; cfg.bandwidth = 7;
cfg.coding_rate = 1; cfg.sync_word = 0x12; cfg.tx_power = 17;
protocore_lora_init(&bus, &cfg); // verifies the chip id, applies the config
protocore_lora_set_rx(&bus); // listen
int n = protocore_lora_recv(&bus, buf, sizeof(buf), &rssi); // -> a frame, or -1
protocore_lora_header h; const uint8_t *payload; uint16_t plen;
protocore_lora_frame_parse(buf, n, &h, &payload, &plen);
protocore_gateway_uplink(0, h.from, payload, plen, rssi); // bridge northbound
proto_bool protocore_gateway_uplink(uint8_t *work, uint8_t port_id, uint16_t src_addr, const uint8_t *payload, uint16_t len, int16_t rssi)
Bridge a received southbound frame northbound: envelope it and .
int protocore_lora_recv(uint8_t *work, const protocore_lora_bus *bus, uint8_t *buf, uint8_t cap, int16_t *rssi)
If a frame has been received, copy it into buf and report its RSSI.
void protocore_lora_set_rx(uint8_t *work, const protocore_lora_bus *bus)
Put the radio in continuous-receive mode (call once, then poll .
proto_bool protocore_lora_init(uint8_t *work, const protocore_lora_bus *bus, const protocore_lora_config *cfg)
Initialize the SX127x: verify the chip, switch to LoRa mode, and .
proto_bool protocore_lora_frame_parse(uint8_t *work, const uint8_t *raw, uint16_t len, protocore_lora_header *hdr, const uint8_t **payload, uint16_t *payload_len)
Split a received frame into its header and payload.
Radio configuration applied by protocore_lora_init().
Definition lora.h:70
uint32_t freq_hz
carrier frequency in Hz (e.g. 868100000 / 915000000).
Definition lora.h:71
uint8_t bandwidth
bandwidth code 0..9 (7 = 125 kHz - the common default).
Definition lora.h:73
uint8_t sync_word
0x12 private / 0x34 LoRaWAN.
Definition lora.h:75
uint8_t spreading
spreading factor 6..12 (SF7 default is a good start).
Definition lora.h:72
uint8_t tx_power
PA_BOOST power 2..17 dBm.
Definition lora.h:76
uint8_t coding_rate
coding rate 1..4 (1 = 4/5).
Definition lora.h:74
RadioHead-compatible LoRa frame header (precedes the payload).
Definition lora.h:47
uint8_t from
source node address
Definition lora.h:49

A downlink (a northbound command) is the mirror: protocore_lora_frame_build() then protocore_lora_send(), driven by the gateway port's transmit callback.

Wiring (ESP32 <-> RFM95)

RFM95 ESP32
SCK GPIO 18
MISO GPIO 19
MOSI GPIO 23
NSS GPIO 5
RST GPIO 14
DIO0 GPIO 26
VCC 3V3
GND GND

Change the PIN_* constants for your board. A production build triggers RX off the DIO0 interrupt and rides the DMA + FORWARD-lane path (RadioGateway); this sketch polls to stay simple. It needs the module wired to actually receive - the codec and the register protocol are host-tested in test/test_lora.

Build-flag note

The flags must reach the library build, so pass them as build flags:

pio ci --board=esp32dev --project-option="framework=arduino" \
--project-option="build_flags=-DPROTOCORE_ENABLE_LORA=1 -DPROTOCORE_ENABLE_GATEWAY=1" \
--lib="." examples/Drivers/LoRaGateway/LoRaGateway.ino