Skip to main content

A lightweight cross-language communication protocol for rocketry telemetry over LoRa.

Project description

edLoRa Protocol

PyPI version

A lightweight, cross-language (C++ & Python) binary protocol designed specifically for rocketry telemetry and command data over LoRa modules. Supports both standard Linux and ESP32 platforms in C++, and comes with a Python 3 ground station implementation.

Features

  • Binary Packing: Completely avoids string processing to keep LoRa bandwidth usage minimal.
  • Robust Framing: Dedicated sync bytes, payload length checking, and CCITT CRC-16 checksums ensure data integrity even on noisy RF channels.
  • Multi-node addressing: Includes Sender ID and Receiver ID (with 0xFF reserved for Broadcast).
  • Message Types: Differentiates traffic types (e.g., GPS, IMU, Altimeter, Commands).
  • Embedded Friendly: The C++ implementation avoids dynamic memory allocation entirely, protecting against heap fragmentation on ESP32/Arduino.
  • Optional Crypto: Includes a lightweight XOR-cipher wrapper inside edlora_crypto for obfuscating payload bytes. (Easily swappable with AES if actual cryptographic security is required).

Directory Structure

  • cpp/: C++ header (edlora.h) and source implementation for ESP32/Linux.
  • python/: Python 3.x module (edlora.py) for the Ground Station / decoding logic.
  • examples/: Sample usage scripts demonstrating perfect cross-language compatibility.
    • test_linux.cpp and test_python.py demonstrate basic raw packing/unpacking.

Message Types (MsgType)

To allow for structured data, edLoRa categorizes packets using the MsgType byte:

Name Hex Value Description
HEARTBEAT 0x00 Simple keep-alive or ping.
GPS 0x01 Latitude, Longitude, Fix Type, Sat count.
ALTIMETER 0x02 Altitude and velocity telemetry data.
IMU 0x03 Raw Accel, Gyro, Mag data.
COMMAND 0x04 Ground-to-vehicle commands or text logs.
SYS_STATE 0x05 System battery, temp, and current flight phase.
ORIENTATION 0x06 Calculated attitude (Quaternions/Euler angles).
EVENT 0x07 Major flight events (Liftoff, MECO, Apogee, Deployment).
ERROR_MSG 0xFE Faults and system error states.
CUSTOM 0xFF Freeform binary payloads.

Device Addressing & Broadcasting

Every packet encapsulates a Sender_ID and a Receiver_ID allowing you to strictly route telemetry between multiple rockets and ground stations.

  • Set the Receiver_ID to 0xFF (which is mapped to Packet::BROADCAST_ID / Packet.BROADCAST_ID in Python) if you want all listening ground stations/nodes to process the packet.
  • When un-packing, use the builtin boolean check rx.is_targeted_to(YOUR_ID) to safely filter out noise intended for other modules!

Usage Guide (C++)

Include edlora.h and edlora.cpp in your ESP-IDF or Arduino project.

#include "edlora.h"

using namespace edlora;

void loop() {
    Packet tx_packet;
    tx_packet.sender_id = 0x10;
    tx_packet.receiver_id = 0xFF; // Broadcast
    tx_packet.msg_type = MsgType::GPS;
    tx_packet.seq_num = 1;

    // Option 1: Send raw bytes
    // tx_packet.payload_len = 4;
    // tx_packet.payload[0] = 0xDE;
    // tx_packet.payload[1] = 0xAD;
    // tx_packet.payload[2] = 0xBE;
    // tx_packet.payload[3] = 0xEF;

    // Option 2: Send strings effortlessly
    tx_packet.set_payload_string("Rocket Stage 1 separated!");

    // Optional Crypto:
    // crypto::XorCipher cipher(0xAA);
    // cipher.process(tx_packet);

    // Pack for transmission
    uint8_t tx_buffer[256];
    int packed_size = Protocol::pack(tx_packet, tx_buffer, sizeof(tx_buffer));

    if (packed_size > 0) {
        // Send tx_buffer[0 ... packed_size-1] over your LoRa modem
        // LoRa.beginPacket();
        // LoRa.write(tx_buffer, packed_size);
        // LoRa.endPacket();
    }
}

