Wir erstellen ein Gateway zwischen Wi-Fi und LoRa fĂŒr UDP

Ich hatte als Kind den Traum, jedem herkömmlichen "Nicht-WiFi"-GerÀt ein Ticket ins Netzwerk zu vergeben, d. h. eine IP-Adresse und einen Port. Nach einiger Zeit wurde mir klar, dass ich nicht lÀnger warten sollte. Ich muss es einfach tun.
Technisches Pflichtenheft
Ein Gateway mit dem M5Stack und dem installierten LoRa-Modul erstellen (siehe Abbildung 1). Das Gateway wird mit einem Wi-Fi-Netzwerk verbunden, wo es eine lokale IP-Adresse ĂŒber DHCP erhalten wird. In bestimmten Zeitintervallen wird das Gateway seinen Namen (analog zu SSID fĂŒr Wi-Fi) und den Bereich zulĂ€ssiger Ports in die "LoRa-Luft" senden, damit andere GerĂ€te wissen, dass es ein solches Netzwerk gibt, zu dem man sich verbinden kann, und in welchem Bereich man einen freien Port wĂ€hlen kann. Da dies ein Prototyp ist, erfolgt die Authentifizierung diesmal nicht. Neue Client-GerĂ€te werden das verfĂŒgbare LoRa-Netzwerk finden und ihm den gewĂ€hlten Port ĂŒbermitteln. Nachdem das Gateway den Port vom neuen Client erhalten hat, ĂŒberprĂŒft es, ob er frei ist; wenn ja, registriert es den neuen Client und beginnt, den angegebenen Port auf seinem eigenen asynchronen UDP-Server abzuhören. Nach der Registrierung erhĂ€lt der Client die Zustimmung oder Ablehnung zur Nutzung des angegebenen Ports. Der Ablauf ist in Tabelle 1 dargestellt.

Abb. 1
Tabelle 1
Seite
Richtung und Daten
Seite
Sitzung
[ client ]
<â Signal-Bake â
[ gateway ]
0xA1
[ client ]
â gewĂ€hlter Port â>
[ gateway ]
0xB1
[ client ]
<â Zustimmung oder Ablehnung â
[ gateway ]
0xA2
[ client ]
â UPD-Paket â>
[ gateway ]
0xB2
[ client ]
<â UPD-Paket â
[ gateway ]
0xA3
[ netz ]
<â UPD-Paket â
[ gateway ]
0xC1
Vor mir auf dem Tisch liegen verschiedene Module fĂŒr den M5Stack und langweilen sich. Lassen Sie uns LoRa nehmen und mit ihr SpaĂ haben. Das Konzept der Module ist groĂartig! Was soll man dazu sagen? Aber ich habe die Module der ersten Revision, bei denen die integrierte Antenne schrecklich ist; sie wurde auf einer flexiblen Leiterplatte gefertigt und an die Seitenwand des GehĂ€uses geklebt. Ich habe einmal Feldtests mit solchen Modulen durchgefĂŒhrt (Sie können auf dem russischsprachigen YouTube-Kanal nachsehen):

NatĂŒrlich musste ich diese Ăberbleibsel entfernen und standardmĂ€Ăige Spiralantennen einlöten, die mit dem Ra-01 geliefert werden. Nach dieser Anpassung hat sich die Reichweite der Verbindung deutlich verbessert, aber es gab einen Nebeneffekt â die Antenne hat einen gröĂeren Durchmesser als der zulĂ€ssige Abstand zwischen den Modulen. Ich musste vorĂŒbergehend auf das abschlieĂende Modul fĂŒr die Dauer des Projekts verzichten.
Die ersten Schwierigkeiten durch synchronen Widerstand
Man könnte meinen, man nimmt einfach die Bibliothek WiFiUdp.h, wo alles fĂŒr das komfortable Betreiben eines UDP-Servers vorhanden ist, ist das nicht der Fall. Die Bibliothek ist fĂŒr den Betrieb eines synchronen Servers ausgelegt, der, bedauerlicherweise, nicht in der Lage ist, mehrere Verbindungen gleichzeitig in einem Thread zu bedienen. Eine solche Bibliothek ist fĂŒr die aktuelle Aufgabe nicht geeignet. Es war erforderlich, viele Tassen Tee zu trinken und nach einer Bibliothek zu suchen, die es ermöglicht, einen asynchronen UDP-Server einzurichten, der mehrere Verbindungen gleichzeitig unterstĂŒtzen kann. Eine solche Bibliothek wurde gefunden â AsyncUDP.h. Was ist nun der Unterschied zwischen einem synchronen und einem asynchronen Server? Lassen Sie uns sechs Episoden in Abbildung 2 betrachten, in denen die Betriebsvarianten von Sockets trivial dargestellt sind.

