Taula de continguts:

Comunicació sense fils LoRa de 3 km a 8 km amb dispositiu E32 de baix cost (sx1278 / sx1276) per a Arduino, Esp8266 o Esp32: 15 passos
Comunicació sense fils LoRa de 3 km a 8 km amb dispositiu E32 de baix cost (sx1278 / sx1276) per a Arduino, Esp8266 o Esp32: 15 passos

Vídeo: Comunicació sense fils LoRa de 3 km a 8 km amb dispositiu E32 de baix cost (sx1278 / sx1276) per a Arduino, Esp8266 o Esp32: 15 passos

Vídeo: Comunicació sense fils LoRa de 3 km a 8 km amb dispositiu E32 de baix cost (sx1278 / sx1276) per a Arduino, Esp8266 o Esp32: 15 passos
Vídeo: Как охотиться на людей ► 1 Прохождение Manhunt (PS2) 2024, Juliol
Anonim
Comunicació sense fils LoRa de 3 km a 8 km amb dispositiu E32 de baix cost (sx1278 / sx1276) per a Arduino, Esp8266 o Esp32
Comunicació sense fils LoRa de 3 km a 8 km amb dispositiu E32 de baix cost (sx1278 / sx1276) per a Arduino, Esp8266 o Esp32

Crec una biblioteca per gestionar EBYTE E32 basat en la sèrie Semtech de dispositius LoRa, un dispositiu molt potent, senzill i econòmic.

Podeu trobar la versió de 3 km aquí, la versió de 8 km aquí

Poden treballar a una distància d'entre 3000 i 8000 m, i tenen moltes funcions i paràmetres. Així que creo aquesta biblioteca per simplificar-ne l’ús.

És una solució per recuperar dades de sensors metropolitans o per controlar drons.

Subministraments

Arduino UNO

Wemos D1 mini

Versió LoRa E32 TTL 100 3Km

Versió LoRa E32 TTL 1W 8Km

Pas 1: biblioteca

Biblioteca
Biblioteca

Podeu trobar la meva biblioteca aquí.

Per descarregar.

Feu clic al botó DESCÀRREGUES de l'extrem superior dret i canvieu el nom de la carpeta sense comprimir LoRa_E32.

Comproveu que la carpeta LoRa_E32 conté LoRa_E32.cpp i LoRa_E32.h.

Col·loqueu la carpeta de la biblioteca LoRa_E32 a la vostra carpeta / libraries /. És possible que hàgiu de crear la subcarpeta de biblioteques si és la vostra primera biblioteca.

Reinicieu l'IDE.

Pas 2: fixació

Pinout
Pinout
Pinout
Pinout
Pinout
Pinout

Com podeu veure, podeu configurar diversos modes mitjançant pins M0 i M1.

Hi ha alguns pins que es poden utilitzar de manera estàtica, però si el connecteu al microcontrolador i els configureu a la biblioteca, obtindreu un rendiment més gran i podreu controlar tot el mode mitjançant programari, però a continuació ho explicarem millor.

Pas 3: Pin AUX

Pin AUX
Pin AUX
Pin AUX
Pin AUX
Pin AUX
Pin AUX

Com ja he dit, no és important connectar tots els pins a la sortida del microcontrolador, podeu posar els pins M0 i M1 a HIGH o LOW per obtenir una configuració desitjada i, si no connecteu AUX, la biblioteca estableix un retard raonable per estar segur que l'operació s'ha completat.

Pin AUX

Quan es transmeten dades, es pot utilitzar per despertar una MCU externa i tornar ALTA en acabar la transferència de dades.

Quan es rep AUX, va BAIX i es torna ALT quan el buffer està buit.

També s’utilitza per a la comprovació automàtica per restablir el funcionament normal (en mode d’engegada i de suspensió / programa).

Pas 4: Esquema completament connectat Esp8266

Esquema completament connectat Esp8266
Esquema completament connectat Esp8266
Esquema completament connectat Esp8266
Esquema completament connectat Esp8266

L'esquema de connexió esp8266 és més senzill perquè funciona al mateix voltatge de les comunicacions lògiques (3.3v).

És important afegir una resistència de tracció (4, 7 Kohm) per obtenir una bona estabilitat.

