This weekend we used the Meshtastic Python API to perform some basic range tests of the Meshtastic LoRa mesh networking communications system, around the lake at Newfound Lake in Bristol, NH.
Heltec widget set up as a automated Meshtastic LoRa mesh 'base station' node in a cabin on a lake. It's run by a Mesthastic-python script that replies to any messages sent to it with the SNR of the incoming message. |
The goal was to test ‘hop’ dynamics with a system of 3 Meshtastic nodes, by first setting up a ‘base station sender’ and a ‘target receiver’ on opposite sides of a hill that blocks direct LoRa transmission; and then placing a ‘relay’ node on the ‘corner’ of that hill, so that messages might ‘hop’ around it.
The ‘sender’ was located in a cabin on a lake, and was controlled by Meshtastic-python, using a script (linked to in the above post) that would ‘reply’ to received messages with the SNR of the incoming message. The idea was that from the field I could send messages from my ‘end node’ (controlled via the Android app), and if the ‘relay’ node was able to relay my message via a ‘hop’ to the ‘base station sender’, I might ultimately get a reply relayed back to me at the end node.
I was able to nicely communicate among all the nodes directly; but in my quick test wasn’t able to accomplish a ‘hop’. Not yet sure why, but my test was a bit goofy and rushed, so I might have been doing something dumb. The ‘hop_limit’ parameter seems to have been set to ‘1’ – which should allow a single hop beyond the immediately adjacent nodes, from what I understand ... need to dig in further.
Below are some hastily-assembled data and scripts; will hope to organize this into a narrative account ASAP.
A link to some of the Meshtastic-Python scripts we played with is here.
import meshtastic
import time
from pubsub import pub
def onReceive(packet): # called when a packet arrives
print(f"Received: {packet}")
if packet['decoded']['data'] is not None:
msg = packet['decoded']['data']['text']
rxSnr = packet['rxSnr']
hopLimit = packet['hopLimit']
print(f"message: {msg}")
reply="got msg \'{}\' with rxSnr: {} and hopLimit: {}".format(msg,rxSnr,hopLimit)
print("Sending reply: ",reply)
interface.sendText(reply)
def onConnection(): # called when we (re)connect to the radio
# defaults to broadcast, specify a destination ID if you wish
interface.sendText("hello mesh")
pub.subscribe(onReceive, "meshtastic.receive")
pub.subscribe(onConnection, "meshtastic.connection.established")
interface = meshtastic.StreamInterface()
Received: {'from': 3520888364, 'to': 4294967295, 'decoded': {'data': {'typ': 'CLEAR_TEXT', 'payload': 'dGVzdDc=', 'text': 'test7'}}, 'id': 2204634416, 'rxSnr': 3.0, 'hopLimit': 1, 'fromId': None, 'toId': '^all'}
message: test7
Sending reply: got msg 'test7' with rxSnr: 3.0 and hopLimit: 1