Abbildung 2
In den Hauptrollen:
Person in der Rolle von Socket;
Taube in der Rolle von Verbindung;
Brief in der Rolle von Daten.
Episode A. Synchroner Socket ohne Timeout
Die Person steht da, bis die Taube ihr einen Brief bringt.
Episode B. Synchroner Socket mit Timeout
Die Person wartet die vereinbarte Zeit auf die Taube, und wenn sie nicht rechtzeitig kommt, wird die Person weggehen.
Episode C. Synchroner Socket mit Multithreading
Die Person faulenzt und beobachtet, wie die Tauben selbststÀndig Briefe liefern.
Episode D. Asynchroner Socket (wenn nichts zu empfangen ist)
Die Person beschÀftigt sich mit ihren LieblingsbeschÀftigungen, vergisst aber nicht die Tauben.
Episode E. Asynchroner Socket (wenn etwas zu empfangen ist)
Die Person hat sich kurz von ihren TĂ€tigkeiten abgelenkt, um einen Brief von der Taube zu empfangen.
Episode F. Asynchroner Socket mit Multithreading
Die Person kĂŒmmert sich um ihre Angelegenheiten und beobachtet, wie die Tauben selbststĂ€ndig Briefe liefern.
Wenn Sie aufmerksam waren, sollten Sie bemerkt haben, dass die HalsbÀnder der Tauben in jeder Episode eine bestimmte Farbe haben. Und das ist nicht zufÀllig. In den Episoden A und B funktioniert nur ein Socket auf dem Server. In Episode C sind bereits zwei Sockets aktiv. In den Episoden D, E und F sind es bereits drei Sockets. 'Warum sind da zwei und hier drei?', fragen Sie sich vielleicht. Das ist hypothetisch 2 und 3, tatsÀchlich kann anstelle von 2 auch 20 stehen und anstelle von drei 200. Die Aufgabe ist zu zeigen, dass asynchrone Sockets die Hardware nicht so stark belasten wie synchrone.
Wie viel Platz ist fĂŒr was?
Lassen Sie uns Tabelle 1 betrachten, die die Struktur eines UDP-Pakets zeigt, und darĂŒber nachdenken, was wir damit machen können.
Tabelle 1. Struktur eines UDP-Pakets
Bits
0 â 15
16 â 31
0-31
Quellport (Source port)
Zielport (Destination port)
32-63
LĂ€nge des Datagramms (Length)
PrĂŒfziffer (Checksum)
64-âŠ
Daten (Data)
Wir fĂŒgen am Anfang dieser Tabelle ein weiteres Feld hinzu. Sitzung (1 Byte). Das reicht fĂŒr dieses Projekt aus. Basierend auf der Sitzung weiĂ das GerĂ€t, was es mit dem Paket weiter tun soll. Jetzt erfinden wir Codes fĂŒr die Sitzungen und notieren sie in Tabelle 2.
Tabelle 2. ErlÀuterung zu den Sitzungen
Code
Bezeichnung
ErlÀuterung
0xA1
Beacon
Der Gateway sendet den Namen des LoRa-Netzwerks und den Bereich der zulĂ€ssigen Ports in regelmĂ€Ăigen AbstĂ€nden. Dies ist notwendig, damit neue Clients das verfĂŒgbare Netzwerk sehen können und aktuelle Clients, wenn keine Ăbertragungen stattfinden, den Signalpegel bestimmen können.
0xB1
Anfrage
Wenn der Client das Netzwerk gefunden hat, sendet er den gewĂŒnschten Port.
0xA2
Zustimmung oder Ablehnung
Wenn der vom Client angeforderte Port frei ist, antwortet der Server mit Zustimmung, andernfalls mit Ablehnung.
0xB2
Up-Link
Wenn der Client ein UDP-Paket an das Gateway ĂŒbertrĂ€gt.
0xA3
Down-Link
Wenn das Gateway ein UDP-Paket an den Client ĂŒbertrĂ€gt.
0xC1
Fortsetzung des Up-Links
Wenn das Gateway ein UDP-Paket in das lokale Netzwerk sendet.
Gut. Jetzt lassen Sie uns die Zusammensetzung der Sitzungen in Tabelle 3 besprechen.
Tabelle 3. Sitzungen
Name der Sitzung
Zusammensetzung
Beacon
Sitzungscode (1 Byte) + Name des LoRa-Netzwerks (4 Byte) + Startport (2 Byte) + Endport (2 Byte)
Anfrage
Ăbertragungscode (1 Byte) + Name des LoRa-Netzwerks (4 Byte) + Bevorzugter Port (2 Byte)
Zustimmung oder Ablehnung
Ăbertragungscode (1 Byte) + Name des LoRa-Netzwerks (4 Byte) + Bevorzugter Port (2 Byte) + Ergebnis (1 Byte)
Up-Link
Ăbertragungscode (1 Byte) + Name des LoRa-Netzwerks (4 Byte) + Remote-IP-Adresse (4 Byte) + Remote-Port (2 Byte) + Lokale-IP-Adresse (4 Byte) + Lokaler Port (2 Byte) + Datenmenge (2 Byte) + Daten
Down-Link
Ăbertragungscode (1 Byte) + Name des LoRa-Netzwerks (4 Byte) + Remote-IP-Adresse (4 Byte) + Remote-Port (2 Byte) + Lokale-IP-Adresse (4 Byte) + Lokaler Port (2 Byte) + Datenmenge (2 Byte) + Daten
Fortsetzung des Up-Links
Remote-IP-Adresse (4 Byte) + Remote-Port (2 Byte) + Datenmenge (2 Byte) + Daten
Ich habe zwei Clients fĂŒr Arduino und fĂŒr M5Stack geschrieben. Sie können sehen, wie es funktioniert. In der Wohnung gibt es keine Probleme, Feldtests habe ich noch nicht gemacht.
Der Quellcode ist auf GitHub verfĂŒgbar unter
Mehr ĂŒber das BasisgerĂ€t M5Stack erfahren und kaufen können Sie
Drahtlose LoRa-Module fĂŒr das BasisgerĂ€t auswĂ€hlen können Sie
Ich wĂŒrde mich freuen, wenn dieses Projekt Ihnen nĂŒtzlich sein wird. Vielen Dank fĂŒr Ihre Zeit!
Literaturverzeichnis und (oder) Quellen:
Quelle: habr.com
