Ebyte LoRa E22 per Arduino, esp32 o esp8266: Libreria – 2
La telemetria dei dati wireless LoRa o Long Range è una tecnologia introdotta da Semtech che opera a una frequenza inferiore degli NRF24L01 (433 MHz, 868 MHz o 916 MHz contro 2,4 GHz per NRF24L01) ma copre tre volte la distanza (da 4000 ma 10000 m).
Creo una libreria per gestire i moduli EBYTE E22 basati sui dispositivi LoRa serie Semtech SX1268, dispositivi molto potenti, semplici ed economici.
Puoi trovare i moduli del dispositivo su AliExpress (433MHz 5.5Km) - AliExpress (433MHz 10Km) - AliExpress (868MHz 915Mhz 5.5Km) - AliExpress (868MHz 915Mhz 10Km)
Libreria
Puoi trovare la mia libreria qui.
And It’s available on Arduino IDE library manager.
Per scaricare.
Clicca il bottone DOWNLOADS sull’angolo in alto a destra, rinomila la cartella decompressa LoRa_E22.
Controlla che la cartella LoRa_E22 contenga LoRa_E22.cpp e LoRa_E22.h.
posizione la cartella della libreria LoRa_E22 sulla tua cartella /libraries/.
Dovrai creare la sotto cartella librarues se è la tua prima libreria.
Riavvia l’IDE.
Pinout
Pin No. | Pin item | Pin direction | Pin application |
---|---|---|---|
1 | M0 | Input(weak pull-up) | Lavora con M1 e setta le quattro modalità di funzionamento. Non è consentito il floating, nel caso va messo a terra |
2 | M1 | Input(weak pull-up) | Lavora con M1 e setta le quattro modalità di funzionamento. Non è consentito il floating, nel caso va messo a terra. |
3 | RXD | Input | Ingresso TTL UART, si collega al pin di uscita TXD esterno (MCU, PC). Può essere configurato come ingresso open-drain o pull-up. |
4 | TXD | Output | Uscita UART TTL, si collega al pin di ingresso RXD esterno (MCU, PC). Può essere configurato come uscita open-drain o push-pull |
5 | AUX | Output | To indicate module’s working status & wakes up the external MCU. During the procedure of self-check initialization, the pin outputs low level. Can be configured as open-drain output orpush-pull output (floating is allowed). If you have trouble like freeze device, you must put a pull-up 4.7k resistor or better connect to the device. |
6 | VCC | Power supply 2.3V~5.5V DC | |
7 | GND | Ground |
As you can see you can set various modes via M0 and M1 pins.
Modalità | M1 | M0 | Spiegazione |
---|---|---|---|
Normale | 0 | 0 | UART e il canale wireless sono aperti, la trasmissione trasparente è attiva (supporta la configurazione via etere tramite comando speciale) |
Modalità WOR | 0 | 1 | Può essere impostato come trasmettitore WOR e ricevitore WOR |
Modalità configurazione | 1 | 0 | Gli utenti possono accedere al registro tramite la porta seriale per controllare lo stato di funzionamento del modulo |
Modalità Deep sleep | 1 | 1 | Sleep mode |
Ci sono alcuni pin che possono essere usati in modo statico, ma se li colleghi al microcontrollore e li fai gestire alla libreria ottieni prestazioni migliori e puoi controllare tutte le modalità tramite software, ma spiegheremo meglio in seguito.
Schema di connessione completo
Come già detto, non è importante collegare tutti i pin all’uscita del microcontrollore, è possibile impostare i pin M0 e M1 su HIGH o LOW per ottenere la configurazione desiderata e, se non si collega il pin AUX, la libreria imposterà un ritardo ragionevole per essere sicuri che l’operazione sia completa, ma se hai problemi, ad esempio ti si freeze il dispositivo è preferibile mettere una restistenza di pull-up da 4.7k o meglio collegarlo al dispositivo .
AUX pin
Durante la trasmissione dei dati può essere utilizzato per riattivare l’MCU esterno e restituirà HIGH al termine del trasferimento dei dati.
Quando si riceve AUX viene impostato a LOW e restituisce HIGH quando il buffer è svuotato.
Viene anche utilizzato quando effettua l’autocontrollo per ripristinare il normale funzionamento (all’accensione ed in modalità sospensione/programma).
esp8266
Lo schema di connessione esp8266 è più semplice perché funziona alla stessa tensione delle comunicazioni logiche (3.3 v).
È importante aggiungere una resistenza di pull-up (4,7Kohm) per ottenere una buona stabilità.
E22 | esp8266 |
---|---|
M0 | D7 |
M1 | D6 |
TX | PIN D2 (PullUP 4,7KΩ) |
RX | PIN D3 (PullUP 4,7KΩ) |
AUX | PIN D5 (PullUP 4,7KΩ) |
VCC | 5V (ma consuma meno in 3.3v) |
GND | GND |
esp32
Schema di connessione simile per l’esp32, ma per RX e TX usiamo RX2 e TX2, perché per impostazione predefinita esp32 non ha il SoftwareSerial ma ha 3 Serial.
E22 | esp32 |
---|---|
M0 | D21 |
M1 | D19 |
TX | PIN RX2 (PullUP 4,7KΩ) |
RX | PIN TX3 (PullUP 4,7KΩ) |
AUX | PIN D18 (PullUP 4,7KΩ) |
VCC | 5V (consuma meno a 3.3v) |
GND | GND |
Arduino
La tensione di lavoro di Arduino è 5v, quindi è necessario aggiungere un partitore di tensione sul pin RX del modulo LoRa per prevenire danni, è possibile ottenere maggiori informazioni qui Partitore di tensione (voltage divider): calcolatore e applicazioni.
È possibile utilizzare una resistenza da 2Kohm su GND e 1Kohm dal segnale e poi insieme su RX.
M0 | 7 (voltage divider) |
M1 | 6 (voltage divider) |
TX | PIN 2 (PullUP 4,7KΩ) |
RX | PIN 3 (PullUP 4,7KΩ & Voltage divider) |
AUX | PIN 5 (PullUP 4,7KΩ) |
VCC | 5V |
GND | GND |
Arduino MKR WiFi 1010
M0 | 2 (voltage divider) |
M1 | 3 (voltage divider) |
TX | PIN 14 Tx (PullUP 4,7KΩ) |
RX | PIN 13 Rx (PullUP 4,7KΩ) |
AUX | PIN 1 (PullUP 4,7KΩ) |
VCC | 5V |
GND | GND |
Costruttore
Ho creato una serie di costruttori abbastanza numerosi, perché possiamo avere più opzioni e situazioni da gestire.
LoRa_E22(byte txE22pin, byte rxE22pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E22(byte txE22pin, byte rxE22pin, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E22(byte txE22pin, byte rxE22pin, byte auxPin, byte m0Pin, byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
Il primo set di costruttori è stato creato per delegare la gestione della seriale software e altri pin alla libreria.
rxPin
etxPin
sono i pin per connettersi all’UART e sono obbligatori.auxPin
è un pin che controlla lo stato delle operazioni, come la trasmissione e lo stato di ricezione (spiegheremo meglio in seguito), quel pin non è obbligatorio, se non lo si imposta applico un ritardo per consentire all’operazione di completarsi (con latenza maggiore, ma se hai problemi, ad esempio ti si freeze il dispositivo è preferibile mettere una restistenza di pull-up da 4.7k o meglio collegarlo al dispositivo ).m0pin
em1Pin
sono i pin per cambiare il funzionamento MODE (vedere la tabella in alto), penso che questi pin in “produzione” si collegheranno direttamente HIGH o LOW, ma per il test è utile farli gestire dalla libreria.bpsRate
è il baud rate della seriale normalmente è 9600 (l’unico baud rate in modalità programmin/sleep)
Un semplice esempio è:
#include "LoRa_E22.h"
LoRa_E32 e22ttl100(2, 3); // e22 TX e22 RX
// LoRa_E32 e32ttl100(2, 3, 5, 6, 7); // e22 TX e22 RX
Possiamo usare direttamente un SoftwareSerial con un altro costruttore
LoRa_E22(HardwareSerial* serial, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E22(HardwareSerial* serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E22(HardwareSerial* serial, byte auxPin, byte m0Pin, byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
L’esempio sopra può essere fatto così.
#include <SoftwareSerial.h>
#include "LoRa_E22.h"
SoftwareSerial mySerial(2, 3); // e22 TX e22 RX
LoRa_E22 e22ttl100(&mySerial);
// LoRa_E22 e22ttl100(&mySerial, 5, 7, 6);
L’ultimo set di costruttori è consente l’uso di un HardwareSerial anziché di nu SoftwareSerial.
LoRa_E22(SoftwareSerial* serial, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E22(SoftwareSerial* serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E22(SoftwareSerial* serial, byte auxPin, byte m0Pin, byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
Per gli esp32 ci sono 3 costruttori specifici in aggiunta, così da permettere di impostare i pin per l’HardWare serial
LoRa_E22(byte txE22pin, byte rxE22pin, HardwareSerial* serial, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600, uint32_t serialConfig = SERIAL_8N1);
LoRa_E22(byte txE22pin, byte rxE22pin, HardwareSerial* serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600, uint32_t serialConfig = SERIAL_8N1);
LoRa_E22(byte txE22pin, byte rxE22pin, HardwareSerial* serial, byte auxPin, byte m0Pin, byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600, uint32_t serialConfig = SERIAL_8N1);
Begin
Il comando begin
viene utilizzato per avviare seriale e pin in modalità input e output.
void begin();
in esecuzione sarà:
// Startup all pins and UART
e22ttl100.begin();
Metodo per configurazione ed informazioni
Esiste una serie di metodi per gestire la configurazione e ottenere informazioni sul dispositivo.
ResponseStructContainer getConfiguration();
ResponseStatus setConfiguration(Configuration configuration, PROGRAM_COMMAND saveType = WRITE_CFG_PWR_DWN_LOSE);
ResponseStructContainer getModuleInformation();
void printParameters(struct Configuration configuration);
ResponseStatus resetModule();
Response container
Per semplificare la gestione della risposta, ho creato un insieme di contenitori, per me utili per gestire gli errori e restituire dati generici.
ResponseStatus
Questo è un contenitore di stato e ha 2 semplici punti di ingresso, da qui puoi ottenere il codice di stato e la descrizione del codice di stato
Serial.println(c.getResponseDescription()); // Description of code
Serial.println(c.code); // 1 if Success
The code are
SUCCESS = 1,
ERR_E22_UNKNOWN,
ERR_E22_NOT_SUPPORT,
ERR_E22_NOT_IMPLEMENT,
ERR_E22_NOT_INITIAL,
ERR_E22_INVALID_PARAM,
ERR_E22_DATA_SIZE_NOT_MATCH,
ERR_E22_BUF_TOO_SMALL,
ERR_E22_TIMEOUT,
ERR_E22_HARDWARE,
ERR_E22_HEAD_NOT_RECOGNIZED
ResponseContainer
Questo contenitore è stato creato per gestire la risposta in formato stringa e ha 2 punti di ingresso.
data
che corrisponde alla stringa ritornata dal messaggio e status
un'istanza del RepsonseStatus
.
ResponseContainer rs = e22ttl.receiveMessage();
String message = rs.data;
Serial.println(rs.status.getResponseDescription());
Serial.println(message);
ma questo comando va a leggere tutti i dati nel buffer, se ricevi 3 messaggi leggerai tutti e 3 i messaggi in una volta, la mia semplice soluzione è usare un carattere di fine da inviare alla fine del messaggio, di default uso \0 (carattere nullo)
ResponseContainer rs = e22ttl.receiveMessageUntil();
// You can specify a custom delimiter also
// ResponseContainer rs = e22ttl.receiveMessageUntil('|');
String message = rs.data;
Serial.println(rs.status.getResponseDescription());
Serial.println(message);
Questa versione del dispositivo supporta anche RSSI, per leggere quel parametro (se specifichi nella configurazione che vuoi inviare anche quello), puoi usare
ResponseContainer rc = e22ttl.receiveMessageRSSI();
String message = rs.data;
Serial.println(rs.status.getResponseDescription());
Serial.println(message);
Serial.print("RSSI: "); Serial.println(rc.rssi, DEC);
ResponseStructContainer
Questo è il contenitore più “complesso”, lo uso per gestire la struttura, ha lo stesso punto di ingresso di ResponseContainer ma i dati sono un puntatore void per gestire la struttura complessa.
ResponseStructContainer c;
c = e22ttl100.getConfiguration();
// It's important get configuration pointer before all other operation
Configuration configuration = *(Configuration*) c.data;
Serial.println(c.status.getResponseDescription());
Serial.println(c.status.code);
c.close();
Se ricevi un messaggio di struttura con RSSI puoi usare
ResponseStructContainer rsc = e22ttl.receiveMessageRSSI(sizeof(Message));
Serial.println(rsc.status.getResponseDescription());
struct Message message = *(Message*) rsc.data;
Serial.println(message.type);
Serial.println(message.message);
Serial.println(*(float*)(message.temperature));
Serial.print("RSSI: "); Serial.println(rsc.rssi, DEC);
rsc.close();
Presta attenzione, ogni volta che richiami ResponseStructContainer
devi richiamare la relativa close()
per liberare la memoria allocata.
getConfiguration and setConfiguration
Il primo metodo è getConfiguration, e permette di recuperare tutti i dati di configurazione memorizzati sul dispositivo.
ResponseStructContainer getConfiguration();
Ecco un semplice esempio:
ResponseStructContainer c;
c = e32ttl100.getConfiguration();
// It's important get configuration pointer before all other operation
Configuration configuration = *(Configuration*) c.data;
Serial.println(c.status.getResponseDescription());
Serial.println(c.status.code);
Serial.println(configuration.SPED.getUARTBaudRate());
c.close();
La struttura della configurazione ha tutti i dati delle impostazioni e aggiungo una serie di funzioni per ottenere tutta la descrizione dei singoli dati.
configuration.ADDL = 0x03; // First part of address
configuration.ADDH = 0x00; // Second part
configuration.NETID = 0x00; // NETID used for repeater function
configuration.CHAN = 23; // Communication channel
configuration.SPED.uartBaudRate = UART_BPS_9600; // Serial baud rate
configuration.SPED.airDataRate = AIR_DATA_RATE_010_24; // Air baud rate
configuration.SPED.uartParity = MODE_00_8N1; // Parity bit
configuration.OPTION.subPacketSetting = SPS_240_00; // Packet size
configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_DISABLED; // Need to send special command
configuration.OPTION.transmissionPower = POWER_22; // Device power
configuration.TRANSMISSION_MODE.enableRSSI = RSSI_DISABLED; // Enable RSSI info
configuration.TRANSMISSION_MODE.fixedTransmission = FT_TRANSPARENT_TRANSMISSION; // Transmission type
configuration.TRANSMISSION_MODE.enableRepeater = REPEATER_DISABLED; // Enable repeater mode
configuration.TRANSMISSION_MODE.enableLBT = LBT_DISABLED; // Check interference
configuration.TRANSMISSION_MODE.WORTransceiverControl = WOR_RECEIVER; // Enable WOR mode
configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011; // WOR timing
Hai una funzione equivalente ad ogni attributo per ottenere la descrizione:
DEBUG_PRINT(F("HEAD : ")); DEBUG_PRINT(configuration.COMMAND, HEX);DEBUG_PRINT(" ");DEBUG_PRINT(configuration.STARTING_ADDRESS, HEX);DEBUG_PRINT(" ");DEBUG_PRINTLN(configuration.LENGHT, HEX);
DEBUG_PRINTLN(F(" "));
DEBUG_PRINT(F("AddH : ")); DEBUG_PRINTLN(configuration.ADDH, HEX);
DEBUG_PRINT(F("AddL : ")); DEBUG_PRINTLN(configuration.ADDL, HEX);
DEBUG_PRINT(F("NetID : ")); DEBUG_PRINTLN(configuration.NETID, HEX);
DEBUG_PRINTLN(F(" "));
DEBUG_PRINT(F("Chan : ")); DEBUG_PRINT(configuration.CHAN, DEC); DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.getChannelDescription());
DEBUG_PRINTLN(F(" "));
DEBUG_PRINT(F("SpeedParityBit : ")); DEBUG_PRINT(configuration.SPED.uartParity, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.SPED.getUARTParityDescription());
DEBUG_PRINT(F("SpeedUARTDatte : ")); DEBUG_PRINT(configuration.SPED.uartBaudRate, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.SPED.getUARTBaudRateDescription());
DEBUG_PRINT(F("SpeedAirDataRate : ")); DEBUG_PRINT(configuration.SPED.airDataRate, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.SPED.getAirDataRateDescription());
DEBUG_PRINTLN(F(" "));
DEBUG_PRINT(F("OptionSubPacketSett: ")); DEBUG_PRINT(configuration.OPTION.subPacketSetting, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.OPTION.getSubPacketSetting());
DEBUG_PRINT(F("OptionTranPower : ")); DEBUG_PRINT(configuration.OPTION.transmissionPower, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.OPTION.getTransmissionPowerDescription());
DEBUG_PRINT(F("OptionRSSIAmbientNo: ")); DEBUG_PRINT(configuration.OPTION.RSSIAmbientNoise, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.OPTION.getRSSIAmbientNoiseEnable());
DEBUG_PRINTLN(F(" "));
DEBUG_PRINT(F("TransModeWORPeriod : ")); DEBUG_PRINT(configuration.TRANSMISSION_MODE.WORPeriod, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.TRANSMISSION_MODE.getWORPeriodByParamsDescription());
DEBUG_PRINT(F("TransModeTransContr: ")); DEBUG_PRINT(configuration.TRANSMISSION_MODE.WORTransceiverControl, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.TRANSMISSION_MODE.getWORTransceiverControlDescription());
DEBUG_PRINT(F("TransModeEnableLBT : ")); DEBUG_PRINT(configuration.TRANSMISSION_MODE.enableLBT, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.TRANSMISSION_MODE.getLBTEnableByteDescription());
DEBUG_PRINT(F("TransModeEnableRSSI: ")); DEBUG_PRINT(configuration.TRANSMISSION_MODE.enableRSSI, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.TRANSMISSION_MODE.getRSSIEnableByteDescription());
DEBUG_PRINT(F("TransModeEnabRepeat: ")); DEBUG_PRINT(configuration.TRANSMISSION_MODE.enableRepeater, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.TRANSMISSION_MODE.getRepeaterModeEnableByteDescription());
DEBUG_PRINT(F("TransModeFixedTrans: ")); DEBUG_PRINT(configuration.TRANSMISSION_MODE.fixedTransmission, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.TRANSMISSION_MODE.getFixedTransmissionDescription());
Allo stesso modo setConfiguration vuole una struttura Configuration
, e penso che il modo migliore per gestire la configurazione sia recuperare quella attuale, applicare l’unica modifica necessaria e reimpostarla.
ResponseStatus setConfiguration(Configuration configuration, PROGRAM_COMMAND saveType = WRITE_CFG_PWR_DWN_LOSE);
configuration
è la struttura vista prima, saveType
permette di rendere persistente le scelte che tu hai fatto, in alternativa dureranno fino al riavvio.
ResponseStructContainer c;
c = e32ttl100.getConfiguration();
// It's important get configuration pointer before all other operation
Configuration configuration = *(Configuration*) c.data;
Serial.println(c.status.getResponseDescription());
Serial.println(c.status.code);
printParameters(configuration);
configuration.ADDL = 0x03; // First part of address
configuration.ADDH = 0x00; // Second part
configuration.NETID = 0x00; // NETID used for repeater function
configuration.CHAN = 23; // Communication channel
configuration.SPED.uartBaudRate = UART_BPS_9600; // Serial baud rate
configuration.SPED.airDataRate = AIR_DATA_RATE_010_24; // Air baud rate
configuration.SPED.uartParity = MODE_00_8N1; // Parity bit
configuration.OPTION.subPacketSetting = SPS_240_00; // Packet size
configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_DISABLED; // Need to send special command
configuration.OPTION.transmissionPower = POWER_22; // Device power
configuration.TRANSMISSION_MODE.enableRSSI = RSSI_DISABLED; // Enable RSSI info
configuration.TRANSMISSION_MODE.fixedTransmission = FT_TRANSPARENT_TRANSMISSION; // Transmission type
configuration.TRANSMISSION_MODE.enableRepeater = REPEATER_DISABLED; // Enable repeater mode
configuration.TRANSMISSION_MODE.enableLBT = LBT_DISABLED; // Check interference
configuration.TRANSMISSION_MODE.WORTransceiverControl = WOR_RECEIVER; // Enable WOR mode
configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011; // WOR timing
// Set configuration changed and set to not hold the configuration
ResponseStatus rs = e32ttl100.setConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE);
Serial.println(rs.getResponseDescription());
Serial.println(rs.code);
printParameters(configuration);
c.close()
I parametri sono tutti gestiti come costanti:
Opzioni base della configurazione
Name | Description | Address |
---|---|---|
ADDH | Indirizzo High del modulo (impostazione predefinita 00H) | 00H |
ADDL | Indirizzo Low del modulo (impostazione predefinita 00H) | 01H |
SPED | Informazioni sul bit di parità della velocità dei dati e sulla velocità dei dati via etere | 02H |
OPTION | Tipo di trasmissione, dimensione del pacchetto, abilitazione comandi speciali | 03H |
CHAN | Canale di comunicazione(410M + CHAN*1M), default 17H (433MHz), valido solo per i dispositivi a 433Mhz controlla sotto per cambiare la frequenza | 04H |
TRANSMISSION_MODE | Molti parametri per specificare le varie modalità di trasmissione | 06H |
CRYPT | Encryption per evitare intercettazioni | 07H |
SPED detail
Bit di parità UART: la modalità UART può essere diversa tra le parti di comunicazione
UART parity bit | Constant value |
---|---|
8N1 (default) | MODE_00_8N1 |
8O1 | MODE_01_8O1 |
8E1 | MODE_10_8E1 |
8N1 (equal to 00) | MODE_11_8N1 |
Velocità di trasmissione UART: la velocità di trasmissione UART può essere diversa tra le parti di comunicazione, la velocità di trasmissione UART non ha nulla a che fare con i parametri di trasmissione wireless e non influisce sulle funzioni di trasmissione/ricezione wireless.
TTL UART baud rate(bps) | Constant value |
---|---|
1200 | UART_BPS_1200 |
2400 | UART_BPS_2400 |
4800 | UART_BPS_4800 |
9600 (default) | UART_BPS_9600 |
19200 | UART_BPS_19200 |
38400 | UART_BPS_38400 |
57600 | UART_BPS_57600 |
115200 | UART_BPS_115200 |
Air data rate: più bassa è l’Air data rate, più lunga è la distanza di trasmissione, migliori prestazioni anti-interferenza e tempo di trasmissione più lungo. L’ Air data rate deve essere la stessa per entrambe le parti di comunicazione.
Air data rate(bps) | Constant value |
---|---|
0.3k | AIR_DATA_RATE_000_03 |
1.2k | AIR_DATA_RATE_001_12 |
2.4k (default) | AIR_DATA_RATE_010_24 |
4.8k | AIR_DATA_RATE_011_48 |
9.6k | AIR_DATA_RATE_100_96 |
19.2k | AIR_DATA_RATE_101_192 |
38.4k | AIR_DATA_RATE_110_384 |
62.5k | AIR_DATA_RATE_111_625 |
OPTION detail
Sub packet setting
Questa è la lunghezza massima del pacchetto.
Quando i dati sono più piccoli della lunghezza del sotto pacchetto, l’uscita seriale dell’estremità ricevente è un’uscita continua ininterrotta. Quando i dati sono maggiori della lunghezza del pacchetto secondario, la porta seriale dell’estremità ricevente emetterà il pacchetto secondario.
Packet size | Constant value |
---|---|
240bytes (default) | SPS_240_00 |
128bytes | SPS_128_01 |
64bytes | SPS_064_10 |
32bytes | SPS_032_11 |
Abilitazione rumore ambientale RSSI
Questo comando può abilitare / disabilitare il tipo di gestione di RSSI, è importante per la gestione della configurazione remota wireless, prestare attenzione non è il parametro RSSI nel messaggio.
Quando abilitato, i comandi C0 C1 C2 C3 possono essere inviati in modalità di trasmissione o in modalità di trasmissione WOR per leggere il registro.
RSSI Ambient noise enable | Constant value |
---|---|
Enable | RSSI_AMBIENT_NOISE_ENABLED |
Disable (default) | RSSI_AMBIENT_NOISE_DISABLED |
Potenza trasmissione
È possibile modificare questo insieme di costanti applicando una definizione in questo modo:
#define E22_22 // default value without set
Applicabile agli E22 con 22dBm come massima potenza.
La trasmissione a bassa potenza non è consigliata a causa della sua bassa efficienza di alimentazione.
Transmission power (approximation) | Constant value |
---|---|
22dBm (default) | POWER_22 |
17dBm | POWER_17 |
13dBm | POWER_13 |
10dBm | POWER_10 |
Applicabile agli E22 con con 30dBm di potenza massima.
La trasmissione a bassa potenza non è consigliata a causa della sua bassa efficienza di alimentazione.
#define E22_30
Transmission power (approximation) | Constant value |
---|---|
30dBm (default) | POWER_30 |
27dBm | POWER_27 |
24dBm | POWER_24 |
21dBm | POWER_21 |
È possibile configurare la frequenza del canale anche con queste define:
// One of
#define FREQUENCY_433
#define FREQUENCY_170
#define FREQUENCY_470
#define FREQUENCY_868
#define FREQUENCY_915
TRANSMISSION_MODE Detail
Abilitazione RSSI
Quando abilitato, il modulo riceve i dati wireless e seguirà un byte di RSSI dopo l’output tramite la porta seriale TXD
Enable RSSI | Constant value |
---|---|
Enable | RSSI_ENABLED |
Disable (default) | RSSI_DISABLED |
Tipo di trasmissione
Modalità di trasmissione: in modalità di trasmissione fissa, i primi tre byte del frame di dati di ciascun utente possono essere utilizzati come indirizzo alto/basso e canale. Il modulo cambia indirizzo e canale durante la trasmissione. E tornerà alle impostazioni originali dopo aver completato il processo.
Fixed transmission enabling bit | Constant value |
---|---|
Fixed transmission mode | FT_FIXED_TRANSMISSION |
Transparent transmission mode (default) | FT_TRANSPARENT_TRANSMISSION |
Abilita la funzione ripetitore
Enable repeater | Constant value |
---|---|
Enable repeater | REPEATER_ENABLED |
Disable repeater (default) | REPEATER_DISABLED |
Monitorare i dati prima della trasmissione
Se abilitato, i dati wireless verranno monitorati prima di essere trasmessi, il che può evitare interferenze, ma potrebbe causare ritardi nei dati.
LBT enable byte | Constant value |
---|---|
Enable | LBT_ENABLED |
Disable (default) | LBT_DISABLED |
WOR
Trasmettitore WOR: le funzioni di ricezione e trasmissione del modulo sono attivate e viene aggiunto un preambolo di attivazione durante la trasmissione dei dati. La ricezione è attivata.
Ricevitore WOR: il modulo non è in grado di trasmettere dati e funziona in modalità di monitoraggio WOR. Il periodo di monitoraggio può far risparmiare molta energia.
WOR | Constant value |
---|---|
WOR transmitter | WOR_TRANSMITTER |
WOR receiver (default) | WOR_RECEIVER |
WOR cycle
Se sta trasmettendo: dopo che il ricevitore riceve i dati wireless e li emette attraverso la porta seriale, attenderà 1000ms prima di entrare nuovamente nella modalità WOR. Gli utenti possono inserire i dati della porta seriale e restituirli tramite il wireless durante questo periodo. Ogni byte seriale verrà aggiornato per 1000 ms. Gli utenti devono trasmettere il primo byte entro 1000 ms.
- Periodo T = (1 + WOR) * 500 ms, massimo 4000 ms, minimo 500 ms
- Più lungo è il periodo dell’intervallo di monitoraggio, minore è il consumo energetico medio, ma maggiore è il ritardo dei dati
- Sia il trasmettitore che il ricevitore devono essere impostati alla stessa maniera (molto importante).
Wireless wake-up time | Constant value |
---|---|
500ms | WAKE_UP_500 |
1000ms | WAKE_UP_1000 |
1500ms | WAKE_UP_1500 |
2000ms (default) | WAKE_UP_2000 |
2500ms | WAKE_UP_2500 |
3000ms | WAKE_UP_3000 |
3500ms | WAKE_UP_3500 |
4000ms | WAKE_UP_4000 |
Controllare la disponibilità dei dati nel buffer
Per prima cosa dobbiamo introdurre un metodo semplice ma utile per verificare se c’è qualcosa nel buffer di ricezione
int available();
It’s simply return how many bytes you have in the current stream.
Inviare e ricevere messaggi
Normal transmission mode
La modalità di trasmissione normale/trasparente viene utilizzata per inviare messaggi a tutti i dispositivi con lo stesso indirizzo e canale.
Esistono molti metodi per inviare / ricevere messaggi, spiegheremo in dettaglio:
ResponseStatus sendMessage(const String message);
ResponseContainer receiveMessage();
Il primo metodo è sendMessage e viene utilizzato per inviare una stringa a un dispositivo in modalità trasparente.
ResponseStatus rs = e22ttl.sendMessage("Prova");
Serial.println(rs.getResponseDescription());
L’altro dispositivo fa semplicemente sul loop
if (e32ttl.available() > 1){
ResponseContainer rs = e32ttl.receiveMessage();
String message = rs.data; // First ever get the data
Serial.println(rs.status.getResponseDescription());
Serial.println(message);
}
Presta attenzione se ricevi multipli messaggi sul buffer la receiveMessage li andrà a leggere tutti in una volta, per leggerli uno ad uno dovrai usare ResponseContainer rs = e32ttl.receiveMessageUntil();
con un delimitatore alla fine del messaggio.
Se hai abilitato l’RSSI devi usare receiveMessageRSSI
.
Gestire strutture
Se vuoi inviare una struttura complessa puoi usare questo metodo
ResponseStatus sendMessage(const void *message, const uint8_t size);
ResponseStructContainer receiveMessage(const uint8_t size);
Viene utilizzato per inviare la struttura, ad esempio:
struct Messaggione {
char type[5];
char message[8];
bool mitico;
};
struct Messaggione messaggione = {"TEMP", "Peple", true};
ResponseStatus rs = e22ttl.sendMessage(&messaggione, sizeof(Messaggione));
Serial.println(rs.getResponseDescription());
e dall’altra parte puoi ricevere il messaggio così
ResponseStructContainer rsc = e22ttl.receiveMessage(sizeof(Messaggione));
struct Messaggione messaggione = *(Messaggione*) rsc.data;
Serial.println(messaggione.message);
Serial.println(messaggione.mitico);
rsc.close();
Se hai abilitato l’RSSI devi usare receiveMessageRSSI
.
Leggere una parte della struttura
Se si desidera leggere la prima parte del messaggio per gestire più tipi di struttura, è possibile utilizzare questo metodo.
ResponseContainer receiveInitialMessage(const uint8_t size);
Lo creo per ricevere una stringa con tipo o altro per identificare la struttura da caricare.
struct Messaggione { // Partial structure without type
char message[8];
bool mitico;
};
char type[5]; // first part of structure
ResponseContainer rs = e32ttl.receiveInitialMessage(sizeof(type));
// Put string in a char array (not needed)
memcpy ( type, rs.data.c_str(), sizeof(type) );
Serial.println("READ TYPE: ");
Serial.println(rs.status.getResponseDescription());
Serial.println(type);
// Read the rest of structure
ResponseStructContainer rsc = e32ttl.receiveMessage(sizeof(Messaggione));
struct Messaggione messaggione = *(Messaggione*) rsc.data;
rsc.close();
Fixed mode invece del normal mode
Allo stesso modo ho creato una serie di metodi da utilizzare con la trasmissione fissa
Fixed transmission
È necessario modificare solo il metodo di invio, poiché il dispositivo di destinazione non riceve il preambolo con Indirizzo e Canale quando impostato il fixed mode.
Così per la trasmissione di stringhe avrai:
ResponseStatus sendFixedMessage(byte ADDH, byte ADDL, byte CHAN, const String message);
ResponseStatus sendBroadcastFixedMessage(byte CHAN, const String message);
e per le strutture avrai:
ResponseStatus sendFixedMessage(byte ADDH, byte ADDL, byte CHAN, const void *message, const uint8_t size);
ResponseStatus sendBroadcastFixedMessage(byte CHAN, const void *message, const uint8_t size );
Ecco un semplice esempio:
ResponseStatus rs = e22ttl.sendFixedMessage(0, 0, 0x17, &messaggione, sizeof(Messaggione));
// ResponseStatus rs = e22ttl.sendFixedMessage(0, 0, 0x17, "Ciao");
La trasmissione fissa ha più scenari
Se si invia a un dispositivo specifico (trasmissione dei secondi scenari fissi) è necessario aggiungere ADDL, ADDH e CHAN per identificarlo direttamente.
ResponseStatus rs = e22ttl.sendFixedMessage(2, 2, 0x17, "Message to a device");
Se si desidera inviare un messaggio a tutti i dispositivi in un canale specificato, è possibile utilizzare questo metodo.
ResponseStatus rs = e22ttl.sendBroadcastFixedMessage(0x17, "Message to a devices of a channel");
Se si desidera ricevere tutti i messaggi broadcast nella rete, è necessario impostare ADDH e ADDL con BROADCAST_ADDRESS.
ResponseStructContainer c;
c = e22ttl100.getConfiguration();
// It's important get configuration pointer before all other operation
Configuration configuration = *(Configuration*) c.data;
Serial.println(c.status.getResponseDescription());
Serial.println(c.status.code);
printParameters(configuration);
configuration.ADDL = BROADCAST_ADDRESS;
configuration.ADDH = BROADCAST_ADDRESS;
// Set configuration changed and set to not hold the configuration
ResponseStatus rs = e32ttl100.setConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE);
Serial.println(rs.getResponseDescription());
Serial.println(rs.code);
printParameters(configuration);
c.close();
Configurazione wireless
Questo dispositivo supporta la configurazione wireless con comando speciale, ma sembra non funzionare, chiedo a EBYTE ma non ho ricevuto risposta.
Implemento un comando che manda il packet in modo corretto (testato con logic analyzer) ma sembra non funzionare.
Comunque, prima devi attivare la gestione del rumore ambientale RSSI, quindi puoi usare il comando in questo modo:
Configuration configuration;
configuration.ADDL = 0x13;
configuration.ADDH = 0x13;
configuration.NETID = 0x00;
configuration.CHAN = 23;
configuration.SPED.uartBaudRate = UART_BPS_9600;
configuration.SPED.airDataRate = AIR_DATA_RATE_010_24;
configuration.SPED.uartParity = MODE_00_8N1;
configuration.OPTION.subPacketSetting = SPS_240_00;
configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_DISABLED;
configuration.OPTION.transmissionPower = POWER_22;
configuration.TRANSMISSION_MODE.enableRSSI = RSSI_DISABLED;
configuration.TRANSMISSION_MODE.fixedTransmission = FT_FIXED_TRANSMISSION;
configuration.TRANSMISSION_MODE.enableRepeater = REPEATER_DISABLED;
configuration.TRANSMISSION_MODE.enableLBT = LBT_DISABLED;
configuration.TRANSMISSION_MODE.WORTransceiverControl = WOR_TRANSMITTER;
configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011;
// Send message
ResponseStatus rs = e22ttl100.sendConfigurationMessage(0, DESTINATION_ADDL, 23, &configuration);
// Check If there is some problem of successfully send
Serial.println(rs.getResponseDescription());
Grazie
Ora hai tutte le informazioni per svolgere il tuo lavoro, ma penso sia importante mostrare alcuni esempi realistici per capire meglio tutte le possibilità.
- Ebyte LoRa E22 per Arduino, esp32 o esp8266: specifiche ed utilizzo base
- Ebyte LoRa E22 per Arduino, esp32 o esp8266: libreria
- Ebyte LoRa E22 per Arduino, esp32 o esp8266: configurazione
- Ebyte LoRa E22 per Arduino, esp32 o esp8266: trasmissione fissa, broadcast, monitor e RSSI
- Ebyte LoRa E22 per Arduino, esp32 o esp8266: risparmio energetico ed invio di dati strutturati
- Ebyte LoRa E22 per Arduino, esp32 o esp8266: ripetitore e configurazione remota
- Ebyte LoRa E22 per Arduino, esp32 o esp8266: WOR il microcontrollore e lo shield per Arduino
- Ebyte LoRa E22 per Arduino, esp32 o esp8266: WOR il microcontrollore e lo shield per il WeMos D1 mini
- Ebyte LoRa E22 per Arduino, esp32 o esp8266: WOR il microcontrollore e lo shield per l’esp32 dev v1
Shield e PCB