Inhaltsverzeichnis:

LoRa 3Km bis 8Km Drahtlose Kommunikation mit kostengünstigem E32 (sx1278/sx1276) Gerät für Arduino, Esp8266 oder Esp32 - Gunook
LoRa 3Km bis 8Km Drahtlose Kommunikation mit kostengünstigem E32 (sx1278/sx1276) Gerät für Arduino, Esp8266 oder Esp32 - Gunook

Video: LoRa 3Km bis 8Km Drahtlose Kommunikation mit kostengünstigem E32 (sx1278/sx1276) Gerät für Arduino, Esp8266 oder Esp32 - Gunook

Video: LoRa 3Km bis 8Km Drahtlose Kommunikation mit kostengünstigem E32 (sx1278/sx1276) Gerät für Arduino, Esp8266 oder Esp32 - Gunook
Video: LORA & El Internet de las Cosas" IOT .Capitulo 01 2024, Juli
Anonim
LoRa 3 km bis 8 km drahtlose Kommunikation mit kostengünstigem E32-Gerät (sx1278/sx1276) für Arduino, Esp8266 oder Esp32
LoRa 3 km bis 8 km drahtlose Kommunikation mit kostengünstigem E32-Gerät (sx1278/sx1276) für Arduino, Esp8266 oder Esp32

Ich erstelle eine Bibliothek zur Verwaltung von EBYTE E32 basierend auf der Semtech-Serie von LoRa-Geräten, einem sehr leistungsstarken, einfachen und billigen Gerät.

Sie finden die 3Km-Version hier, die 8Km-Version hier

Sie können über eine Entfernung von 3000 m bis 8000 m arbeiten und haben viele Funktionen und Parameter. Also erstelle ich diese Bibliothek, um die Verwendung zu vereinfachen.

Es ist eine Lösung zum Abrufen von Daten von städtischen Sensoren oder zur Steuerung von Drohnen.

Lieferungen

Arduino UNO

Wemos D1 mini

LoRa E32 TTL 100 3Km-Version

LoRa E32 TTL 1W 8Km-Version

Schritt 1: Bibliothek

Bücherei
Bücherei

Hier finden Sie meine Bibliothek.

Herunterladen.

Klicken Sie oben rechts auf die Schaltfläche DOWNLOADS, benennen Sie den unkomprimierten Ordner LoRa_E32 um.

Überprüfen Sie, ob der Ordner LoRa_E32 LoRa_E32.cpp und LoRa_E32.h enthält.

Platzieren Sie den LoRa_E32-Bibliotheksordner in Ihrem /libraries/-Ordner. Möglicherweise müssen Sie den Unterordner Bibliotheken erstellen, wenn es sich um Ihre erste Bibliothek handelt.

Starten Sie die IDE neu.

Schritt 2: Pinbelegung

Pinbelegung
Pinbelegung
Pinbelegung
Pinbelegung
Pinbelegung
Pinbelegung

Wie Sie sehen, können Sie über die Pins M0 und M1 verschiedene Modi einstellen.

Es gibt einige Pins, die statisch verwendet werden können, aber wenn Sie es mit dem Mikrocontroller verbinden und sie in der Bibliothek konfigurieren, gewinnen Sie an Leistung und Sie können alle Modi per Software steuern, aber als nächstes werden wir es besser erklären.

Schritt 3: AUX-Pin

AUX-Pin
AUX-Pin
AUX-Pin
AUX-Pin
AUX-Pin
AUX-Pin

Wie ich bereits sagte, ist es nicht wichtig, alle Pins mit dem Ausgang des Mikrocontrollers zu verbinden. Sie können die Pins M0 und M1 auf HIGH oder LOW setzen, um die gewünschte Konfiguration zu erhalten dass die Operation abgeschlossen ist.

AUX-Pin

Beim Übertragen von Daten kann die externe MCU aufgeweckt und nach Abschluss der Datenübertragung HIGH zurückgegeben werden.

