# GRC Flowgraph Guide GNU Radio Companion (GRC) integration for gr-rylr998. ## Installation After installing gr-rylr998, the blocks appear in GRC under the **[RYLR998]** category. ```bash # Install the module cd gr-rylr998 pip install -e . # Refresh GRC block tree grcc --help # or restart GRC ``` ## Block Palette | Block | Category | Description | |-------|----------|-------------| | RYLR998 Receiver | [RYLR998] | Complete RX chain (hier block) | | RYLR998 Transmitter | [RYLR998] | Complete TX chain (hier block) | | CSS Demodulator | [RYLR998] | FFT-based chirp demodulation | | CSS Modulator | [RYLR998] | Chirp generation from bins | | Frame Sync | [RYLR998] | Preamble/sync word detection | | Frame Generator | [RYLR998] | Preamble/SFD/sync word generation | | PHY Decoder | [RYLR998] | Gray → deinterleave → Hamming → dewhiten | | PHY Encoder | [RYLR998] | Whiten → Hamming → interleave → Gray | --- ## Quick Start Flowgraphs ### 1. Basic Receiver (BladeRF → Decoded Payload) ``` ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ │ osmocom Source │────▶│ RYLR998 Receiver │────▶│ Message Debug │ │ (BladeRF) │ IQ │ SF9, NID=18 │ msg │ (or File Sink) │ └─────────────────┘ └──────────────────┘ └─────────────────┘ ``` **GRC Setup:** 1. Add **osmocom Source** (or your SDR source) - Device Arguments: `bladerf=0` - Sample Rate: `250e3` - Center Freq: `915e6` (or your frequency) 2. Add **RYLR998 Receiver** - Spreading Factor: `9` - Sample Rate: `250e3` - Bandwidth: `125e3` - Expected NETWORKID: `18` (or `-1` for any) 3. Add **Message Debug** (or **PDU to Tagged Stream** → **File Sink**) 4. Connect: Source → RYLR998 RX → Debug --- ### 2. Basic Transmitter (Payload → BladeRF) ``` ┌─────────────────┐ ┌──────────────────────┐ ┌─────────────────┐ │ Message Strobe │────▶│ RYLR998 Transmitter │────▶│ osmocom Sink │ │ "Hello" │ msg │ SF9, NID=18 │ IQ │ (BladeRF) │ └─────────────────┘ └──────────────────────┘ └─────────────────┘ ``` **GRC Setup:** 1. Add **Message Strobe** (or **PDU Generator**) - Message: `pmt.intern("Hello, LoRa!")` - Period: `1000` (ms) 2. Add **RYLR998 Transmitter** - Spreading Factor: `9` - Sample Rate: `125e3` - Bandwidth: `125e3` - NETWORKID: `18` - Preamble Length: `8` 3. Add **osmocom Sink** - Device Arguments: `bladerf=0` - Sample Rate: `125e3` - Center Freq: `915e6` 4. Connect: Strobe → RYLR998 TX → Sink --- ### 3. Loopback Test (No Hardware) ``` ┌─────────────────┐ ┌────────────┐ ┌─────────────┐ ┌─────────────────┐ │ Message Strobe │────▶│ RYLR998 TX │────▶│ Channel Sim │────▶│ RYLR998 RX │ │ "Test" │ │ NID=18 │ │ (optional) │ │ NID=18 │ └─────────────────┘ └────────────┘ └─────────────┘ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Message Debug │ └─────────────────┘ ``` **GRC Setup:** 1. TX chain as above (but no SDR sink) 2. Optionally add **Channel Model** for noise/fading 3. Add **RYLR998 Receiver** 4. Add **Message Debug** to see decoded payloads 5. Connect: TX IQ → (Channel) → RX → Debug --- ## Advanced Flowgraphs ### 4. Multi-Channel Scanner Scan multiple LoRa channels and decode any detected frames: ``` ┌────────────────┐ ┌──────────────┐ ┌───▶│ Freq Xlating │────▶│ RYLR998 RX │───┐ │ │ Filter (ch 0) │ │ SF9 │ │ ┌─────────────┐ │ └────────────────┘ └──────────────┘ │ │ SDR Source │─────┤ │ ┌─────────────┐ │ Wideband │ │ ┌────────────────┐ ┌──────────────┐ ├──▶│ Msg Mux/ │ └─────────────┘ ├───▶│ Freq Xlating │────▶│ RYLR998 RX │───┤ │ Aggregator │ │ │ Filter (ch 1) │ │ SF9 │ │ └─────────────┘ │ └────────────────┘ └──────────────┘ │ │ │ └───▶ ... more channels ... ────┘ ``` **Key Settings:** - SDR Source: Wide bandwidth (e.g., 2 MHz) - Freq Xlating Filters: Tune to each channel center - Each RX can have different SF/NETWORKID --- ### 5. Detailed RX Chain (Custom Processing) For advanced users who need access to intermediate data: ``` ┌───────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │ SDR Source│────▶│ CSS Demod │────▶│ Frame Sync │────▶│ PHY Decode │────▶│ Msg Debug │ │ │ IQ │ │bins │ │syms │ │ msg │ │ └───────────┘ └──────┬──────┘ └──────┬──────┘ └─────────────┘ └───────────┘ │ │ ▼ ▼ ┌─────────────┐ ┌─────────────┐ │ File Sink │ │ Tag Debug │ │ (raw bins) │ │ (NETWORKID) │ └─────────────┘ └─────────────┘ ``` This allows: - Saving raw demodulated bins for analysis - Monitoring NETWORKID without full decode - Custom filtering between stages --- ### 6. Detailed TX Chain (Custom Processing) ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │ Msg Source │────▶│ PHY Encode │────▶│ Frame Gen │────▶│ CSS Mod │────▶│ SDR Sink │ │ │bytes│ │bins │ │bins │ │ IQ │ │ └─────────────┘ └─────────────┘ └──────┬──────┘ └─────────────┘ └───────────┘ │ ▼ ┌─────────────┐ │ Vector Sink │ │ (frame bins)│ └─────────────┘ ``` This allows: - Inspecting encoded symbols before modulation - Custom preamble/sync word injection - Frame structure debugging --- ## Parameter Reference ### Common Parameters (All Blocks) | Parameter | Values | Description | |-----------|--------|-------------| | Spreading Factor | 7-12 | Higher = longer range, lower rate | | Sample Rate | Hz | Must be ≥ bandwidth × oversampling | | Bandwidth | 125e3, 250e3, 500e3 | LoRa signal bandwidth | | Coding Rate | 1-4 | 1=4/5, 2=4/6, 3=4/7, 4=4/8 | ### RX-Specific Parameters | Parameter | Default | Description | |-----------|---------|-------------| | Expected NETWORKID | -1 | Filter frames by NID (-1 = accept all) | | use_grlora_gray | True | Gray mapping mode (see notes) | | soft_decoding | False | Bin offset mode (see notes) | ### TX-Specific Parameters | Parameter | Default | Description | |-----------|---------|-------------| | NETWORKID | 18 | Encode this NID in sync word | | Preamble Length | 8 | Number of preamble upchirps | --- ## Sample Rate Guidelines | Configuration | Minimum Sample Rate | Recommended | |---------------|--------------------:|------------:| | BW=125kHz, any SF | 125 kHz | 250 kHz | | BW=250kHz, any SF | 250 kHz | 500 kHz | | BW=500kHz, any SF | 500 kHz | 1 MHz | **Note:** Higher sample rates improve timing accuracy but increase CPU load. --- ## Tips & Troubleshooting ### No Frames Detected 1. **Check center frequency** - Must match RYLR998 setting 2. **Check NETWORKID** - Set to `-1` to accept any, or match RYLR998 3. **Check bandwidth** - RYLR998 default is 125 kHz 4. **Lower sample rate** - Try `sample_rate = bw` first 5. **Check antenna** - Ensure proper connection ### Decoded Payload is Garbage 1. **SF mismatch** - Must match transmitter exactly 2. **CR mismatch** - Must match transmitter 3. **Wrong decode mode** - For real SDR captures, use defaults ### High CPU Usage 1. **Reduce sample rate** - Use minimum needed 2. **Increase SF** - Lower symbol rate = less processing 3. **Add decimation** - Before RYLR998 RX block ### Message Output Format The RX block outputs PMT messages with: ```python { 'payload': bytes, # Decoded payload 'networkid': int, # Extracted NETWORKID 'cfo_bin': float, # Carrier frequency offset 'crc_ok': bool, # CRC verification result 'rssi': float, # Signal strength (if available) } ``` --- ## Example GRC Files The `examples/` directory contains ready-to-use flowgraphs: | File | Description | |------|-------------| | `rylr998_rx_flowgraph.grc` | BladeRF → RX → File output | | `rylr998_tx_flowgraph.grc` | File input → TX → BladeRF | | `rylr998_loopback_test.grc` | Software loopback verification | To use: ```bash gnuradio-companion examples/rylr998_rx_flowgraph.grc ``` --- ## Integration with Other Tools ### With gr-lora_sdr gr-rylr998 is compatible with gr-lora_sdr. You can: - Use gr-lora_sdr CSS demod → gr-rylr998 PHY decode - Use gr-rylr998 PHY encode → gr-lora_sdr CSS mod ### With SoapySDR Any SoapySDR-supported device works: ``` Device Arguments: soapy=0,driver=bladerf ``` ### With File Sources For offline analysis: ``` File Source → Throttle → RYLR998 RX → Message Debug ``` Set throttle rate to match original sample rate.