Spisu treści:
- Kieszonkowe dzieci
- Krok 1: Biblioteka
- Krok 2: Pinout
- Krok 3: pin AUX
- Krok 4: W pełni połączony schemat Esp8266
- Krok 5: W pełni połączony schemat Arduino
- Krok 6: Biblioteka: Konstruktor
- Krok 7: Rozpocznij
- Krok 8: Metoda konfiguracji i informacji
- Krok 9: Kontener odpowiedzi
- Krok 10: Podstawowa opcja konfiguracji
- Krok 11: Wyślij wiadomość do odbioru
- Krok 12: Normalny tryb transmisji
- Krok 13: Zarządzaj strukturą
- Krok 14: Tryb stały zamiast trybu normalnego
- Krok 15: Dzięki
2025 Autor: John Day | [email protected]. Ostatnio zmodyfikowany: 2025-01-13 06:58
Tworzę bibliotekę do zarządzania EBYTE E32 w oparciu o urządzenie LoRa serii Semtech, bardzo wydajne, proste i tanie urządzenie.
Wersję 3Km znajdziesz tutaj, wersję 8Km tutaj
Mogą pracować na dystansie od 3000m do 8000m, posiadają wiele funkcji i parametrów. Więc tworzę tę bibliotekę, aby uprościć użytkowanie.
To rozwiązanie do pobierania danych z czujników miejskich lub sterowania dronem.
Kieszonkowe dzieci
Arduino UNO
Wemos D1 mini
Wersja LoRa E32 TTL 100 3Km
Wersja LoRa E32 TTL 1W 8Km
Krok 1: Biblioteka
Moją bibliotekę znajdziesz tutaj.
Pobrać.
Kliknij przycisk POBIERZ w prawym górnym rogu, zmień nazwę nieskompresowanego folderu LoRa_E32.
Sprawdź, czy folder LoRa_E32 zawiera LoRa_E32.cpp i LoRa_E32.h.
Umieść folder biblioteki LoRa_E32 w folderze /libraries/. Może być konieczne utworzenie podfolderu biblioteki, jeśli jest to Twoja pierwsza biblioteka.
Uruchom ponownie środowisko IDE.
Krok 2: Pinout
Jak widać, możesz ustawić różne tryby za pomocą pinów M0 i M1.
Istnieje kilka pinów, których można używać w sposób statyczny, ale jeśli podłączysz go do mikrokontrolera i skonfigurujesz je w bibliotece, zyskujesz na wydajności i możesz sterować wszystkimi trybami za pomocą oprogramowania, ale dokładniej wyjaśnimy to w dalszej części.
Krok 3: pin AUX
Jak już pisałem Nie jest ważne, aby podłączyć wszystkie piny do wyjścia mikrokontrolera, można ustawić piny M0 i M1 na HIGH lub LOW, aby uzyskać pożądaną konfigurację, a jeśli nie podłączysz AUX biblioteka ustaw rozsądną zwłokę dla pewności że operacja została zakończona.
Styk AUX
Podczas transmisji danych można użyć do wybudzenia zewnętrznego MCU i powrotu do stanu HIGH po zakończeniu przesyłania danych.
Po odebraniu AUX przechodzi w LOW i zwraca HIGH, gdy bufor jest pusty.
Służy również do samokontroli w celu przywrócenia normalnej pracy (w trybie włączenia i uśpienia/programu).
Krok 4: W pełni połączony schemat Esp8266
Schemat podłączenia esp8266 jest prostszy, ponieważ działa na tym samym napięciu komunikacji logicznej (3,3v).
Ważne jest, aby dodać rezystor podciągający (4, 7Kohm), aby uzyskać dobrą stabilność.
Krok 5: W pełni połączony schemat Arduino
Napięcie pracy Arduino wynosi 5V, dlatego musimy dodać dzielnik napięcia na pinie RX M0 i M1 modułu LoRa, aby zapobiec uszkodzeniom, więcej informacji znajdziesz tutaj Dzielnik napięcia: kalkulator i aplikacja.
Możesz użyć rezystora 2Kohm do GND i 1Kohm z sygnału niż połączone na RX.
Krok 6: Biblioteka: Konstruktor
Zrobiłem zestaw dość licznych konstruktorów, ponieważ możemy mieć więcej opcji i sytuacji do zarządzania.
LoRa_E32 (bajt rxPin, bajt txPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E32 (bajt rxPin, bajt txPin, bajt auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600); LoRa_E32(bajt rxPin, bajt txPin, bajt auxPin, bajt m0Pin, bajt m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
Tworzony jest pierwszy zestaw konstruktorów do delegowania zarządzania pinami Serial i innymi pinami do biblioteki.
rxPin i txPin to pin do podłączenia do UART i są one obowiązkowe.
auxPin to pin, który sprawdza stan operacji, transmisji i odbioru (będziemy wyjaśniać dokładniej dalej), ten pin Nie jest obowiązkowy, jeśli nie ustawisz. z opóźnieniem).
m0pin i m1Pin to piny do zmiany TRYBU pracy (patrz tabela u góry), myślę, że te piny w „produkcji” będą łączyć bezpośrednio WYSOKI lub NISKI, ale do testu przydatne są do zarządzania przez bibliotekę.
bpsRate to szybkość transmisji oprogramowania SoftwareSerial, która zwykle wynosi 9600 (jedyna szybkość transmisji w trybie programowania/uśpienia)
Prostym przykładem jest
#include "LoRa_E32.h"LoRa_E32 e32ttl100(2, 3); // RX, TX // LoRa_E32 e32ttl100(2, 3, 5, 6, 7); // RX, TX
Możemy użyć bezpośrednio SoftwareSerial z innym konstruktorem
LoRa_E32 (szeregowy sprzęt szeregowy*, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E32 (Szeregowy sprzęt szeregowy*, bajt auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E32 (Szeregowy sprzęt szeregowy*, bajt auxPin, bajt m0Pin, bajt m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
Przykład górny z tym konstruktorem można zrobić w ten sposób.
#include #include "LoRa_E32.h"
SoftwareSerial mySerial(2, 3); // RX, TX
LoRa_E32 e32ttl100(&mySerial);
// LoRa_E32 e32ttl100(&mySerial, 5, 7, 6);
Ostatnim zestawem konstruktorów jest zezwolenie na użycie HardwareSerial zamiast SoftwareSerial.
LoRa_E32 (szeregowy SoftwareSerial*, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E32 (szeregowy SoftwareSerial*, bajt auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E32 (Serial SoftwareSerial*, bajt auxPin, bajt m0Pin, bajt m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
Krok 7: Rozpocznij
Polecenie begin służy do uruchamiania portu szeregowego i pinów w trybie wejścia i wyjścia.
nieważny początek();
w wykonaniu jest
// Uruchom wszystkie piny i UART
e32ttl100.begin();
Krok 8: Metoda konfiguracji i informacji
Istnieje zestaw metod zarządzania konfiguracją i uzyskiwania informacji o urządzeniu.
ResponseStructContainer getConfiguration();
ResponseStatus setConfiguration(Konfiguracja konfiguracji, PROGRAM_COMMAND saveType = WRITE_CFG_PWR_DWN_LOSE);
ResponseStructContainer getModuleInformation();
void printParameters(struktura konfiguracji konfiguracji);
ResponseStatus resetModule();
Krok 9: Kontener odpowiedzi
Aby uprościć zarządzanie odpowiedziami, tworzę zestaw kontenerów, które są dla mnie bardzo przydatne do zarządzania błędami i zwracania danych generycznych.
Stan odpowiedzi
Jest to kontener statusu i ma 2 proste punkty wejścia, dzięki czemu możesz uzyskać kod statusu i opis kodu statusu
Serial.println(c.getResponseDescription()); // Opis kodu
Serial.println(c.kod); // 1 jeśli sukces
Kod są
SUKCES = 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
Kontener odpowiedzi
Ten kontener jest tworzony do zarządzania odpowiedzią ciągu i ma 2 punkty wejścia.
dane z ciągiem zwróconym z komunikatu i statusem wystąpienia RepsonseStatus.
Kontener Odpowiedzi rs = e32ttl.receiveMessage();
Wiadomość ciąg = rs.data;
Serial.println(rs.status.getResponseDescription());
Serial.println(wiadomość);
Kontener struktury odpowiedzi
Jest to bardziej „złożony” kontener, używam go do zarządzania strukturą. Ma ten sam punkt wejścia co ResponseContainer, ale dane są pustym wskaźnikiem do zarządzania złożoną strukturą.
ResponseStructContainer c;
c = e32ttl100.getConfiguration();// Ważne jest, aby uzyskać wskaźnik konfiguracji przed wszystkimi innymi operacjami
Konfiguracja konfiguracji = *(Konfiguracja*) c.data;
Serial.println(c.status.getResponseDescription());
Serial.println(c.status.kod);
getConfiguration i setConfiguration
Pierwsza metoda to getConfiguration, możesz jej użyć do odzyskania wszystkich danych przechowywanych na urządzeniu.
ResponseStructContainer getConfiguration();
Oto przykład użycia.
ResponseStructContainer c;
c = e32ttl100.getConfiguration();// Ważne jest, aby uzyskać wskaźnik konfiguracji przed wszystkimi innymi operacjami
Konfiguracja konfiguracji = *(Konfiguracja*) c.data;
Serial.println(c.status.getResponseDescription());
Serial.println(c.status.kod);
Serial.println(konfiguracja. SPED.getUARTBaudRate());
Struktura konfiguracji zawiera wszystkie dane ustawień i dodaję szereg funkcji, aby uzyskać cały opis pojedynczych danych.
konfiguracja. ADDL = 0x0; // Pierwsza część adresuconfiguration. ADDH = 0x1; // Druga część konfiguracji adresu. CHAN = 0x19;// Konfiguracja kanału. OPTION.fec = FEC_0_OFF; // Przekaż konfigurację przełącznika korekcji błędów. OPTION.fixedTransmission = FT_TRANSPARENT_TRANSMISSION; // Konfiguracja trybu transmisji. OPTION.ioDriveMode = IO_D_MODE_PUSH_PULLS_PULL_UPS; // Konfiguracja zarządzania pull-up. OPTION.transmissionPower = POWER_17; // konfiguracja mocy transmisji dBm. OPTION.wirelessWakeupTime = WAKE_UP_1250; // Czas oczekiwania na wybudzenie configuration. SPED.airDataRate = AIR_DATA_RATE_011_48; // Konfiguracja szybkości transmisji danych. SPED.uartBaudRate = UART_BPS_115200; // Konfiguracja szybkości transmisji komunikacji. SPED.uartParity = MODE_00_8N1; // Bit parzystości
Masz równoważną funkcję dla wszystkich atrybutów, aby uzyskać cały opis:
Serial.print(F("Chan: ")); Serial.print(konfiguracja. CHAN, DEC); Serial.print(" -> "); Serial.println(configuration.getChannelDescription());Serial.println(F(" ")); Serial.print(F("SpeedParityBit: ")); Serial.print(konfiguracja. SPED.uartParity, BIN);Serial.print("->"); Serial.println(konfiguracja. SPED.getUARTParityDescription()); Serial.print(F("DataPrędkościUART: ")); Serial.print(konfiguracja. SPED.uartBaudRate, BIN);Serial.print("->"); Serial.println(konfiguracja. SPED.getUARTBaudRate()); Serial.print(F("SpeedAirDataRate: ")); Serial.print(konfiguracja. SPED.airDataRate, BIN);Serial.print("->"); Serial.println(konfiguracja. SPED.getAirDataRate()); Serial.print(F("OptionTrans: ")); Serial.print(konfiguracja. OPCJA.fixedTransmission, BIN);Serial.print("->"); Serial.println(konfiguracja. OPCJA.getFixedTransmissionDescription()); Serial.print(F("OptionPullup: ")); Serial.print(konfiguracja. OPCJA.ioDriveMode, BIN);Serial.print("->"); Serial.println(konfiguracja. OPCJA.getIODroveModeDescription()); Serial.print(F("OpcjaWakeup: ")); Serial.print(konfiguracja. OPCJA.wirelessWakeupTime, BIN);Serial.print(" -> "); Serial.println(konfiguracja. OPCJA.getWirelessWakeUPTimeDescription()); Serial.print(F("OpcjaFEC: ")); Serial.print(konfiguracja. OPCJA.fec, BIN);Serial.print("->"); Serial.println(konfiguracja. OPCJA.getFECDescription()); Serial.print(F("OpcjaMoc: ")); Serial.print(konfiguracja. OPCJA.transmissionPower, BIN);Serial.print("->"); Serial.println(konfiguracja. OPCJA.getTransmissionPowerDescription());
W ten sam sposób setConfiguration chce struktury konfiguracji, więc myślę, że lepszym sposobem zarządzania konfiguracją jest pobranie bieżącej, zastosowanie jedynej potrzebnej zmiany i ponowne ustawienie.
ResponseStatus setConfiguration(Konfiguracja konfiguracji, PROGRAM_COMMAND saveType = WRITE_CFG_PWR_DWN_LOSE);
Konfiguracja jest strukturą pokazaną wcześniej, saveType pozwala wybrać, czy zmiana zostanie trwale ustawiona tylko na bieżącą sesję.
ResponseStructContainer c;c = e32ttl100.getConfiguration(); // Ważne jest, aby uzyskać wskaźnik konfiguracji przed wszystkimi innymi operacjami Configuration configuration = *(Configuration*) c.data; Serial.println(c.status.getResponseDescription()); Serial.println(c.status.kod); printParameters(konfiguracja); konfiguracja. ADDL = 0x0; konfiguracja. ADDH = 0x1; konfiguracja. KANAŁ = 0x19; konfiguracja. OPCJA.fec = FEC_0_OFF; configuration. OPTION.fixedTransmission = FT_TRANSPARENT_TRANSMISSION; konfiguracja. OPTION.ioDriveMode = IO_D_MODE_PUSH_PULLS_PULL_UPS; konfiguracja. OPCJA.moc transmisji = MOC_17; configuration. OPTION.wirelessWakeupTime = WAKE_UP_1250; configuration. SPED.airDataRate = AIR_DATA_RATE_011_48; konfiguracja. SPED.uartBaudRate = UART_BPS_115200; konfiguracja. SPED.uartParity = MODE_00_8N1; // Ustaw konfigurację zmienioną i ustaw, aby nie przechowywać konfiguracji ResponseStatus rs = e32ttl100.setConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE); Serial.println(rs.getResponseDescription()); Serial.println(rs.kod); printParameters(konfiguracja);
Wszystkie parametry są zarządzane jako stałe:
Krok 10: Podstawowa opcja konfiguracji
Krok 11: Wyślij wiadomość do odbioru
Najpierw musimy wprowadzić prostą, ale użyteczną metodę sprawdzania, czy coś jest w buforze odbiorczym
dostępne();
Po prostu zwraca, ile bajtów masz w bieżącym strumieniu.
Krok 12: Normalny tryb transmisji
Tryb transmisji Normal/Transparent służy do wysyłania wiadomości do wszystkich urządzeń o tym samym adresie i kanale.
Istnieje wiele metod wysyłania/odbierania wiadomości, wyjaśnimy szczegółowo:
ResponseStatus sendMessage(const String wiadomość);
ResponseContainer odbierzMessage();
Pierwsza metoda to sendMessage i służy do wysyłania ciągu do urządzenia w trybie normalnym.
ResponseStatus rs = e32ttl.sendMessage("Prova");Serial.println(rs.getResponseDescription());
Drugie urządzenie po prostu działa w pętli
if (e32ttl.available() > 1){ResponseContainer rs = e32ttl.receiveMessage(); Wiadomość ciąg = rs.data; // Najpierw pobierz dane Serial.println(rs.status.getResponseDescription()); Serial.println(wiadomość); }
Krok 13: Zarządzaj strukturą
Jeśli chcesz wysłać złożoną strukturę, możesz skorzystać z tej metody
ResponseStatus sendMessage(const void *wiadomość, const uint8_t rozmiar);ResponseStructContainer odbiór wiadomości(const uint8_t rozmiar);
Służy do wysyłania struktur, na przykład:
struct Messaggione {typ znaku[5]; wiadomość znakowa[8]; bool mitico; }; struct Messaggione messaggione = {"TEMP", "Peple", prawda}; ResponseStatus rs = e32ttl.sendMessage(&messaggione, sizeof(Messaggione)); Serial.println(rs.getResponseDescription());
a po drugiej stronie możesz otrzymać wiadomość, więc
ResponseStructContainer rsc = e32ttl.receiveMessage(sizeof(Messaggione));struct Messaggione messaggione = *(Messaggione*) rsc.data; Serial.println(wiadomość.wiadomość); Serial.println(messaggione.mitico);
Przeczytaj częściową strukturę
Jeśli chcesz przeczytać pierwszą część wiadomości, aby zarządzać większą ilością struktur, możesz skorzystać z tej metody.
ResponseContainer odbierzInitialMessage(const uint8_t size);
Tworzę go, aby otrzymać ciąg z typem lub innym w celu identyfikacji struktury do załadowania.
struct Messaggione { // Częściowa struktura bez typechar message[8]; bool mitico; }; typ znaku[5]; // pierwsza część struktury ResponseContainer rs = e32ttl.receiveInitialMessage(sizeof(type)); // Wstaw ciąg znaków do tablicy znaków (niepotrzebne) memcpy (type, rs.data.c_str(), sizeof(type)); Serial.println("TYP ODCZYTU: "); Serial.println(rs.status.getResponseDescription()); Serial.println(typ); // Odczytaj resztę struktury ResponseStructContainer rsc = e32ttl.receiveMessage(sizeof(Messaggione)); struct Messaggione messaggione = *(Messaggione*) rsc.data;
Krok 14: Tryb stały zamiast trybu normalnego
W ten sam sposób tworzę zestaw metod do użycia ze stałą transmisją
Transmisja stała
Należy zmienić tylko metodę wysyłania, ponieważ urządzenie docelowe nie otrzymuje preambuły w trybie Adres i Kanał quando settato il fixed.
Więc dla wiadomości String masz
ResponseStatus sendFixedMessage(bajt ADDL, bajt ADDH, bajt CHAN, const String komunikat);ResponseStatus sendBroadcastFixedMessage(bajt CHAN, const String komunikat);
i za strukturę, którą masz
ResponseStatus sendFixedMessage(bajt ADDL, bajt ADDH, bajt CHAN, const void *wiadomość, const uint8_t rozmiar);Status odpowiedzi sendBroadcastFixedMessage(bajt CHAN, const void *wiadomość, const uint8_t rozmiar);
Oto prosty przykład
ResponseStatus rs = e32ttl.sendFixedMessage(0, 0, 0x17, &messaggione, sizeof(Messaggione));// ResponseStatus rs = e32ttl.sendFixedMessage(0, 0, 0x17, "Ciao");
Transmisja stała ma więcej scenariuszy
Jeśli wysyłasz do konkretnego urządzenia (scenariusze drugie Transmisja stała) musisz dodać ADDL, ADDH i CHAN, aby bezpośrednio je zidentyfikować.
ResponseStatus rs = e32ttl.sendFixedMessage(2, 2, 0x17, "Wiadomość do urządzenia");
Jeśli chcesz wysłać wiadomość do wszystkich urządzeń w określonym kanale, możesz użyć tej metody.
ResponseStatus rs = e32ttl.sendBroadcastFixedMessage(0x17, "Wiadomość do urządzeń kanału");
Jeśli chcesz otrzymywać wszystkie wiadomości rozgłoszeniowe w sieci, musisz ustawić ADDH i ADDL z BROADCAST_ADDRESS.
ResponseStructContainer c;c = e32ttl100.getConfiguration(); // Ważne jest, aby uzyskać wskaźnik konfiguracji przed wszystkimi innymi operacjami Configuration configuration = *(Configuration*) c.data; Serial.println(c.status.getResponseDescription()); Serial.println(c.status.kod); printParameters(konfiguracja); konfiguracja. ADDL = BROADCAST_ADDRESS; konfiguracja. ADDH = BROADCAST_ADDRESS; // Ustaw konfigurację zmienioną i ustaw, aby nie przechowywać konfiguracji ResponseStatus rs = e32ttl100.setConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE); Serial.println(rs.getResponseDescription()); Serial.println(rs.kod); printParameters(konfiguracja);
Krok 15: Dzięki
Teraz masz wszystkie informacje do wykonania swojej pracy, ale myślę, że ważne jest, aby pokazać kilka realistycznych przykładów, aby lepiej zrozumieć wszystkie możliwości.
- Urządzenie LoRa E32 dla Arduino, esp32 lub esp8266: ustawienia i podstawowe użytkowanie
- Urządzenie LoRa E32 dla Arduino, esp32 lub esp8266: biblioteka
- Urządzenie LoRa E32 dla Arduino, esp32 lub esp8266: konfiguracja
- Urządzenie LoRa E32 dla Arduino, esp32 lub esp8266: poprawiona transmisja
- Urządzenie LoRa E32 dla Arduino, esp32 lub esp8266: oszczędzanie energii i wysyłanie uporządkowanych danych