Beim Empfang von AUX wird LOW und HIGH zurückgegeben, wenn der Puffer leer ist.

Es wird auch für die Selbstprüfung verwendet, um den normalen Betrieb wiederherzustellen (beim Einschalten und im Schlaf-/Programmmodus).

Schritt 4: Vollständig verbundenes Schema Esp8266

Vollständig verbundenes Schema Esp8266
Vollständig verbundenes Schema Esp8266
Vollständig verbundenes Schema Esp8266
Vollständig verbundenes Schema Esp8266

esp8266 Verbindungsschema ist einfacher, weil es mit der gleichen Spannung der logischen Kommunikation (3,3 V) arbeitet.

Es ist wichtig, einen Pull-up-Widerstand (4, 7Kohm) hinzuzufügen, um eine gute Stabilität zu erzielen.

Schritt 5: Vollständig verbundenes Schema Arduino

Vollständig verbundenes Schema Arduino
Vollständig verbundenes Schema Arduino
Vollständig verbundenes Schema Arduino
Vollständig verbundenes Schema Arduino

Die Arduino-Arbeitsspannung beträgt 5 V, daher müssen wir einen Spannungsteiler an RX-Pin M0 und M1 des LoRa-Moduls hinzufügen, um Schäden zu vermeiden. Weitere Informationen finden Sie hier Spannungsteiler: Rechner und Anwendung.

Sie können einen 2Kohm-Widerstand gegen GND und 1Kohm vom Signal verwenden, als auf RX zusammengesetzt.

Schritt 6: Bibliothek: Konstruktor

Ich habe eine Reihe von ziemlich zahlreichen Konstruktoren erstellt, weil wir mehr Optionen und Situationen zu verwalten haben.

