sudomesh / disaster-radio

A (paused) work-in-progress long-range, low-bandwidth wireless disaster recovery mesh network powered by the sun.
https://disaster.radio
1.04k stars 110 forks source link

Documentation on LoRa parameters + LoStik example code #50

Open tlrobinson opened 4 years ago

tlrobinson commented 4 years ago

I have a LoStik and took some time to figure out how to get it to receive disaster-radio messages (and parse them). I figured this might be useful to someone, so maybe it could be added to the Wiki.

The important part is these commands to configure the RN2903 chip to match what disaster-radio does. I'm not sure if these are all documented for disaster radio anywhere:

Command Description
radio set mod lora LoRa mode
radio set freq 915000000 Frequency 915Mhz
radio set bw 125 Bandwidth 125Khz
radio set sf sf9 Spreading factor 9
radio set sync 12 Sync word 0x12
radio set cr 4/6 Coding rate 4/6
radio set crc off CRC off
radio set prlen 12 Preamble length 12

Here's the complete code, forked from LoStik's radio_receiver.py example:

#!/usr/bin/env python3
import time
import sys
import serial
import argparse 

from serial.threaded import LineReader, ReaderThread

parser = argparse.ArgumentParser(description='LoRa Radio mode receiver.')
parser.add_argument('port', help="Serial port descriptor")
args = parser.parse_args()

class PrintLines(LineReader):

    def connection_made(self, transport):
        print("listening for disaster.radio messages")
        self.transport = transport
        self.send_cmd('sys get ver')

        self.send_cmd('mac pause')
        self.send_cmd('radio set pwr 10')

        # these are the commands needed for compatibility with disaster.radio
        self.send_cmd('radio set mod lora')
        self.send_cmd('radio set freq 915000000')
        self.send_cmd('radio set sf sf9')
        self.send_cmd('radio set sync 12')
        self.send_cmd('radio set cr 4/6')
        self.send_cmd('radio set bw 125')
        self.send_cmd('radio set crc off')

        self.send_cmd('radio rx 0')
        self.send_cmd("sys set pindig GPIO10 0")

    def handle_line(self, data):
        if data == "ok" or data == 'busy':
            return
        if data == "radio_err":
            self.send_cmd('radio rx 0')
            return

        self.send_cmd("sys set pindig GPIO10 1", delay=0)

        command, *body = data.split("  ")
        if command == "radio_rx" and len(body) > 0:
            message = bytes.fromhex(body[0])
            l2_message = {
                "ttl":  message[0],
                "len":  message[1],
                "src":  message[2:8],
                "dst":  message[8:14],
                "seq":  message[14],
                "type": message[15],
                "data": message[16:]
            }
            print(l2_message)
            if l2_message["type"] == 99:
                diaster_message = {
                    "id": l2_message["data"][0:2],
                    "type": l2_message["data"][2],
                    "data": l2_message["data"][4:]
                }
                print(diaster_message)

        time.sleep(.1)
        self.send_cmd("sys set pindig GPIO10 0", delay=1)
        self.send_cmd('radio rx 0')

    def connection_lost(self, exc):
        if exc:
            print(exc)
        print("port closed")

    def send_cmd(self, cmd, delay=.5):
        self.transport.write(('%s\r\n' % cmd).encode('UTF-8'))
        time.sleep(delay)

ser = serial.Serial(args.port, baudrate=57600)
with ReaderThread(ser, PrintLines) as protocol:
    while(1):
        pass
tlrobinson commented 4 years ago

Heh, I just found the LoRa library’s defaults listed here which would have made figuring this out a little easier https://github.com/sandeepmistry/arduino-LoRa/blob/master/API.md#radio-parameters

spattinson commented 4 years ago

I am figuring out the lora parameters for ESP32. I have 2s TTGO T-Beams with sx1278 so they are 433Mhz. So I need to change from the default 915Mhz. It seems to be defined in .pio/libdeps/ttgo-lora32-tbeam/LoRaLayer2/src/Layer1_LoRa.cpp. I cant find the bandwidth being defined anywhere though and that greatly affects speed vs range tradeoff. In my initial experiments using an example from a different lora library (https://github.com/LoRaTracker/SX12XX-LoRa) I need to set 31250hz to get any sort of reasonable range in an urban env. Its quite slow but works across the town - spreading 12, code rate 4/6, and LDRO. The antennas supplied with the units may be part of the issue, they are about 45mm long.

samuk commented 4 years ago

Have a look at https://github.com/sudomesh/disaster-radio/issues/43#issuecomment-576314978

This should be edited: https://github.com/sudomesh/disaster-radio/blob/master/firmware/esp32/main.ino#L280

spattinson commented 4 years ago

Thats better than what I did modifying the library.Thanks