Pas 5: Esquema Arduino completament connectat

Esquema Arduino completament connectat
Esquema Arduino completament connectat
Esquema Arduino completament connectat
Esquema Arduino completament connectat

La tensió de treball d’Arduino és de 5v, per tant, hem d’afegir un divisor de tensió al pin RX M0 i M1 del mòdul LoRa per evitar danys. Podeu obtenir més informació aquí Divisor de tensió: calculadora i aplicació.

Podeu utilitzar una resistència de 2 Kohm a GND i 1 Kohm des del senyal que no pas a RX.

Pas 6: Biblioteca: constructor

He creat un conjunt de constructors força nombrosos, perquè podem tenir més opcions i situacions per gestionar.

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);

Els primers conjunts de constructors es creen per delegar la gestió de pins i altres sèries a la biblioteca.

rxPin i txPin són els pins per connectar-se a UART i són obligatoris.

auxPin és un pin que comprova l'estat de funcionament, transmissió i recepció (ho explicarem millor a continuació), aquest pin No és obligatori, si no ho configureu, aplico un retard per permetre que l'operació es completi (amb latència).

m0pin i m1Pin són els pins per canviar el MODE d'operació (vegeu la taula superior), crec que aquests pins de "producció" es connectaran directament ALTA o BAIXA, però per a la prova, seran útils per a la gestió de la biblioteca.