LoRa_E32 (Byte rxPin, Byte txPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

LoRa_E32 (Byte rxPin, Byte txPin, Byte AuxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600); LoRa_E32 (Byte rxPin, Byte txPin, Byte AuxPin, Byte m0Pin, Byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

Der erste Satz von Konstruktoren wird erstellt, um die Verwaltung von seriellen und anderen Pins an die Bibliothek zu delegieren.

rxPin und txPin ist der Pin zum Verbinden mit UART und sie sind obligatorisch.

auxPin ist ein Pin, der den Betriebs-, Sende- und Empfangsstatus überprüft (wir werden es als nächstes besser erklären), dieser Pin Es ist nicht obligatorisch, wenn Sie es nicht setzen, wende ich eine Verzögerung an, damit der Vorgang von selbst abgeschlossen werden kann (mit Latenz).

m0pin und m1Pin sind die Pins zum Ändern des Betriebsmodus (siehe Tabelle oben). Ich denke, diese Pins in "Produktion" werden direkt HIGH oder LOW verbinden, aber zum Testen sind sie sinnvollerweise von der Bibliothek zu verwalten.

bpsRate ist die Baudrate von SoftwareSerial ist normalerweise 9600 (die einzige Baudrate im Programmier-/Schlafmodus)

Ein einfaches Beispiel ist

#include "LoRa_E32.h"LoRa_E32 e32ttl100(2, 3); // RX, TX // LoRa_E32 e32ttl100 (2, 3, 5, 6, 7); // RX, TX

Wir können direkt eine SoftwareSerial mit einem anderen Konstruktor verwenden

LoRa_E32 (HardwareSerial* seriell, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

LoRa_E32 (HardwareSerial* seriell, Byte AuxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

LoRa_E32 (HardwareSerial* seriell, Byte auxPin, Byte m0Pin, Byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

Das obere Beispiel mit diesem Konstruktor kann so gemacht werden.

#include #include "LoRa_E32.h"

SoftwareSerial mySerial(2, 3); // RX, TX

LoRa_E32 e32ttl100(&mySerial);

// LoRa_E32 e32ttl100(&mySerial, 5, 7, 6);

Der letzte Satz von Konstruktoren erlaubt die Verwendung einer HardwareSerial anstelle von SoftwareSerial.

LoRa_E32 (SoftwareSerial* seriell, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

LoRa_E32 (SoftwareSerial* seriell, Byte AuxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

LoRa_E32 (SoftwareSerial* seriell, Byte auxPin, Byte m0Pin, Byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

Schritt 7: Beginnen Sie

Der Befehl begin wird verwendet, um Serial und Pins im Eingabe- und Ausgabemodus zu starten.

Leerer Anfang ();

in Ausführung ist

// Alle Pins und UART starten

e32ttl100.begin();

Schritt 8: Konfigurations- und Informationsmethode

Es gibt eine Reihe von Methoden zum Verwalten der Konfiguration und zum Abrufen von Informationen über das Gerät.

ResponseStructContainer getConfiguration();

ResponseStatus setConfiguration(Konfigurationskonfiguration, PROGRAM_COMMAND saveType = WRITE_CFG_PWR_DWN_LOSE);

ResponseStructContainer getModuleInformation();

void printParameters(struct Konfigurationskonfiguration);

AntwortStatus resetModule();

Schritt 9: Antwortcontainer

Um die Verwaltung von Antworten zu vereinfachen, erstelle ich eine Reihe von Containern, die für mich sehr nützlich sind, um Fehler zu verwalten und generische Daten zurückzugeben.

Antwortstatus

Dies ist ein Statuscontainer und hat 2 einfache Einstiegspunkte, mit denen Sie den Statuscode und die Beschreibung des Statuscodes erhalten können

Serial.println (c.getResponseDescription()); // Beschreibung des Codes

Serial.println (c.code); // 1 wenn Erfolg

Der Code ist

ERFOLG = 1, ERR_UNKNOWN, ERR_NOT_SUPPORT, ERR_NOT_IMPLEMENT, ERR_NOT_INITIAL, ERR_INVALID_PARAM, ERR_DATA_SIZE_NOT_MATCH, ERR_BUF_TOO_SMALL, ERR_TIMEOUT, ERR_HARDWARE, ERR_HEAD_NOT_RECOGNIZED

AntwortContainer

Dieser Container wird erstellt, um die String-Antwort zu verwalten und hat 2 Einstiegspunkte.

data mit der von message zurückgegebenen Zeichenfolge und status eine Instanz von RepsonseStatus.

AntwortContainer rs = e32ttl.receiveMessage();

String-Nachricht = rs.data;

Serial.println (rs.status.getResponseDescription());

Serial.println (Nachricht);

ResponseStructContainer

Dies ist der „komplexere“Container. Ich verwende ihn, um die Struktur zu verwalten.

ResponseStructContainer c;

c = e32ttl100.getConfiguration(); // Es ist wichtig, den Konfigurationszeiger vor allen anderen Operationen zu erhalten

Konfigurationskonfiguration = *(Konfiguration*) c.data;

Serial.println (c.status.getResponseDescription());

Serial.println (c.status.code);

getConfiguration und setConfiguration

Die erste Methode ist getConfiguration, mit der Sie alle auf dem Gerät gespeicherten Daten abrufen können.

ResponseStructContainer getConfiguration();

Hier ein Anwendungsbeispiel.

ResponseStructContainer c;

c = e32ttl100.getConfiguration(); // Es ist wichtig, den Konfigurationszeiger vor allen anderen Operationen zu erhalten

Konfigurationskonfiguration = *(Konfiguration*) c.data;

Serial.println (c.status.getResponseDescription());

Serial.println (c.status.code);

Serial.println (configuration. SPED.getUARTBaudRate());

Struktur der Konfiguration haben alle Daten der Einstellungen, und ich füge eine Reihe von Funktionen hinzu, um alle Beschreibungen der einzelnen Daten zu erhalten.

Konfiguration. ADDL = 0x0; // Erster Teil der Adresskonfiguration. ADDH = 0x1; // Zweiter Teil der Adresskonfiguration. CHAN = 0x19;// Kanalkonfiguration. OPTION.fec = FEC_0_OFF; // Forward Error Correction Switch configuration. OPTION.fixedTransmission = FT_TRANSPARENT_TRANSMISSION; // Übertragungsmodus-Konfiguration. OPTION.ioDriveMode = IO_D_MODE_PUSH_PULLS_PULL_UPS; // Pullup-Verwaltungskonfiguration. OPTION.transmissionPower = POWER_17; // dBm Sendeleistungskonfiguration. OPTION.wirelessWakeupTime = WAKE_UP_1250; // Wartezeit für Aufweckkonfiguration. SPED.airDataRate = AIR_DATA_RATE_011_48; // Konfiguration der Luftdatenrate. SPED.uartBaudRate = UART_BPS_115200; // Konfiguration der Kommunikationsbaudrate. SPED.uartParity = MODE_00_8N1; // Paritätsbit

Sie haben die entsprechende Funktion für alle Attribute, um alle Beschreibungen zu erhalten:

Serial.print (F ("Chan:")); Serial.print (Konfiguration. CHAN, DEC); Serial.print(" -> "); Serial.println (configuration.getChannelDescription ()); Serial.println (F (" ")); Serial.print (F ("SpeedParityBit: ")); Serial.print (configuration. SPED.uartParity, BIN); Serial.print (" -> "); Serial.println (configuration. SPED.getUARTParityDescription()); Serial.print (F ("SpeedUARTDatte: ")); Serial.print (configuration. SPED.uartBaudRate, BIN); Serial.print (" -> "); Serial.println (configuration. SPED.getUARTBaudRate()); Serial.print (F ("SpeedAirDataRate: ")); Serial.print (configuration. SPED.airDataRate, BIN); Serial.print (" -> "); Serial.println (configuration. SPED.getAirDataRate()); Serial.print (F ("OptionTrans: ")); Serial.print (configuration. OPTION.fixedTransmission, BIN); Serial.print(" -> "); Serial.println (configuration. OPTION.getFixedTransmissionDescription()); Serial.print (F("OptionPullup:")); Serial.print (configuration. OPTION.ioDriveMode, BIN); Serial.print (" -> "); Serial.println (configuration. OPTION.getIODroveModeDescription()); Serial.print (F ("OptionWakeup: ")); Serial.print (configuration. OPTION.wirelessWakeupTime, BIN); Serial.print (" -> "); Serial.println (configuration. OPTION.getWirelessWakeUPTimeDescription()); Serial.print (F("OptionFEC:")); Serial.print (configuration. OPTION.fec, BIN); Serial.print (" -> "); Serial.println (configuration. OPTION.getFECDescription()); Serial.print (F("OptionPower:")); Serial.print (configuration. OPTION.transmissionPower, BIN); Serial.print (" -> "); Serial.println (configuration. OPTION.getTransmissionPowerDescription());

Auf die gleiche Weise möchte setConfiguration eine Konfigurationsstruktur, daher denke ich, dass der bessere Weg, die Konfiguration zu verwalten, darin besteht, die aktuelle abzurufen, die einzige Änderung vorzunehmen, die Sie benötigen, und sie erneut festzulegen.

ResponseStatus setConfiguration(Konfigurationskonfiguration, PROGRAM_COMMAND saveType = WRITE_CFG_PWR_DWN_LOSE);

Konfiguration ist die Struktur vorher anzuzeigen, saveType erlaubt Ihnen zu wählen, ob die Änderung nur für die aktuelle Sitzung dauerhaft wirksam wird.

ResponseStructContainer c;c = e32ttl100.getConfiguration(); // Es ist wichtig, den Konfigurationszeiger vor allen anderen Operationen zu erhalten Configuration configuration = *(Configuration*) c.data; Serial.println (c.status.getResponseDescription()); Serial.println (c.status.code); printParameters(Konfiguration); Konfiguration. ADDL = 0x0; Konfiguration. ADDH = 0x1; Konfiguration. CHAN = 0x19; configuration. OPTION.fec = FEC_0_OFF; configuration. OPTION.fixedTransmission = FT_TRANSPARENT_TRANSMISSION; configuration. OPTION.ioDriveMode = IO_D_MODE_PUSH_PULLS_PULL_UPS; configuration. OPTION.transmissionPower = POWER_17; configuration. OPTION.wirelessWakeupTime = WAKE_UP_1250; configuration. SPED.airDataRate = AIR_DATA_RATE_011_48; configuration. SPED.uartBaudRate = UART_BPS_115200; configuration. SPED.uartParity = MODE_00_8N1; // Konfiguration geändert und so eingestellt, dass die Konfiguration nicht gehalten wird ResponseStatus rs = e32ttl100.setConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE); Serial.println (rs.getResponseDescription()); Serial.println (rs.code); printParameters(Konfiguration);

Die Parameter werden alle als Konstante verwaltet:

Schritt 10: Basiskonfigurationsoption

Basiskonfigurationsoption
Basiskonfigurationsoption

Schritt 11: Empfangsnachricht senden

Zuerst müssen wir eine einfache, aber nützliche Methode einführen, um zu überprüfen, ob sich etwas im Empfangspuffer befindet

int verfügbar();

Es gibt einfach zurück, wie viele Bytes Sie im aktuellen Stream haben.

Schritt 12: Normaler Übertragungsmodus

Normaler Übertragungsmodus
Normaler Übertragungsmodus

Der normale/transparente Übertragungsmodus wird verwendet, um Nachrichten an alle Geräte mit derselben Adresse und demselben Kanal zu senden.

Es gibt viele Methoden zum Senden/Empfangen von Nachrichten, die wir im Detail erklären werden:

ResponseStatus sendMessage(const String Nachricht);

AntwortContainer receiveMessage();

Die erste Methode ist sendMessage und wird verwendet, um einen String im Normalmodus an ein Gerät zu senden.

ResponseStatus rs = e32ttl.sendMessage("Prova");Serial.println(rs.getResponseDescription());

Das andere Gerät macht einfach auf der Schleife

if (e32ttl.available() > 1){ResponseContainer rs = e32ttl.receiveMessage(); String-Nachricht = rs.data; // Holen Sie sich zuerst die Daten Serial.println (rs.status.getResponseDescription ()); Serial.println (Nachricht); }

Schritt 13: Struktur verwalten

Wenn Sie eine komplexe Struktur senden möchten, können Sie diese Methode verwenden

ResponseStatus sendMessage(const void *message, const uint8_t size);ResponseStructContainer receiveMessage(const uint8_t size);

Es wird verwendet, um Strukturen zu senden, zum Beispiel:

struct Messaggione {Zeichentyp[5]; char-Nachricht[8]; bool mitico; }; struct Messaggione messaggione = {"TEMP", "Peple", true}; ResponseStatus rs = e32ttl.sendMessage(&messaggione, sizeof(Messaggione)); Serial.println (rs.getResponseDescription());

und auf der anderen Seite kannst du die Nachricht so empfangen

ResponseStructContainer rsc = e32ttl.receiveMessage(sizeof(Messaggione));struct Messaggione messaggione = *(Messaggione*) rsc.data; Serial.println (messaggione.message); Serial.println (messaggione.mitico);

Teilstruktur lesen

Wenn Sie den ersten Teil der Nachricht lesen möchten, um mehr Strukturtypen zu verwalten, können Sie diese Methode verwenden.

ResponseContainer receiveInitialMessage(const uint8_t size);

Ich erstelle es, um eine Zeichenfolge mit dem Typ oder einem anderen zu erhalten, um die zu ladende Struktur zu identifizieren.

struct Messaggione { // Teilstruktur ohne typechar message[8]; bool mitico; }; Zeichentyp[5]; // erster Teil der Struktur ResponseContainer rs = e32ttl.receiveInitialMessage(sizeof(type)); // String in ein char-Array einfügen (nicht benötigt) memcpy (type, rs.data.c_str(), sizeof(type)); Serial.println("LESENTYP:"); Serial.println (rs.status.getResponseDescription()); Serial.println (Typ); // Rest der Struktur lesen ResponseStructContainer rsc = e32ttl.receiveMessage(sizeof(Messaggione)); struct Messaggione messaggione = *(Messaggione*) rsc.data;

Schritt 14: Fester Modus statt Normalmodus

Auf die gleiche Weise erstelle ich eine Reihe von Methoden für die Verwendung mit fester Übertragung

Feste Übertragung

Sie müssen nur die Sendemethode ändern, da das Zielgerät die Präambel nicht mit Adresse und Kanal quando settato il fixed mode empfängt.

Also für String-Nachricht haben Sie

ResponseStatus sendFixedMessage(Byte ADDL, Byte ADDH, Byte CHAN, Nachricht const String);ResponseStatus sendBroadcastFixedMessage(Byte CHAN, Nachricht const String);

und für struktur hast du

ResponseStatus sendFixedMessage(Byte ADDL, Byte ADDH, Byte CHAN, const void *message, const uint8_t size);ResponseStatus sendBroadcastFixedMessage(byte CHAN, const void *message, const uint8_t size);

Hier ein einfaches Beispiel

ResponseStatus rs = e32ttl.sendFixedMessage(0, 0, 0x17, &messaggione, sizeof(Messaggione)); // ResponseStatus rs = e32ttl.sendFixedMessage(0, 0, 0x17, "Ciao");

Feste Übertragung hat mehr Szenarien

Wenn Sie an ein bestimmtes Gerät senden (zweite Szenarien Feste Übertragung), müssen Sie ADDL, ADDH und CHAN hinzufügen, um es direkt zu identifizieren.

ResponseStatus rs = e32ttl.sendFixedMessage(2, 2, 0x17, "Nachricht an ein Gerät");

Wenn Sie eine Nachricht an alle Geräte in einem bestimmten Kanal senden möchten, können Sie diese Methode verwenden.

ResponseStatus rs = e32ttl.sendBroadcastFixedMessage(0x17, "Nachricht an ein Gerät eines Kanals");

Wenn Sie alle Broadcast-Nachrichten im Netzwerk empfangen möchten, müssen Sie Ihre ADDH und ADDL mit BROADCAST_ADDRESS einstellen.

ResponseStructContainer c;c = e32ttl100.getConfiguration(); // Es ist wichtig, den Konfigurationszeiger vor allen anderen Operationen zu erhalten Configuration configuration = *(Configuration*) c.data; Serial.println (c.status.getResponseDescription()); Serial.println (c.status.code); printParameters(Konfiguration); configuration. ADDL = BROADCAST_ADDRESS; Konfiguration. ADDH = BROADCAST_ADDRESS; // Konfiguration geändert und so eingestellt, dass die Konfiguration nicht gehalten wird ResponseStatus rs = e32ttl100.setConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE); Serial.println (rs.getResponseDescription()); Serial.println (rs.code); printParameters(Konfiguration);

Schritt 15: Danke

Jetzt haben Sie alle Informationen, um Ihre Arbeit zu erledigen, aber ich denke, es ist wichtig, einige realistische Beispiele zu zeigen, um alle Möglichkeiten besser zu verstehen.

  1. LoRa E32-Gerät für Arduino, esp32 oder esp8266: Einstellungen und grundlegende Verwendung
  2. LoRa E32-Gerät für Arduino, esp32 oder esp8266: Bibliothek
  3. LoRa E32-Gerät für Arduino, esp32 oder esp8266: Konfiguration
  4. LoRa E32 Gerät für Arduino, esp32 oder esp8266: feste Übertragung
  5. LoRa E32-Gerät für Arduino, esp32 oder esp8266: Strom sparen und strukturierte Daten senden

Empfohlen: