Dies ist eine Sammlung von Python -Skripten (2 erledigt, weiterentwickelt, noch mehr) und andere Informationen über das RAK3272S -Breakout -Board. Im Moment kommt es mit einer Firmware. Da es sich bei dem STM32WL um einen neuen Chip handelt, ist es ein bisschen kompliziert, eine Umgebung für den Schreiben von C ++-Code dafür einrichten (ich habe einen Blick auf STM32Cubeides, und ich bin immer noch schwindelig vom tiefen Tauchgang ...). Ich konzentriere mich jedoch auf das Schreiben von Code, die die AT-Firmware ein wenig schmerzhafter und weniger benutzerfreundlicher machen.
Das STM32WL wurde dem STM32 Arduino BSP, ohne den Lora -Teil, hinzugefügt. Sobald Lora verfügbar ist, werde ich meine minimale Lora -Firmware auf diesen Chip portieren, und wir können etwas weniger Kludgy verwenden. Dazwischen werde ich an Werkzeugen arbeiten, die das Verhalten von minimaler Lora nachahmen.
Es gibt 2 Skripte, die jeweils nur eines tun: Empfangen oder Senden. Die Art und Weise, wie die AT -Firmware für P2P eingerichtet ist, ist es etwas kompliziert, beides zu haben. Grundsätzlich stellt die Firmware den Chip in den TX -Modus ein, und wenn Sie empfangen möchten, müssen Sie die Firmware wissen lassen und einen Zeitüberschreitungswert geben (dumme Idee, wenn Sie mich fragen). Es ist ein 16-Bit-Wert, also bedeutet der maximale Wert, 65535, für immer warten. Alles andere wartet so viel Millisekunden. Pfffrt. Aber was noch schlimmer ist, selbst wenn Sie im Modus "Wait Ewn Wait Wait ewig" sind, wenn Sie eine Zeile erhalten, sind Sie wieder im TX -Modus. Das ist ungewöhnliche Grausamkeit.
Also hatte ich zwei Breakout -Boards und jeder war mit einem Computer verbunden, der ein Skript ausführte. Beim Start stellt das Skript die Firmware in den P2P -Modus ein, legt Parameter (Frequenz, SF, BW usw.) und legt den TX- oder RX -Modus fest. Der Empfänger setzt bei jedem Empfangsmodus zurück, wenn eine Nachricht empfangen wird.
Da diese 2 in demselben Netzwerk von Bastwan -Geräten arbeiten, die ich habe, muss ich das Protokoll nachahmen:
UUID , from und cmd -Schlüssel. Danach kann es andere Schlüssel geben oder nicht. Der Absender fügt nichts anderes hinzu, aber einige meiner Bastwan -Geräte tun es. Der Empfänger weiß, was er anzeigen soll. Außerdem werden die Pakete Zeitstempel, sodass Sie ein Protokoll mit Paketen aufbewahren können.Alles in allem tun sie schon ziemlich viel. Ich möchte sie verschmelzen und mehr Optionen für minimal_lora hinzufügen. Eine robustere Lösung könnte darin bestehen, eine GUI -App in Xojo zu erstellen. Wir werden sehen ...

Ich habe ein neues Skript hinzugefügt, RAK3272S_Minimal_LoRa.py , das die BastWAN_Minimal_LoRa -Firmware nachahmt, und ich hatte mehr Probleme mit SF/BW -Kombinationen im Zusammenhang mit Nutzlasten. Bei SF 10, BW 7 (125 kHz), werden von Bastwan -Geräten, sowohl Bastwan als auch RAK3272s, empfangen. Auf der anderen Seite werden von RAK3272 gesendete Pakete von Bastwan -Geräten überhaupt nicht empfangen und auf anderen RAK3272 verstümmelt. Wenn ich nach meinem SDR nachschaue, wird tatsächlich etwas gesendet, aber die Bastwan -Geräte reagieren nicht einmal darauf. Ich denke, entweder die AT -Firmware oder die Hardware selbst ist viel strenger als nötig, wenn es um Nutzlastbeschränkungen geht: Wenn die RAK3272 -Nutzlasten lange (~ 180 Bytes) erhalten können, sollte es sie auch senden können (und sie waren etwas kürzer, etwa 160 Bytes).
Während ich mich mit dem Produktteam überlegt habe, habe ich die SF/BW -Kombination in SF 10, BW 9 (500 kHz) geändert und lange Pakete funktionieren jetzt gut. SF 9, BW 7 scheint ebenfalls zu funktionieren. Ich füge verschiedene JSON -PREFS -Dateien zum Testen hinzu. Sie können beim Start eine PREFS -Datei auswählen, indem Sie:
python3 RAK3272S_Minimal_LoRa.py /dev/tty.usbserial-A901LHDG sf9bw7.json
Ich habe ein paar Befehle von minimal_lora hinzugefügt:
knownFunctions = [
[ "/p" , sendPing , 0 ], [ "/>" , sendMsg , 1 ], [ "/hm" , setHmac , 1 ],
[ "/cr" , setCr , 1 ], [ "/tx" , setTx , 1 ], [ "/bw" , setBw , 1 ],
[ "/sf" , setSf , 1 ], [ "/r" , setRP , 1 ], [ "/fq" , setFq , 1 ],
[ "/as" , setAs , 1 ], [ "/e" , setEnc , 1 ], [ "/dn" , setDeviceName , 1 ],
[ "/PW" , setPwd , 1 ], [ "/save" , savePrefs , 0 ], [ "/msl" , sendMSL , 1 ],
[ "/gps" , setGPS , 1 ], [ "/help" , showHelp , 0 ]
]Das ist immer noch ein bisschen zerbrechlich, scheint aber gut genug zu funktionieren! Viel Spaß!


Eine calcMaxPayload() -Funktion hinzugefügt, die die maximale Nutzlast berechnet, die Sie basierend auf der SF/BW -Konfiguration senden können. Gibt -1 zurück, wenn (angeblich sowieso) ungültig. Daten aus TTN. Diese Berechnung wird beim Aufrufen packOptions() angezeigt, dh beim Zurücksetzen der Optionen für den Chip.
Ich habe den Teil des Codes neu übernommen, der die Benutzereingabe analysiert und die Befehle bewertet. Die Befehle, die relevante FN, und ob sie ein Argument benötigen oder nicht, werden in einem Array gespeichert, knownFunctions . Eine Funktion, testFn(line) , analysiert das Array und nennt die relevante Funktion, wenn es eine Übereinstimmung findet. Dies erleichtert es viel einfacher, Befehle hinzuzufügen.
knownFunctions = [
# Updated list as of 2021/08/05
[ "/p" , sendPing , 0 ], [ "/>" , sendMsg , 1 ], [ "/hm" , setHmac , 1 ],
[ "/cr" , setCr , 1 ], [ "/tx" , setTx , 1 ], [ "/bw" , setBw , 1 ],
[ "/sf" , setSf , 1 ], [ "/r" , setRP , 1 ], [ "/fq" , setFq , 1 ],
[ "/as" , setAs , 1 ], [ "/e" , setEnc , 1 ], [ "/dn" , setDeviceName , 1 ],
[ "/PW" , setPwd , 1 ], [ "/save" , savePrefs , 0 ]
]
def testFn ( line ):
# This function takes one line from user input
# And looks for a know command (see above)
# If the command requires no arguments, 3rd value
# in the array is 0, and the Fn is called as is.
# Or the remainder of the line is passed as argument.
# eg:
# '/p' PING, no argument need. ["/p", sendPing, 0]
# '/fq' Set Frequency, frequency needs to be passed: ["/fq", setFq, 1]
global knownFunctions
for x in knownFunctions :
if line . startswith ( x [ 0 ]):
if x [ 2 ] == 0 :
x [ 1 ]()
else :
param = line [ len ( x [ 0 ]):]
x [ 1 ]( param )
return
print ( "Unknown command!" )Ich habe ein paar Befehle hinzugefügt:
/e0 ~ /e1 schaltet die AES aus oder auf/PWxxxxxx legt das Kennwort auf xxxx fest/dnxxxxxx legt den Gerätenamen auf xxxx fest/save speichert PreFs in der aktuellen PREFS -Datei 

Abgenommen die serial.SerialException , als er versuchte, einen nicht existierenden Port zu öffnen. Der Code existiert viel sauberer.

Portierte meine C ++ hexDump() -Funktion mit Python, um Pakete in Hex -Form für Debug -Zwecke zu zeigen. Nur während sendPacket() angerufen, sollte aber später an einigen anderen Orten hinzugefügt werden. Schließlich wird es mit einem #DEBUG -ähnlichen Define optional gemacht.
Die Funktion wurde aktualisiert, um Puffer lange als 256 Bytes zu ermöglichen.


Ich habe Protokolle hinzugefügt: Hauptereignisse (Voraussetzungen speichern, Pakete senden/empfangen) werden an einer neuen Protokolldatei angemeldet, die zum Startzeit von einem zufälligen UUID erstellt wurde: Log_<UUID>.log . Ich werde diese Funktionalität optional, aber im Moment, während ich teste, werde ich sie anlassen.

Ich habe weitere Befehle hinzugefügt, einschließlich /help und gps . Dies spiegelt sich auch in den Vorlieben wider, in denen die GPS -Position gespeichert wird, wenn sie manuell über den Befehl /gps hinzugefügt wird. JSON -Schlüsselwort addGPS . Wie unten gezeigt, enthält die Befehle /help eine Erklärung der Befehle (die __doc__ -Eigenschaft jeder Funktion).
knownFunctions = [
[ "/p" , sendPing , 0 ], [ "/>" , sendMsg , 1 ], [ "/hm" , setHmac , 1 ],
[ "/cr" , setCr , 1 ], [ "/tx" , setTx , 1 ], [ "/bw" , setBw , 1 ],
[ "/sf" , setSf , 1 ], [ "/r" , setRP , 1 ], [ "/fq" , setFq , 1 ],
[ "/as" , setAs , 1 ], [ "/e" , setEnc , 1 ], [ "/dn" , setDeviceName , 1 ],
[ "/PW" , setPwd , 1 ], [ "/save" , savePrefs , 0 ], [ "/msl" , sendMSL , 1 ],
[ "/gps" , setGPS , 1 ], [ "/help" , showHelp , 0 ]
] Hier ist die Ausgabe des Befehls /help :
/help
/p: Sends a ping packet. 0 args
/>: Sends a custom packet (message). 1 args
/hm: Sets HMAC parameter (0/1). 1 args
/cr: Sets C/R parameter (5..8). 1 args
/tx: Sets Tx power (7..22). 1 args
/bw: Sets bandwidth parameter (7..9). 1 args
/sf: Sets spreading factor parameter (6..12). 1 args
/r: Sets pong back parameter (0/1). 1 args
/fq: Sets LoRa frequency. 1 args
/as: Sets autosend parameter (0/XX seconds). 1 args
/e: Sets AES encryption parameter (0/1). 1 args
/dn: Sets device name. 1 args
/PW: Sets AES encryption key. 1 args
/save: Saves preferences to disk. 0 args
/msl: Sets Mean Sea Level air pressure (dor altitude calculation). 1 args
/gps: Sets GPS coords (or turns off GPS location). 1 args
/help: Shows this help. 0 args