// Example: Receiving in C++
void receive_example(uint8_t* rx_buffer, size_t length) {
    Packet rx_packet;
    
    // Unpack incoming bytes
    if (Protocol::unpack(rx_buffer, length, rx_packet)) {
        char str_buffer[256];
        rx_packet.get_payload_string(str_buffer, sizeof(str_buffer));
        
        // Use your received data!
        // Serial.printf("Received string: %s\n", str_buffer);
    }
}

Usage Guide (Python)

from edlora import Packet, MsgType
from edlora_crypto import XorCipher

# Assume `rx_bytes` is the raw byte array received from Ground Station LoRa
rx_bytes = b'\xed\x10\xff\x01\x01\x04\xde\xad\xbe\xef\x00\xb1'

try:
    packet = Packet.unpack(rx_bytes)
    
    # Optional Crypto decoding:
    # cipher = XorCipher(0xAA)
    # packet = cipher.process(packet)
    
    # Retrieve raw bytes
    print(f"Payload (Bytes): {packet.payload}")
    
    # Retrieve as a decoded string
    print(f"Payload (String): {packet.get_payload_string()}")
except ValueError as e:
    print(f"Packet corrupted or rejected: {e}")


# Example: Unpacking specific message types
import struct
from edlora import Packet

p = Packet.unpack(rx_bytes) # Automatically validates sync byte and CRC16

# Extract targeted or broadcast addressing
is_for_me = p.is_targeted_to(0x01) 

if p.msg_type == MsgType.ALTIMETER:
    alt, vel = struct.unpack("<ff", p.payload)
    print(f"Altimeter: {alt}m, {vel}m/s")

Serial Monitor (CLI)

You can directly stream incoming data out of a physical LoRa module connected via USB using the cli_monitor.py example script. It fully handles framing raw serial bytes into complete Packets.

pip install pyserial
python3 examples/cli_monitor.py --port /dev/ttyUSB0 --baud 115200

Outputs formatted logs: [15:30:22.123] [0x10] [ALTIMETER] [BROADCAST] Altitude: 1500.5m, Velocity: 20.3m/s

Example: Transmitting from Python

tx_packet = Packet(
    sender_id=0xFF,   # Ground station ID
    receiver_id=0x10, # Rocket ID
    msg_type=MsgType.COMMAND,
    seq_num=42
)

tx_packet.set_payload_string("DEPLOY PARACHUTE")
bytes_to_send = tx_packet.pack()

# Send `bytes_to_send` over your serial/USB LoRa module!
# serial_port.write(bytes_to_send)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

edlora-1.1.1.tar.gz (5.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

edlora-1.1.1-py3-none-any.whl (6.1 kB view details)

Uploaded Python 3

File details

Details for the file edlora-1.1.1.tar.gz.

File metadata

  • Download URL: edlora-1.1.1.tar.gz
  • Upload date:
  • Size: 5.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for edlora-1.1.1.tar.gz
Algorithm Hash digest
SHA256 8ac3e61c3270bb98f2818768150b8890118ed174091f135cdeec1f4e2e9f1c89
MD5 79c4cc2f62475eaff39b7209b9da4907
BLAKE2b-256 c37d8085826abb4d0225c28cecbc9b54f6279d54fbf43d2ebf494339a5a05866

See more details on using hashes here.

File details

Details for the file edlora-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: edlora-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 6.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for edlora-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1ec6745cdbed4f5036572b10ec23fa2cc51917a430ee21296e2c8843cbf7a2e2
MD5 a3e3b880c8630a7a484d9f8f209be32f
BLAKE2b-256 ffe9724d13dd2bb060e93cb9e5e9c0d248c3bb4c7527c04b46a81303e4cf6e4d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page