bpsRate és la velocitat màxima de SoftwareSerial normalment és de 9600 (l'única velocitat de transmissió en mode programmin / sleep)

Un exemple senzill és

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

Podem utilitzar directament un SoftwareSerial amb un altre constructor

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

LoRa_E32 (sèrie HardwareSerial *, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

LoRa_E32 (HardwareSerial * serial, byte auxPin, byte m0Pin, byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

L'exemple superior amb aquest constructor es pot fer així.

#include #include "LoRa_E32.h"

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

LoRa_E32 e32ttl100 (& mySerial);

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

L'últim conjunt de constructors és permetre utilitzar un HardwareSerial en lloc de SoftwareSerial.

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

LoRa_E32 (SoftwareSerial * serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

LoRa_E32 (SoftwareSerial * serial, byte auxPin, byte m0Pin, byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);

Pas 7: Comenceu

L'ordre begin s'utilitza per iniciar el serial i els pins en mode d'entrada i sortida.

void begin ();

en execució és

// Inicieu tots els pins i UART

e32ttl100.begin ();

Pas 8: Configuració i mètode d'informació

Hi ha un conjunt de mètodes per gestionar la configuració i obtenir informació del dispositiu.

ResponseStructContainer getConfiguration ();

ResponseStatus setConfiguration (Configuració de configuració, PROGRAM_COMMAND saveType = WRITE_CFG_PWR_DWN_LOSE);

ResponseStructContainer getModuleInformation ();

void printParameters (configuració de configuració struct);

ResponseStatus resetModule ();

Pas 9: contenidor de resposta

Per simplificar la gestió de la resposta, creo un conjunt de contenidors per a mi, de manera molt útil, per gestionar errors i retornar dades genèriques.

ResponseStatus

Es tracta d'un contenidor d'estat i té 2 punts d'entrada simples, amb els quals podeu obtenir el codi d'estat i la descripció del codi d'estat

Serial.println (c.getResponseDescription ()); // Descripció del codi

Serial.println (c.code); // 1 si té èxit

El codi és

ÈXIT = 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

ResponseContainer

Aquest contenidor està creat per gestionar la resposta de la cadena i té 2 punts d’entrada.

les dades amb la cadena van retornar del missatge i l'estat una instància de RepsonseStatus.

ResponseContainer rs = e32ttl.receiveMessage ();

Missatge de cadena = rs.data;

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

Serial.println (missatge);

ResponseStructContainer

Aquest és el contenidor més "complex", ho faig servir per gestionar l'estructura. Té el mateix punt d'entrada de ResponseContainer, però les dades són un indicador buit per gestionar l'estructura complexa.

ResponseStructContainer c;

c = e32ttl100.getConfiguration (); // És important obtenir el punter de configuració abans de qualsevol altra operació

Configuració de la configuració = * (Configuració *) c.data;

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

Serial.println (c.status.code);

getConfiguration i setConfiguration

El primer mètode és getConfiguration, podeu utilitzar-lo per recuperar totes les dades emmagatzemades al dispositiu.

ResponseStructContainer getConfiguration ();

Aquí teniu un exemple d’ús.

ResponseStructContainer c;

c = e32ttl100.getConfiguration (); // És important obtenir el punter de configuració abans de qualsevol altra operació

Configuració de la configuració = * (Configuració *) c.data;

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

Serial.println (c.status.code);

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

L’estructura de configuració té totes les dades de configuració, i afegeixo una sèrie de funcions per obtenir tota la descripció de dades individuals.

configuration. ADDL = 0x0; // Primera part de l'adreça de configuració. ADDH = 0x1; // Segona part de la configuració de l'adreça. CHAN = 0x19; // Configuració del canal. OPTION.fec = FEC_0_OFF; // Configuració del commutador de correcció d’errors cap endavant. OPTION.fixedTransmission = FT_TRANSPARENT_TRANSMISSION; // Configuració del mode de transmissió. OPTION.ioDriveMode = IO_D_MODE_PUSH_PULLS_PULL_UPS; // Configuració de gestió de pull-up. OPTION.transmissionPower = POWER_17; // configuració de potència de transmissió dBm. OPTION.wirelessWakeupTime = WAKE_UP_1250; // Temps d'espera per a la configuració de despertador. SPED.airDataRate = AIR_DATA_RATE_011_48; // Configuració de la taxa de dades aèries. SPED.uartBaudRate = UART_BPS_115200; // Configuració de la velocitat en transmissió de comunicació. SPED.uartParity = MODE_00_8N1; // Bit de paritat

Teniu la funció equivalent per a tots els atributs per obtenir tota la descripció:

Serial.print (F ("Chan:")); Serial.print (configuration. 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 ());

De la mateixa manera, setConfiguration vol una estructura de configuració, de manera que crec que la millor manera de gestionar la configuració és recuperar l'actual, aplicar l'únic canvi que necessiteu i tornar-lo a configurar.

ResponseStatus setConfiguration (Configuració de configuració, PROGRAM_COMMAND saveType = WRITE_CFG_PWR_DWN_LOSE);

la configuració és la que es mostra de manera previsual, guardeu TypePermetteu de triar si el canvi només es fa permanentment per a la sessió actual.

ResponseStructContainer c; c = e32ttl100.getConfiguration (); // És important obtenir el punter de configuració abans de qualsevol altra operació Configuració de la configuració = * (Configuració *) c.data; Serial.println (c.status.getResponseDescription ()); Serial.println (c.status.code); printParameters (configuració); configuration. ADDL = 0x0; configuration. ADDH = 0x1; configuration. 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; // Estableix la configuració canviat i estableix que no mantingui la configuració ResponseStatus rs = e32ttl100.setConfiguration (configuració, WRITE_CFG_PWR_DWN_LOSE); Serial.println (rs.getResponseDescription ()); Serial.println (rs.code); printParameters (configuració);

Tots els paràmetres es gestionen com a constants:

Pas 10: opció de configuració bàsica

Opció de configuració bàsica
Opció de configuració bàsica

Pas 11: enviar missatges de recepció

Primer hem d’introduir un mètode senzill però útil per comprovar si hi ha alguna cosa al buffer receptor

int disponible ();

Simplement és retornar quants bytes teniu al flux actual.

Pas 12: mode de transmissió normal

Mode de transmissió normal
Mode de transmissió normal

El mode de transmissió normal / transparent s’utilitza per enviar missatges a tots els dispositius amb la mateixa adreça i canal.

Hi ha molts mètodes per enviar / rebre missatges, els explicarem amb detall:

ResponseStatus sendMessage (missatge de cadena const);

ResponseContainer receiveMessage ();

El primer mètode és sendMessage i s’utilitza per enviar una cadena a un dispositiu en mode normal.

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

L'altre dispositiu simplement ho fa al bucle

if (e32ttl.available ()> 1) {ResponseContainer rs = e32ttl.receiveMessage (); Missatge de cadena = rs.data; // Primer obtingueu les dades Serial.println (rs.status.getResponseDescription ()); Serial.println (missatge); }

Pas 13: gestioneu l'estructura

Si voleu enviar una estructura complexa, podeu utilitzar aquest mètode

ResponseStatus sendMessage (missatge const void *, mida const uint8_t); ResponseStructContainer receiveMessage (mida const uint8_t);

S'utilitza per enviar estrucutres, per exemple:

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

i a l'altra banda, podeu rebre el missatge així

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

Llegiu l'estructura parcial

Si voleu llegir la primera part del missatge per gestionar més tipus d’estructura, podeu utilitzar aquest mètode.

ResponseContainer receiveInitialMessage (mida constant uint8_t);

El creo per rebre una cadena amb tipus o altre per identificar l'estructura a carregar.

struct Messaggione {// Estructura parcial sense missatge typechar [8]; bool mitico; }; tipus char [5]; // primera part de l'estructura ResponseContainer rs = e32ttl.receiveInitialMessage (sizeof (type)); // Posa una cadena en una matriu de caràcters (no cal) memcpy (type, rs.data.c_str (), sizeof (type)); Serial.println ("LLEGIR TIPUS:"); Serial.println (rs.status.getResponseDescription ()); Serial.println (tipus); // Llegiu la resta de l'estructura ResponseStructContainer rsc = e32ttl.receiveMessage (sizeof (Messaggione)); struct Messaggione messaggione = * (Messaggione *) rsc.data;

Pas 14: mode fix en lloc del mode normal

De la mateixa manera, creo un conjunt de mètodes per utilitzar amb transmissions fixes

Transmissió fixa

Només heu de canviar el mètode d’enviament, perquè el dispositiu de destinació no rep el preàmbul amb Adreça i canal quan s’estableix el mode fix.

Per tant, per al missatge de cadena que teniu

ResponseStatus sendFixedMessage (byte ADDL, byte ADDH, byte CHAN, const String message); ResponseStatus sendBroadcastFixedMessage (byte CHAN, const String message);

i per l'estructura que teniu

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);

Aquí un exemple senzill

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

La transmissió fixa té més escenaris

Si envieu a un dispositiu específic (segons escenaris Transmissió fixa), heu d'afegir ADDL, ADDH i CHAN per identificar-lo directament.

ResponseStatus rs = e32ttl.sendFixedMessage (2, 2, 0x17, "Missatge a un dispositiu");

Si voleu enviar un missatge a tots els dispositius d’un canal especificat, podeu utilitzar aquest mètode.

ResponseStatus rs = e32ttl.sendBroadcastFixedMessage (0x17, "Missatge a dispositius d'un canal");

Si voleu rebre tots els missatges de difusió a la xarxa, heu de configurar ADDH i ADDL amb BROADCAST_ADDRESS.

ResponseStructContainer c; c = e32ttl100.getConfiguration (); // És important obtenir el punter de configuració abans de qualsevol altra operació Configuració de la configuració = * (Configuració *) c.data; Serial.println (c.status.getResponseDescription ()); Serial.println (c.status.code); printParameters (configuració); configuration. ADDL = BROADCAST_ADDRESS; configuration. ADDH = BROADCAST_ADDRESS; // Estableix la configuració canviat i estableix que no mantingui la configuració ResponseStatus rs = e32ttl100.setConfiguration (configuració, WRITE_CFG_PWR_DWN_LOSE); Serial.println (rs.getResponseDescription ()); Serial.println (rs.code); printParameters (configuració);

Pas 15: gràcies

Ara teniu tota la informació per fer el vostre treball, però crec que és important mostrar alguns exemples realistes per entendre millor tota la possibilitat.

  1. Dispositiu LoRa E32 per Arduino, esp32 o esp8266: configuració i ús bàsic
  2. Dispositiu LoRa E32 per Arduino, esp32 o esp8266: biblioteca
  3. Dispositiu LoRa E32 per a Arduino, esp32 o esp8266: configuració
  4. Dispositiu LoRa E32 per Arduino, esp32 o esp8266: transmissió fixa
  5. Dispositiu LoRa E32 per Arduino, esp32 o esp8266: estalvi d'energia i enviament de dades estructurades

Recomanat: