### RNode Device Info Output Example Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/guides/install_firmware.md This is an example of the output you should expect when querying device information after a successful firmware installation. ```txt [20:11:22] Opening serial port /dev/ttyUSB0... [20:11:25] Device connected [20:11:25] Current firmware version: 1.26 [20:11:25] Reading EEPROM... [20:11:25] EEPROM checksum correct [20:11:25] Device signature validated [20:11:25] [20:11:25] Device info: [20:11:25] Product : LilyGO LoRa32 v2.0 850 - 950 MHz (b0:b8:36) [20:11:25] Device signature : Validated - Local signature [20:11:25] Firmware version : 1.26 [20:11:25] Hardware revision : 1 [20:11:25] Serial number : 00:00:00:02 [20:11:25] Frequency range : 850.0 MHz - 950.0 MHz [20:11:25] Max TX power : 17 dBm [20:11:25] Manufactured : 2022-01-27 20:10:32 [20:11:25] Device mode : Normal (host-controlled) ``` -------------------------------- ### Install Firmware on Board Source: https://github.com/markqvist/rnode_firmware/blob/master/Release/README.md After installing `rnodeconf`, use this command to automatically install the firmware on a connected board, following the installation guide. ```bash # Install the firmware on a board with the install guide rnodeconf --autoinstall ``` -------------------------------- ### Install RNode Configuration Program Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/guides/loracomms.md Install the RNode configuration program using pip. Ensure Python 3 and pip are installed on your system. ```bash pip install rnodeconf ``` -------------------------------- ### Install LXMF Locally Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/s_lxmf.md Use this command to install LXMF from a downloaded package when offline. Ensure Reticulum is installed first. ```bash pip install ./{PKG_NAME_lxmf} ``` -------------------------------- ### Install Nomad Network Locally Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/s_nn.md Use this command to install Nomad Network from a downloaded package when offline. Ensure Reticulum and LXMF are installed first. ```bash pip install ./{PKG_NAME_nomadnet} ``` -------------------------------- ### Install and Manage RNode Firmware with `rnodeconf` Source: https://context7.com/markqvist/rnode_firmware/llms.txt Use `rnodeconf` to install, update, and extract RNode firmware. Ensure the `rns` Python package is installed and the device is connected via USB. ```bash pip install rns --upgrade ``` ```bash rnodeconf --autoinstall ``` ```bash rnodeconf --info /dev/ttyUSB0 ``` ```bash rnodeconf --extract ``` ```bash rnodeconf --autoinstall --use-extracted ``` ```bash rnodeconf --update --use-extracted ``` -------------------------------- ### Install RNode Config Utility Source: https://github.com/markqvist/rnode_firmware/blob/master/README.md Install the RNode configuration utility via pip. This tool is used for managing and installing firmware releases on supported boards. ```bash # Install rnodeconf via rns package pip install rns --upgrade # Install the firmware on a board with the install guide rnodeconf --autoinstall ``` -------------------------------- ### Verify Nomad Network Installation Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/s_nn.md Run this command after installation to check the installed version of Nomad Network. This applies to both local and online installations. ```bash nomadnet --version ``` -------------------------------- ### Run RNode Autoinstaller Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/guides/install_firmware.md Use this command to start the RNode firmware autoinstaller. It will prompt for device insertion and configuration details. ```txt rnodeconf --autoinstall ``` -------------------------------- ### Start Reticulum Daemon (rnsd) Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/guides/loracomms.md Start the Reticulum daemon to check if the installation was successful and to generate a default configuration file if one does not exist. ```bash rnsd ``` -------------------------------- ### Verify RNode Firmware Installation Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/guides/install_firmware.md Run this command to query device information and confirm successful firmware installation. Replace `/dev/ttyUSB0` with your device's serial port. ```bash rnodeconf --info /dev/ttyUSB0 ``` -------------------------------- ### Run Nomad Network Client Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/guides/loracomms.md Start the Nomad Network client. This command initializes the client, creates necessary configuration files, and begins the network connection process. ```bash nomadnet ``` -------------------------------- ### Example RNode Device Info Output Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/guides/make_rnodes.md This is an example of the output you should expect when querying RNode device information. It confirms firmware version, hardware details, and operational mode. ```text [2022-01-27 20:11:22] Opening serial port /dev/ttyUSB0... [2022-01-27 20:11:25] Device connected [2022-01-27 20:11:25] Current firmware version: 1.26 [2022-01-27 20:11:25] Reading EEPROM... [2022-01-27 20:11:25] EEPROM checksum correct [2022-01-27 20:11:25] Device signature validated [2022-01-27 20:11:25] [2022-01-27 20:11:25] Device info: [2022-01-27 20:11:25] Product : LilyGO LoRa32 v2.0 850 - 950 MHz (b0:b8:36) [2022-01-27 20:11:25] Device signature : Validated - Local signature [2022-01-27 20:11:25] Firmware version : 1.26 [2022-01-27 20:11:25] Hardware revision : 1 [2022-01-27 20:11:25] Serial number : 00:00:00:02 [2022-01-27 20:11:25] Frequency range : 850.0 MHz - 950.0 MHz [2022-01-27 20:11:25] Max TX power : 17 dBm [2022-01-27 20:11:25] Manufactured : 2022-01-27 20:10:32 [2022-01-27 20:11:25] Device mode : Normal (host-controlled) ``` -------------------------------- ### Install LXMF Online Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/s_lxmf.md Use this command to install the latest version of LXMF via pip when an internet connection is available. ```bash pip install lxmf ``` -------------------------------- ### Verify Reticulum Version Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/s_rns.md Run this command after installation to check the installed version of Reticulum. ```bash rnstatus --version ``` -------------------------------- ### Reticulum Configuration File Example Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/guides/loracomms.md This is an example of a Reticulum configuration file. It includes settings for enabling transport, sharing the instance, and configuring a RNode LoRa interface with specific radio parameters. ```ini [reticulum] enable_transport = Yes share_instance = Yes shared_instance_port = 37428 instance_control_port = 37429 panic_on_interface_error = No [logging] loglevel = 4 [interfaces] [[Default Interface]] type = AutoInterface interface_enabled = True [[RNode LoRa Interface]] type = RNodeInterface interface_enabled = True port = /dev/ttyUSB0 frequency = 867200000 bandwidth = 125000 txpower = 7 spreadingfactor = 8 codingrate = 5 ``` -------------------------------- ### Install Reticulum Locally Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/s_rns.md Use this command to install Reticulum from a downloaded package when offline. Ensure the package is unzipped in the current directory. ```bash pip install ./{PKG_NAME_rns} ``` -------------------------------- ### Verify LXMF Installation Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/s_lxmf.md Run this command after installation to verify the LXMF version. This command is also used to check the Reticulum version. ```bash lxmd --version ``` -------------------------------- ### Install Nomad Network Online Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/s_nn.md Use this pip command to install the latest version of Nomad Network when you have an internet connection. ```bash pip install nomadnet ``` -------------------------------- ### Bidirectional Chat Node Example (Python) Source: https://context7.com/markqvist/rnode_firmware/llms.txt A complete end-to-end example demonstrating a two-node chat application. It showcases receive callbacks, packet transmission, RSSI/SNR reporting, and graceful shutdown using the RNodeInterface class. Ensure the serial port and radio parameters match on both nodes. ```python #!/usr/bin/env python3 """ RNode bidirectional chat example. Run on two machines each with an RNode on the same frequency/BW/SF/CR. """ from RNode import RNodeInterface import time, threading, sys NODE_NAME = "Chat Node A" SERIAL_PORT = "/dev/ttyUSB0" FREQUENCY = 868000000 # 868 MHz BANDWIDTH = 125000 # 125 kHz TXPOWER = 14 # dBm SF = 9 # Spreading factor CR = 5 # Coding rate 4/5 def on_packet(data: bytes, iface: RNodeInterface): try: msg = data.decode("utf-8") except UnicodeDecodeError: msg = data.hex() ts = time.strftime("%H:%M:%S") print(f"\n[{ts}] REMOTE > {msg}") print(f" RSSI={iface.r_stat_rssi} dBm SNR={iface.r_stat_snr} dB") print(f" Bitrate={iface.bitrate_kbps} kbps") print("You > ", end="", flush=True) print(f"Connecting to RNode on {SERIAL_PORT} ...") try: rnode = RNodeInterface( callback = on_packet, name = NODE_NAME, port = SERIAL_PORT, frequency = FREQUENCY, bandwidth = BANDWIDTH, txpower = TXPOWER, sf = SF, cr = CR, loglevel = RNodeInterface.LOG_NOTICE, ) except (ValueError, IOError) as e: print(f"Failed to connect: {e}") sys.exit(1) print(f"Ready on {FREQUENCY/1e6:.3f} MHz, BW={BANDWIDTH/1000:.0f}kHz, SF{SF}, CR4/{CR}") print("Type messages and press Enter to send. Ctrl-C to exit.\n") try: while True: print("You > ", end="", flush=True) msg = input() if msg: rnode.send(msg.encode("utf-8")) print(f" [sent {len(msg.encode())} bytes]") except KeyboardInterrupt: print("\nShutting down.") rnode.setRadioState(0x00) # KISS.RADIO_STATE_OFF sys.exit(0) ``` -------------------------------- ### Install rnodeconf via rns package Source: https://github.com/markqvist/rnode_firmware/blob/master/Release/README.md Install the `rns` package, which includes the `rnodeconf` tool, using pip. Ensure you upgrade to the latest version. ```bash # Install rnodeconf via rns package pip install rns --upgrade ``` -------------------------------- ### Install Reticulum Online Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/s_rns.md Use this command to install the latest version of Reticulum directly from the Python Package Index (PyPI) when an internet connection is available. ```bash pip install rns ``` -------------------------------- ### RNodeInterface Constructor and Initialization Source: https://context7.com/markqvist/rnode_firmware/llms.txt Initializes the RNodeInterface, opening the serial port, configuring radio parameters, and starting a background read thread. It handles parameter validation and potential I/O errors. ```APIDOC ## RNodeInterface ### Description Initializes the RNodeInterface, opening the serial port, configuring radio parameters, and starting a background read thread. It raises `ValueError` on invalid parameter ranges and `IOError` if the port cannot be opened or validation fails. ### Parameters - **callback** (function) - Required - Callback invoked for every received packet. - **name** (string) - Required - Name for the interface. - **port** (string) - Required - Serial port of the RNode. - **frequency** (int) - Required - Radio frequency in Hz (valid: 137–1020 MHz). - **bandwidth** (int) - Required - Radio bandwidth in Hz (valid: 7800–500000 Hz). - **txpower** (int) - Required - Transmit power in dBm (valid: 0–17). - **sf** (int) - Required - Spreading factor (valid: 7–12). - **cr** (int) - Required - Coding rate (valid: 5–8, represents 4/5 through 4/8). - **loglevel** (int) - Optional - Logging level. - **flow_control** (bool) - Optional - Enable KISS flow control. - **id_interval** (int) - Optional - Beacon interval in seconds. - **id_callsign** (string) - Optional - Amateur callsign for beaconing. ### Example ```python from RNode import RNodeInterface def on_packet(data: bytes, interface: RNodeInterface): print(f"[{interface.name}] Received {len(data)} bytes") try: rnode = RNodeInterface( callback = on_packet, name = "Field Unit 1", port = "/dev/ttyUSB0", frequency = 868000000, bandwidth = 125000, txpower = 14, sf = 8, cr = 5, loglevel = RNodeInterface.LOG_DEBUG, flow_control = False, id_interval = 600, id_callsign = "MYCALL-1", ) print(f"Interface ready: {rnode}") except ValueError as e: print(f"Configuration error: {e}") except IOError as e: print(f"Hardware error: {e}") ``` ``` -------------------------------- ### Start Reticulum Daemon with Verbose Output Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/guides/loracomms.md Start the Reticulum daemon with verbose logging enabled (`-vvv`) to monitor the configuration and status of interfaces, particularly the LoRa radio. ```bash rnsd -vvv ``` -------------------------------- ### Extract Firmware from RNode Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/guides/install_firmware.md Run this command to extract the firmware from an existing RNode device. This is useful for offline installations or updates. ```txt rnodeconf --extract ``` -------------------------------- ### Log Output for LoRa Communications Setup Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/guides/loracomms.md This log output indicates the successful initialization of the LoRa transport and the rnsd service, signifying that the system is ready for secure communication. ```log [2022-03-26 18:17:50] [Verbose] Loaded 0 tunnel table entries from storage [2022-03-26 18:17:50] [Verbose] Transport instance started [2022-03-26 18:17:50] [Notice] Started rnsd version 0.3.3 ``` -------------------------------- ### Install Reticulum Without Dependencies Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/s_rns.md Install Reticulum without resolving dependencies. This is useful in environments where dependencies cannot be met, but may result in missing functionality. Read the Pure-Python Reticulum section for implications. ```bash pip install --no-dependencies ./{PKG_NAME_rns} ``` -------------------------------- ### Control Radio State (On/Off) Source: https://context7.com/markqvist/rnode_firmware/llms.txt Turns the LoRa transceiver on or off. Use `KISS.RADIO_STATE_ON` to enable and `KISS.RADIO_STATE_OFF` to disable. The radio starts ON after `initRadio()`. ```python from RNode import RNodeInterface, KISS from time import sleep def on_packet(data, iface): print(f"Packet: {data!r}") rnode = RNodeInterface( callback=on_packet, name="Managed", port="/dev/ttyUSB0", frequency=868000000, bandwidth=125000, txpower=14, sf=7, cr=5) # Radio starts ON after initRadio() — turn it off rnode.setRadioState(KISS.RADIO_STATE_OFF) print(f"Radio state (device): {rnode.r_state}") # 0x00 sleep(2) # Turn radio back on rnode.setRadioState(KISS.RADIO_STATE_ON) print(f"Radio state (device): {rnode.r_state}") # 0x01 ``` -------------------------------- ### Autoinstall with Extracted Firmware Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/guides/install_firmware.md Use this command to perform an autoinstall using a previously extracted firmware file. This is helpful when an internet connection is unavailable. ```txt rnodeconf --autoinstall --use-extracted ``` -------------------------------- ### Initialize RNodeInterface with Callbacks and Parameters Source: https://context7.com/markqvist/rnode_firmware/llms.txt Initializes the RNodeInterface, setting up the serial port, radio parameters, and a callback for received packets. Catches configuration and hardware errors. ```python from RNode import RNodeInterface # Callback invoked for every received packet def on_packet(data: bytes, interface: RNodeInterface): print(f"[{interface.name}] Received {len(data)} bytes") print(f" Payload : {data.decode('utf-8', errors='replace')}") print(f" RSSI : {interface.r_stat_rssi} dBm") print(f" SNR : {interface.r_stat_snr} dB") print(f" Bitrate : {interface.bitrate_kbps} kbps") try: rnode = RNodeInterface( callback = on_packet, name = "Field Unit 1", port = "/dev/ttyUSB0", # Serial port of the RNode frequency = 868000000, # 868 MHz (valid: 137–1020 MHz) bandwidth = 125000, # 125 kHz (valid: 7800–500000 Hz) txpower = 14, # dBm (valid: 0–17) sf = 8, # Spreading factor (valid: 7–12) cr = 5, # Coding rate 4/5 (valid: 5–8) loglevel = RNodeInterface.LOG_DEBUG, flow_control = False, # Enable KISS flow control id_interval = 600, # Beacon interval in seconds id_callsign = "MYCALL-1", # Amateur callsign for beaconing ) print(f"Interface ready: {rnode}") # Interface ready: RNodeInterface[Field Unit 1] except ValueError as e: print(f"Configuration error: {e}") except IOError as e: print(f"Hardware error: {e}") # --- Valid parameter ranges --- # frequency : 137,000,000 – 1,020,000,000 Hz # bandwidth : 7,800 – 500,000 Hz # txpower : 0 – 17 dBm (SX1262 boards may support up to 22 dBm; # Heltec v4 with PA up to 28 dBm) # sf : 5 – 12 # cr : 5 – 8 (represents 4/5 through 4/8) ``` -------------------------------- ### Build RNode Firmware with `make` Targets Source: https://context7.com/markqvist/rnode_firmware/llms.txt Compile RNode firmware for various supported boards using `make` targets. Ensure the appropriate toolchains are prepared before building. ```bash make prep-esp32 ``` ```bash make prep-nrf ``` ```bash make firmware-tbeam ``` ```bash make firmware-tbeam_sx126x ``` ```bash make firmware-heltec32_v3 ``` ```bash make firmware-lora32_v21 ``` ```bash make firmware-t3s3 ``` ```bash make release ``` ```bash make upload-tbeam ``` ```bash make upload-lora32_v21 ``` ```bash make clean ``` -------------------------------- ### Enter TNC Mode with rnodeconf Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/guides/tnc_mode.md Use this command to place your RNode into TNC mode. Replace `/dev/ttyUSB0` with your device's serial port. The program will then prompt for channel configuration parameters. ```bash rnodeconf -T /dev/ttyUSB0 ``` -------------------------------- ### Update Radio Parameters Dynamically Source: https://context7.com/markqvist/rnode_firmware/llms.txt Demonstrates updating radio parameters like frequency after initialization using setter methods. Changes are sent as KISS commands and should be validated. ```python from RNode import RNodeInterface, KISS def noop(data, iface): pass rnode = RNodeInterface( callback=noop, name="Configurable", port="/dev/ttyUSB0", frequency=433000000, bandwidth=125000, txpower=10, sf=7, cr=5) # Change frequency to 915 MHz rnode.frequency = 915000000 rnode.setFrequency() ``` -------------------------------- ### Reticulum Daemon Output with Default Config Creation Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/guides/loracomms.md This output indicates that Reticulum could not find a configuration file and has created a default one. Review and modify the configuration file at `/home/bob/.reticulum/config` as needed. ```log [2022-03-26 17:14:05] [Notice] Could not load config file, creating default configuration file... [2022-03-26 17:14:05] [Notice] Default config file created. Make any necessary changes in /home/bob/.reticulum/config and restart Reticulum if needed. [2022-03-26 17:14:09] [Notice] Started rnsd version 0.3.3 ``` -------------------------------- ### Update Firmware on Existing RNode Source: https://github.com/markqvist/rnode_firmware/blob/master/Console/source/guides/install_firmware.md Use this command to update the firmware on an existing RNode using a locally extracted firmware file. This is an alternative to a full autoinstall. ```txt rnodeconf --update ``` -------------------------------- ### Configure CSMA Airtime Limits via KISS Commands Source: https://context7.com/markqvist/rnode_firmware/llms.txt This Python script demonstrates how to set short-term and long-term airtime limits using KISS commands. Ensure the serial port and baud rate match your device configuration. ```python import serial, struct, time ser = serial.Serial("/dev/ttyUSB0", 115200, timeout=1) time.sleep(2) FEND = 0xC0 def kiss_cmd(cmd, data=b""): return bytes([FEND, cmd]) + data + bytes([FEND]) # Set short-term airtime limit to 20% (CMD_ST_ALOCK = 0x0B) # Value encoding: int(limit_fraction * 100 * 100) st_limit = int(0.20 * 10000) # = 2000 ser.write(kiss_cmd(0x0B, struct.pack(">H", st_limit))) # Set long-term airtime limit to 10% (CMD_LT_ALOCK = 0x0C) lt_limit = int(0.10 * 10000) # = 1000 ser.write(kiss_cmd(0x0C, struct.pack(">H", lt_limit))) # Remove airtime limits (set to 0) ser.write(kiss_cmd(0x0B, struct.pack(">H", 0))) ser.write(kiss_cmd(0x0C, struct.pack(">H", 0))) # CSMA parameters (firmware compile-time defaults in Config.h): # CSMA_SIFS_MS = 0 ms (Short Inter-Frame Space) # CSMA_SLOT_MIN_MS = 24 ms (minimum slot time) # CSMA_SLOT_MAX_MS = 100 ms (maximum slot time) # CSMA_CW_BANDS = 4 (contention window bands) # CSMA_CW_PER_BAND_WINDOWS = 15 (windows per band) # CSMA_BAND_1_MAX_AIRTIME = 7 % (max airtime for band 1) # CSMA_BAND_N_MIN_AIRTIME = 85 % (min airtime for top band) # CSMA_INFR_THRESHOLD_DB = 11 dB (interference detection threshold) # CSMA_RFENV_RECAL_MS = 2500 ms (RF environment recalibration period) # DCD_SAMPLES = 2500 (channel utilization sample window) # AIRTIME_LONGTERM = 3600 s (long-term airtime tracking window) ser.close() ``` -------------------------------- ### RNodeInterface.setFrequency(), setBandwidth(), setTXPower(), setSpreadingFactor(), setCodingRate() Source: https://context7.com/markqvist/rnode_firmware/llms.txt Dynamically updates radio parameters by sending KISS command frames. The device echoes back the accepted value, which is then stored in the corresponding `r_*` attributes. `validateRadioState()` should be called to confirm changes. ```APIDOC ## RNodeInterface.setFrequency() / setBandwidth() / setTXPower() / setSpreadingFactor() / setCodingRate() ### Description Each method encodes the corresponding parameter as a KISS command frame and writes it to the serial port. The device echoes back the accepted value, which is stored in the `r_*` attributes. Call `validateRadioState()` after changes to confirm the device accepted all parameters. ### Parameters - **frequency** (int) - Required (for `setFrequency`) - The new frequency in Hz. - **bandwidth** (int) - Required (for `setBandwidth`) - The new bandwidth in Hz. - **txpower** (int) - Required (for `setTXPower`) - The new transmit power in dBm. - **sf** (int) - Required (for `setSpreadingFactor`) - The new spreading factor. - **cr** (int) - Required (for `setCodingRate`) - The new coding rate. ### Example ```python from RNode import RNodeInterface, KISS def noop(data, iface): pass rnode = RNodeInterface( callback=noop, name="Configurable", port="/dev/ttyUSB0", frequency=433000000, bandwidth=125000, txpower=10, sf=7, cr=5) # Change frequency to 915 MHz rnode.frequency = 915000000 rnode.setFrequency() ``` ``` -------------------------------- ### RNodeInterface.queue() / process_queue() Source: https://context7.com/markqvist/rnode_firmware/llms.txt Manages outgoing packet transmission with flow control, queuing packets until the device is ready. ```APIDOC ## RNodeInterface.queue() / process_queue() - Flow-Controlled Transmission ### Description When `flow_control=True`, outgoing packets are queued instead of written immediately. The device signals readiness with a `CMD_READY` frame, at which point `process_queue()` is called automatically by the read loop to dequeue and transmit one packet. ### Method `queue(packet)` (internal) `process_queue()` (internal, called automatically) ### Parameters #### Path Parameters - **packet** (bytes) - The data packet to be queued. ### Request Example ```python from RNode import RNodeInterface def on_packet(data, iface): print(f"Received: {data!r}") rnode = RNodeInterface( callback=on_packet, name="Flow Controlled", port="/dev/ttyUSB0", frequency=868000000, bandwidth=125000, txpower=14, sf=9, cr=5, flow_control=True) # <-- enable flow control # Queue multiple packets — only one is sent at a time for i in range(5): msg = f"Packet {i}".encode() rnode.send(msg) # internally calls processOutgoing -> queue() if not ready print(f"Packets queued: {len(rnode.packet_queue)}") # The read loop calls process_queue() automatically when CMD_READY arrives # You can also manually inspect and drain the queue: import time while len(rnode.packet_queue) > 0: print(f"Still queued: {len(rnode.packet_queue)}") time.sleep(0.5) ``` ### Response #### Success Response (200) Packets are transmitted sequentially when the device signals readiness. The `packet_queue` attribute reflects the current number of queued packets. ``` -------------------------------- ### RNodeInterface.updateBitrate() Source: https://context7.com/markqvist/rnode_firmware/llms.txt Calculates the theoretical on-air data rate from current radio parameters and stores it. ```APIDOC ## RNodeInterface.updateBitrate() - Compute On-Air Bitrate ### Description Calculates the theoretical on-air data rate from the current `r_sf`, `r_cr`, and `r_bandwidth` values reported by the device and stores the result in `bitrate` (bps) and `bitrate_kbps` (kbps). ### Method `updateBitrate()` ### Parameters None ### Request Example ```python from RNode import RNodeInterface def on_packet(data, iface): pass rnode = RNodeInterface( callback=on_packet, name="Bitrate Test", port="/dev/ttyUSB0", frequency=868000000, bandwidth=500000, txpower=14, sf=7, cr=5) # updateBitrate is called automatically when r_sf/r_cr/r_bandwidth update # Manually trigger a recalculation after reading reported values rnode.updateBitrate() print(f"SF{rnode.r_sf} / BW{rnode.r_bandwidth/1000:.0f}kHz / CR4/{rnode.r_cr}") print(f"On-air bitrate: {rnode.bitrate_kbps} kbps") # SF7 / BW500kHz / CR4/5 # On-air bitrate: 21.88 kbps # Compare configurations: # SF7 BW500kHz CR4/5 → ~21.88 kbps (short range, high throughput) # SF9 BW125kHz CR4/5 → ~1.76 kbps (medium range) # SF12 BW125kHz CR4/8 → ~0.18 kbps (maximum range) ``` ### Response #### Success Response (200) - **bitrate** (int) - The calculated on-air bitrate in bits per second (bps). - **bitrate_kbps** (float) - The calculated on-air bitrate in kilobits per second (kbps). #### Response Example ``` SF7 / BW500kHz / CR4/5 On-air bitrate: 21.88 kbps ``` ``` -------------------------------- ### Send Advanced KISS Commands via Serial Source: https://context7.com/markqvist/rnode_firmware/llms.txt Use this Python script for direct serial access to advanced KISS commands not exposed by the RNode.py library. Ensure the serial port is correctly configured and the device is connected. ```python import serial, time # Direct serial access for advanced commands not in RNode.py ser = serial.Serial("/dev/ttyUSB0", 115200, timeout=1) time.sleep(2) FEND = 0xC0 def kiss_cmd(cmd_byte, payload=b""): return bytes([FEND, cmd_byte]) + payload + bytes([FEND]) # --- Device detection handshake (CMD_DETECT = 0x08) --- # Send DETECT_REQ (0x73), device responds with DETECT_RESP (0x46) ser.write(kiss_cmd(0x08, bytes([0x73]))) # --- Query firmware version (CMD_FW_VERSION = 0x50) --- ser.write(kiss_cmd(0x50)) # --- Read EEPROM (CMD_ROM_READ = 0x51) --- ser.write(kiss_cmd(0x51)) # --- Hard reset (CMD_RESET = 0x55, payload must be 0xF8) --- # ser.write(kiss_cmd(0x55, bytes([0xF8]))) # --- Bluetooth control (CMD_BT_CTRL = 0x46) --- # 0x00 = off, 0x01 = on, 0x02 = enable pairing mode ser.write(kiss_cmd(0x46, bytes([0x02]))) # enter pairing mode # --- WiFi mode (CMD_WIFI_MODE = 0x6A) --- # 0x00 = off, 0x01 = station, 0x02 = access point ser.write(kiss_cmd(0x6A, bytes([0x01]))) # STA mode # --- Set short-term airtime limit (CMD_ST_ALOCK = 0x0B) --- # 2-byte uint16, value = limit * 100 * 100 (e.g. 0.1 = 1000) import struct limit = int(0.1 * 100 * 100) # 10% airtime limit ser.write(kiss_cmd(0x0B, struct.pack(">H", limit))) # --- Request random byte (CMD_RANDOM = 0x40) --- ser.write(kiss_cmd(0x40)) # --- LED blink (CMD_BLINK = 0x30) --- ser.write(kiss_cmd(0x30, bytes([3]))) # blink 3 times ser.close() ``` -------------------------------- ### Board Feature Flags in Boards.h Source: https://context7.com/markqvist/rnode_firmware/llms.txt These are compile-time flags used to enable or disable hardware subsystems on different boards. Inspect these to understand a board's capabilities. ```c // Feature flags available in Boards.h // (all default to false, set to true per board) #define HAS_DISPLAY // SSD1306 / SH110X / ST7789 / e-paper display #define HAS_BLUETOOTH // Classic Bluetooth (SerialBT) #define HAS_BLE // Bluetooth Low Energy #define HAS_WIFI // 802.11 WiFi (ESP32 only) #define HAS_TCXO // Temperature Compensated Crystal Oscillator #define HAS_PMU // Power Management Unit (AXP192/AXP2101) #define HAS_NP // NeoPixel RGB LED #define HAS_EEPROM // On-chip or emulated EEPROM #define HAS_INPUT // Physical button(s) #define HAS_SLEEP // Deep sleep / wakeup support #define HAS_LORA_PA // External LoRa Power Amplifier #define HAS_LORA_LNA // External LoRa Low Noise Amplifier // Platform identifiers // PLATFORM_AVR = 0x90 (ATmega1284P, ATmega2560) // PLATFORM_ESP32 = 0x80 (all ESP32 variants) // PLATFORM_NRF52 = 0x70 (nRF52840) // Modem chip identifiers (set via -DMODEM=0xNN compile flag) // SX1276 = 0x01 // SX1278 = 0x02 // SX1262 = 0x03 // SX1280 = 0x04 (2.4 GHz) // Example: check capabilities at runtime via reported board byte // Board 0x3F (Heltec v4) has: HAS_LORA_PA, HAS_LORA_LNA, // HAS_BLE, HAS_WIFI, PA_MAX_OUTPUT=28dBm ``` -------------------------------- ### Configure Radio Parameters Source: https://context7.com/markqvist/rnode_firmware/llms.txt Adjusts radio settings such as bandwidth, TX power, spreading factor, and coding rate. Use `validateRadioState()` to confirm changes. ```python rnode.bandwidth = 500000 rnode.setBandwidth() rnode.txpower = 2 rnode.setTXPower() rnode.sf = 12 rnode.setSpreadingFactor() rnode.cr = 8 rnode.setCodingRate() from time import sleep sleep(0.3) if rnode.validateRadioState(): print("Radio reconfigured successfully") print(f" Frequency : {rnode.r_frequency / 1e6:.3f} MHz") print(f" Bandwidth : {rnode.r_bandwidth / 1000:.0f} kHz") print(f" TX Power : {rnode.r_txpower} dBm") print(f" SF : {rnode.r_sf}") print(f" CR : 4/{rnode.r_cr}") print(f" Bitrate : {rnode.bitrate_kbps} kbps") else: print("WARNING: Radio parameter mismatch") ``` -------------------------------- ### Compute On-Air Bitrate Source: https://context7.com/markqvist/rnode_firmware/llms.txt Calculates the theoretical on-air data rate based on SF, CR, and bandwidth. `updateBitrate()` is called automatically on parameter changes but can be triggered manually. ```python from RNode import RNodeInterface def on_packet(data, iface): pass rnode = RNodeInterface( callback=on_packet, name="Bitrate Test", port="/dev/ttyUSB0", frequency=868000000, bandwidth=500000, txpower=14, sf=7, cr=5) # updateBitrate is called automatically when r_sf/r_cr/r_bandwidth update # Manually trigger a recalculation after reading reported values rnode.updateBitrate() print(f"SF{rnode.r_sf} / BW{rnode.r_bandwidth/1000:.0f}kHz / CR4/{rnode.r_cr}") print(f"On-air bitrate: {rnode.bitrate_kbps} kbps") # SF7 / BW500kHz / CR4/5 # On-air bitrate: 21.88 kbps # Compare configurations: # SF7 BW500kHz CR4/5 → ~21.88 kbps (short range, high throughput) # SF9 BW125kHz CR4/5 → ~1.76 kbps (medium range) # SF12 BW125kHz CR4/8 → ~0.18 kbps (maximum range) ```