Documentation on LoRa parameters + LoStik example code
tlrobinson opened this issue · 4 comments
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
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
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.
Have a look at #43 (comment)
This should be edited:
https://github.com/sudomesh/disaster-radio/blob/master/firmware/esp32/main.ino#L280
Thats better than what I did modifying the library.Thanks