Ebyte LoRa E220 LLCC68 per Arduino, esp32 o esp8266: libreria – 2
La telemetria dati wireless LoRa o Long Range è una tecnologia introdotta da Semtech che opera a una frequenza inferiore rispetto al NRF24L01 (433 MHz, 868 MHz o 916 MHz contro 2,4 GHz per NRF24L01) ma a una distanza tripla (da 5000 m a 11000 m).
LLCC68
LoRa Smart Home (LLCC68) è un ricetrasmettitore RF LoRa® sub-GHz per applicazioni wireless a medio raggio da interno e da interno a esterno. Interfaccia SPI. Pin-to-pin compatibile con SX1262. SX1261, SX1262, SX1268 e LLCC68 sono progettati per una lunga durata della batteria con solo 4,2mA di consumo di corrente in ricezione attiva. L’SX1261 può trasmettere fino a +15 dBm e l’SX1262, SX1268 e LLCC68 possono trasmettere fino a +22 dBm con amplificatori di potenza integrati ad alta efficienza.
Questi dispositivi supportano la modulazione LoRa per i casi d’uso LPWAN e la modulazione (G)FSK per i casi d’uso legacy. I dispositivi sono altamente configurabili per soddisfare i diversi requisiti applicativi per l’uso da parte dei consumatori. Il dispositivo fornisce una modulazione LoRa compatibile con i ricetrasmettitori Semtech utilizzati dalla specifica LoRaWAN® rilasciata da LoRa Alliance®. La radio è adatta per i sistemi che mirano alla conformità alle normative radio, inclusi, a titolo esemplificativo, ETSI EN 300 220, FCC CFR 47 Part 15, requisiti normativi cinesi e ARIB T-108 giapponese. La copertura di frequenza continua da 150 MHz a 960 MHz consente il supporto di tutte le principali bande ISM sub-GHz in tutto il mondo.
Caratteristiche
- La nuova tecnologia di modulazione a spettro esteso LoRa sviluppata sulla base dell’LLCC68, offre una distanza di comunicazione più estesa e una maggiore capacità anti-interferenza;
- Supporta gli utenti nell’impostare da soli la chiave di comunicazione e non può essere letta, il che migliora significativamente la riservatezza dei dati dell’utente;
- Supporta la funzione LBT, monitora il rumore ambientale del canale prima dell’invio, il che migliora significativamente il tasso di successo della comunicazione del modulo in ambienti difficili;
- Supporta la funzione dell’indicatore di potenza del segnale RSSI per valutare la qualità del segnale, per migliorare la rete di comunicazione e l’intervallo;
- Supporta la modalità di risveglio via radio, e questo permette un consumo energetico estremamente basso, adatto per applicazioni alimentate a batteria;
- Supporta la trasmissione punto a punto, la trasmissione broadcast;
- Supporta il deep sleep, il consumo energetico dell’intera macchina è di circa 5uA in questa modalità;
- Il modulo ha PA+LNA integrato e la distanza di comunicazione può raggiungere i 5 km in condizioni ideali;
- I parametri vengono salvati dopo lo spegnimento e il modulo funzionerà secondo i parametri impostati dopo l’accensione;
- Design efficiente del watchdog, una volta che si verifica un’eccezione, il modulo si riavvierà automaticamente e continuerà a funzionare secondo le impostazioni dei parametri precedenti;
- Supporta la velocità in bit di 2,4 k~62,5 kbps;
- Supporta l’alimentazione da 3,0 a 5,5 V, l’alimentazione superiore a 5 V può garantire le migliori prestazioni;
- Design standard industriale, che supporta l’uso a lungo termine a -40 + 85 ;
Comparazione
LLCC68 | SX1278-SX1276 | |
---|---|---|
Distanza | > 11Km | 8Km |
Rate (LoRa) | 1.76Kbps – 62.5Kbps | 0.3Kbps – 19.2Kbps |
Consumo energetico durante il sonno | 2µA | 5µA |
Libreria
Puoi trovare la mia libreria qui, ed è disponibile anche dal Library Manager dell’Arduino IDE.
Per scaricare:
Clicca sul bottone DOWNLOADS sull’angolo in alto a destra, e rimonima la cartella decompressa come LoRa_E220.
Controlla che la cartella LoRa_E220 contenga LoRa_E220.cpp e LoRa_E220.h.
Posizione la cartella della libreria LoRa_E220 nella tua cartella /libraries/.
Potresti aver bisogno di creare la cartella libraries se è la prima volta.
Riavvia l’IDE.
Piedinatura
1 | M0 | Input(weak pull-up) | Lavora con M1 e decide le quattro modalità operative. Non può essere lasciato libero, può essere messo a terra. |
2 | M1 | Input(weak pull-up) | Lavora con M1 e decide le quattro modalità operative. Non può essere lasciato libero, può essere messo a terra. |
3 | RXD | Input | Ingressi UART TTL, connessione a pin di uscita TXD esterno (MCU, PC). Può essere configurato come ingresso open-drain o pull-up. |
4 | TXD | Output | Uscite TTL UART, si collega all’inputpin esterno RXD (MCU, PC). Può essere configurato come uscita open-drain o push-pull |
5 | AUX | Output | Per indicare lo stato di funzionamento del modulo e riattivare l’MCU esterno. Durante la procedura di inizializzazione di autocontrollo, il pin emette una bassa tensione. Può essere configurato come uscita open-drain o output push-pull (è consentito non metterlo a terra). |
6 | VCC | Alimentazione 3V~5.5V DC | |
7 | GND | Terra |
Come puoi vedere, puoi impostare varie modalità tramite i pin M0 e M1.
Mode | M1 | M0 | Explanation |
---|---|---|---|
Normal | 0 | 0 | UART e canale wireless sono open, e la transparent transmission è attiva |
WOR Transmitter | 0 | 1 | Trasmettitore WOR (Wake on radio) |
WOR Receiver | 1 | 0 | Ricevitore WOR (Supporta sveglia via radio) |
Deep sleep mode | 1 | 1 | Il modulo va in sleep (ma si sveglia automaticamente quando riceve i parametri di configurazione) |
Alcuni pin possono essere usati staticamente, ma se li colleghi al microcontrollore e li configuri nella libreria, guadagni in prestazioni e puoi controllare tutte le modalità tramite software. Tuttavia, ci spiegheremo meglio in seguito.
Schema completamente connesso
Come ho già detto, non è indispensabile collegare tutti i pin all’uscita del microcontrollore; puoi mettere i pin M0 e M1 su HIGH o LOW per ottenere la configurazione desiderata. Se non si collega AUX, la libreria imposta un ragionevole ritardo per assicurarsi che l’operazione sia completa (se si riscontrano problemi con il blocco del dispositivo, è necessario inserire una resistenza di pull-up da 4.7k o meglio connettersi al dispositivo).
Pin AUX
Durante la trasmissione dei dati può essere utilizzato per riattivare l’MCU e restituire HIGH al termine del trasferimento dati.
Durante la ricezione, AUX diventa LOW e ritorna HIGH quando il buffer è vuoto.
Viene anche utilizzato per l’autocontrollo per ripristinare il normale funzionamento (all’accensione e in modalità sleep/programma).
esp8266
Lo schema di connessione esp8266 è più semplice perché funziona alla stessa tensione delle comunicazioni logiche (3.3v).
È essenziale aggiungere una resistenza di pull-up (4,7Kohm) per ottenere una buona stabilità.
E220 | 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 (but work with less power in 3.3v) |
GND | GND |
esp32
Schema di connessione simile per esp32, ma per RX e TX, utilizziamo RX2 e TX2 perché, per impostazione predefinita, esp32 non ha SoftwareSerial ma ha 3 Serial.
E220 | esp32 |
---|---|
M0 | D21 |
M1 | D19 |
TX | PIN RX2 (PullUP 4,7KΩ) |
RX | PIN TX3 (PullUP 4,7KΩ) |
AUX | PIN D18 (PullUP 4,7KΩ) (D15 to wake up) |
VCC | 5V (but work with less power in 3.3v) |
GND | GND |
Arduino
La tensione di lavoro di Arduino è 5v, quindi dobbiamo aggiungere un partitore di tensione sui pin RX, M0 e M1 del modulo LoRa per evitare danni; puoi ottenere maggiori informazioni qui Partitore di tensione (voltage divider): calcolatore e applicazioni.
Puoi usare un resistore da 2Kohm su GND e 1Kohm dal segnale, quindi metterli insieme sull’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 |
Arduino Nano 33 IoT
M0 | 4 |
M1 | 6 |
RX | PIN PB23 Tx (PullUP 4,7KΩ) |
TX | PIN PB22 Rx (PullUP 4,7KΩ) |
AUX | PIN 2 (PullUP 4,7KΩ) |
VCC | 5V |
GND | GND |
// ------------- Arduino Nano 33 IoT -------------
// LoRa_E220 e220ttl(&Serial1, 2, 4, 6); // RX AUX M0 M1
// -------------------------------------------------
Costruttore
Ho creato un insieme di costruttori abbastanza numeroso, perché possiamo avere più opzioni e situazioni da gestire.
LoRa_E220(byte txE220pin, byte rxE220pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E220(byte txE220pin, byte rxE220pin, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E220(byte txE220pin, byte rxE220pin, byte auxPin, byte m0Pin, byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
Viene creato il primo set di costruttori per delegare la gestione della Serial e altri pin alla libreria.
txE220pin
edrxE220pin
sono i pin per connettersi all’UART e sono obbligatori .auxPin
è un pin che controlla lo stato di funzionamento, trasmissione e ricezione (ci spiegheremo meglio in seguito), quel pin Non è obbligatorio , se non lo imposti applico un ritardo per permettere che l’operazione si completi (con latenza, se hai problemi, come il dispositivo di blocco, devi mettere un resistore di pull-up da 4.7k o meglio connetterti al dispositivo ).m0pin
em1Pin
sono i pin per cambiare MODALITÀ di funzionamento (vedi tabella in alto), penso che questi pin in “produzione” andranno a collegarsi direttamente HIGH o LOW, ma per i test sono gestiti dalla libreria.bpsRate
è il boudrate di SoftwareSerial normalmente è 9600 (l’unico baud rate in modalità programmazione/sleep)
Un semplice esempio è
#include "LoRa_E220.h"
LoRa_E220 e220ttl(2, 3); // e220 TX e220 RX
// LoRa_E220 e220ttl(2, 3, 5, 6, 7); // e220 TX e220 RX
Possiamo usare un SoftwareSerial direttamente con un altro costruttore
LoRa_E220(HardwareSerial* serial, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E220(HardwareSerial* serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E220(HardwareSerial* serial, byte auxPin, byte m0Pin, byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
L’esempio sopra con questo costruttore può essere eseguito in questo modo.
#include <SoftwareSerial.h>
#include "LoRa_E220.h"
SoftwareSerial mySerial(2, 3); // e220 TX e220 RX
LoRa_E220 e220ttl(&mySerial);
// LoRa_E220 e220ttl(&mySerial, 5, 7, 6);
L’ultimo set di costruttori è quello di consentire un HardwareSerial invece di SoftwareSerial.
LoRa_E220(SoftwareSerial* serial, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E220(SoftwareSerial* serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
LoRa_E220(SoftwareSerial* serial, byte auxPin, byte m0Pin, byte m1Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
Per l’esp32, hai tre costruttori aggiuntivi per consentire la gestione dei pin per la seriale HardWare.
LoRa_E220(byte txE220pin, byte rxE220pin, HardwareSerial* serial, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600, uint32_t serialConfig = SERIAL_8N1);
LoRa_E220(byte txE220pin, byte rxE220pin, HardwareSerial* serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600, uint32_t serialConfig = SERIAL_8N1);
LoRa_E220(byte txE220pin, byte rxE220pin, 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 la Serial e pins in modalità input e output.
void begin();
in esecuzione è
// Startup all pins and UART
e220ttl.begin();
Configurazione e metodo per le informazione
Esistono molti 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();
Contenitori in risposta
Per semplificare la gestione della risposta, ho creato un set di contenitori, molto utile per gestire gli errori e restituire dati generici.
ResponseStatus
ResponseStatus
è un contenitore in risposta con 2 semplici punti di ingresso, con questo 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
I codici sono
E220_SUCCESS = 1,
ERR_E220_UNKNOWN,
ERR_E220_NOT_SUPPORT,
ERR_E220_NOT_IMPLEMENT,
ERR_E220_NOT_INITIAL,
ERR_E220_INVALID_PARAM,
ERR_E220_DATA_SIZE_NOT_MATCH,
ERR_E220_BUF_TOO_SMALL,
ERR_E220_TIMEOUT,
ERR_E220_HARDWARE,
ERR_E220_HEAD_NOT_RECOGNIZED
ResponseContainer
Questo contenitore è stato creato per gestire la risposta String e ha due punti di ingresso.
data
con la stringa restituita dal messaggio e status
un’istanza di RepsonseStatus
.
ResponseContainer rs = e220ttl.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 tre messaggi, leggerai tutte e tre le informazioni contemporaneamente, la mia soluzione è usare un carattere finale da inviare alla fine del messaggio, per impostazione predefinita uso \0 (carattere nullo)
ResponseContainer rs = e220ttl.receiveMessageUntil();
// You can specify a custom delimiter also
// ResponseContainer rs = e220ttl.receiveMessageUntil('|');
String message = rs.data;
Serial.println(rs.status.getResponseDescription());
Serial.println(message);
Questa versione del dispositivo supporta anche l’RSSI. Per leggere quel parametro (se specifichi nella configurazione che vuoi inviare anche quello), puoi usare
ResponseContainer rc = e220ttl.receiveMessageRSSI();
String message = rs.data;
Serial.println(rs.status.getResponseDescription());
Serial.println(message);
Serial.print("RSSI: "); Serial.println(rc.rssi, DEC);
ResponseStructContainer
Il ResponseStructContainer
è il contenitore più “complesso”. Lo uso per gestire le strutture, ha gli stessi punti di ingresso di ResponseContainer, ma i dati sono un puntatore void per gestire la struttura complessa.
ResponseStructContainer c;
c = e220ttl.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 strutturato con RSSI, puoi usare
ResponseStructContainer rsc = e220ttl.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();
Ogni volta che usi un ResponseStructContainer
devi chiuderlo con close()
getConfiguration e setConfiguration
Il primo metodo è getConfiguration e puoi usarlo per recuperare tutti i dati archiviati sul dispositivo.
ResponseStructContainer getConfiguration();
Ecco un esempio di utilizzo.
ResponseStructContainer c;
c = e220ttl.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 tutte le descrizioni dei singoli dati.
configuration.ADDL = 0x03; // First part of address
configuration.ADDH = 0x00; // Second part
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_200_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; // Enable repeater mode
configuration.TRANSMISSION_MODE.enableLBT = LBT_DISABLED; // Check interference
configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011; // WOR timing
Hai la funzione equivalente per tutti gli attributi per ottenere tutte le descrizioni:
void printParameters(struct Configuration configuration) {
Serial.println("----------------------------------------");
Serial.print(F("HEAD : ")); Serial.print(configuration.COMMAND, HEX);Serial.print(" ");Serial.print(configuration.STARTING_ADDRESS, HEX);Serial.print(" ");Serial.println(configuration.LENGHT, HEX);
Serial.println(F(" "));
Serial.print(F("AddH : ")); Serial.println(configuration.ADDH, HEX);
Serial.print(F("AddL : ")); Serial.println(configuration.ADDL, HEX);
Serial.println(F(" "));
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.getUARTBaudRateDescription());
Serial.print(F("SpeedAirDataRate : ")); Serial.print(configuration.SPED.airDataRate, BIN);Serial.print(" -> "); Serial.println(configuration.SPED.getAirDataRateDescription());
Serial.println(F(" "));
Serial.print(F("OptionSubPacketSett: ")); Serial.print(configuration.OPTION.subPacketSetting, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getSubPacketSetting());
Serial.print(F("OptionTranPower : ")); Serial.print(configuration.OPTION.transmissionPower, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getTransmissionPowerDescription());
Serial.print(F("OptionRSSIAmbientNo: ")); Serial.print(configuration.OPTION.RSSIAmbientNoise, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getRSSIAmbientNoiseEnable());
Serial.println(F(" "));
Serial.print(F("TransModeWORPeriod : ")); Serial.print(configuration.TRANSMISSION_MODE.WORPeriod, BIN);Serial.print(" -> "); Serial.println(configuration.TRANSMISSION_MODE.getWORPeriodByParamsDescription());
Serial.print(F("TransModeEnableLBT : ")); Serial.print(configuration.TRANSMISSION_MODE.enableLBT, BIN);Serial.print(" -> "); Serial.println(configuration.TRANSMISSION_MODE.getLBTEnableByteDescription());
Serial.print(F("TransModeEnableRSSI: ")); Serial.print(configuration.TRANSMISSION_MODE.enableRSSI, BIN);Serial.print(" -> "); Serial.println(configuration.TRANSMISSION_MODE.getRSSIEnableByteDescription());
Serial.print(F("TransModeFixedTrans: ")); Serial.print(configuration.TRANSMISSION_MODE.fixedTransmission, BIN);Serial.print(" -> "); Serial.println(configuration.TRANSMISSION_MODE.getFixedTransmissionDescription());
Serial.println("----------------------------------------");
}
Allo stesso modo, setConfiguration vuole una struttura di configurazione, quindi penso che il modo migliore per gestire la configurazione sia recuperare quella corrente, applicare l’unica modifica necessaria e impostarla di nuovo.
ResponseStatus setConfiguration(Configuration configuration, PROGRAM_COMMAND saveType = WRITE_CFG_PWR_DWN_LOSE);
configuration
è la struttura mostrata in precedenza, saveType
consente di scegliere se il cambio diventa permanente o solo per la sessione corrente.
ResponseStructContainer c;
c = e220ttl1.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.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_200_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; // Enable repeater mode
configuration.TRANSMISSION_MODE.enableLBT = LBT_DISABLED; // Check interference
configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011; // WOR timing
// Set configuration changed and set to not hold the configuration
ResponseStatus rs = e220ttl.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:
Opzione di configurazione di base
Name | Description | Address |
---|---|---|
ADDH | High address byte of the module (the default 00H) | 00H |
ADDL | Low address byte of the module (the default 00H) | 01H |
SPED | Information about data rate parity bit and Air data rate | 02H |
OPTION | Type of transmission, pull-up settings, wake-up time, FEC, Transmission power | 03H |
CHAN | Communication channel(410M + CHAN*1M), default 17H (433MHz), valid only for 433MHz device | 04H |
TRANSMISSION_MODE | All transmission parameters | 05H |
CRTYPT_H | User encryption | 06H |
CRTYPT_L | User encryption | 07H |
Dettaglio SPED
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 (ma non raccomandato), 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 |
---|---|
2.4k | AIR_DATA_RATE_000_24 |
2.4k | AIR_DATA_RATE_001_24 |
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 |
Dettaglio OPTION
Sub packet setting
Questa è la lunghezza massima del pacchetto.
Quando i dati inviati dall’utente sono inferiori alla lunghezza del sottopacchetto, l’uscita seriale del ricevente appare come un’uscita continua. Se i dati sono meno della dimensione verrà inviato in pacchetto.
Packet size | Constant value |
---|---|
200bytes (default) | SPS_200_00 |
128bytes | SPS_128_01 |
64bytes | SPS_064_10 |
32bytes | SPS_032_11 |
RSSI Abilita rumore ambientale
Questo comando può abilitare/disabilitare il tipo di gestione di RSSI. Prestare attenzione non è il parametro RSSI nel messaggio.
Quando abilitati, i comandi C0, C1, C2, C3 possono essere inviati in modalità di trasmissione o in modalità di trasmissione WOR per leggere il registro. Registro 0x00: RSSI rumore ambientale attuale Registro 0X01: RSSI quando i dati sono stati ricevuti l’ultima volta.
RSSI Ambient noise enable | Constant value |
---|---|
Enable | RSSI_AMBIENT_NOISE_ENABLED |
Disable (default) | RSSI_AMBIENT_NOISE_DISABLED |
Potenza di trasmissione
Puoi modificare questo insieme di costanti applicando una definizione in questo modo:
#define E220_22 // default value without set
Applicabile per E220 con 22dBm come potenza massima.
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 |
Applicable for E220 with 30dBm as max power.
La trasmissione a bassa potenza non è consigliata a causa della sua bassa efficienza di alimentazione.
#define E220_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 con questa definizione:
// One of
#define FREQUENCY_433
#define FREQUENCY_170
#define FREQUENCY_470
#define FREQUENCY_868
#define FREQUENCY_915
Dettaglio TRANSMISSION_MODE
Abilita RSSI
Quando abilitato, il modulo riceve dati wireless e seguirà un byte di forza RSSI dopo l’uscita tramite la porta seriale TXD
Enable RSSI | Constant value |
---|---|
Enable | RSSI_ENABLED |
Disable (default) | RSSI_DISABLED |
Tipo di trasmissione
Modalità di trasmissione: i primi tre byte del frame di dati di ciascun utente possono essere utilizzati come indirizzo alto/basso e canale in modalità di trasmissione fissa. Il modulo cambia indirizzo e canale quando viene trasmesso. E tornerà all’impostazione originale dopo aver completato il processo.
Fixed transmission enabling bit | Constant value |
---|---|
Fixed transmission mode | FT_FIXED_TRANSMISSION |
Transparent transmission mode (default) | FT_TRANSPARENT_TRANSMISSION |
Monitorare i dati prima della trasmissione
Se abilitato, i dati wireless verranno monitorati prima di essere trasmessi, evitando in una certa misura le interferenze, ma potrebbero causare ritardi nei dati.
LBT enable byte | Constant value |
---|---|
Enable | LBT_ENABLED |
Disable (default) | LBT_DISABLED |
Ciclo WOR (Wake on Radio)
Se il WOR sta trasmettendo: dopo che il ricevitore WOR ha ricevuto i dati wireless e li ha emessi tramite la porta seriale, attenderà 1000 ms prima di immettere nuovamente il WOR.
Gli utenti possono inserire i dati della porta seriale e restituirli via 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 WOR, minore è il consumo energetico medio, ma maggiore è il ritardo dei dati
- Sia il trasmettitore che il ricevitore devono essere gli stessi (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 il buffer
Innanzitutto, dobbiamo introdurre un metodo semplice ma pratico per verificare se c’è qualcosa nel buffer di ricezione.
int available();
È semplice restituire quanti byte hai nel flusso corrente.
Invia ricevere messaggi
Modalità di trasmissione normale
La modalità di trasmissione Normale/Trasparente invia messaggi a tutti i dispositivi con lo stesso indirizzo e canale.
Esistono molti metodi per inviare/ricevere messaggi e li 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à Normale.
ResponseStatus rs = e220ttl.sendMessage("Prova");
Serial.println(rs.getResponseDescription());
L’altro dispositivo fa semplicemente il loop.
if (e220ttl.available() > 1){
ResponseContainer rs = e220ttl.receiveMessage();
String message = rs.data; // First ever get the data
Serial.println(rs.status.getResponseDescription());
Serial.println(message);
}
Fai attenzione se ricevi più messaggi nel buffer e non vuoi leggerli tutti in una volta. È necessario utilizzare ResponseContainer rs = e220ttl.receiveMessageUntil();
con un delimitatore inserito alla fine dell’invio di un messaggio.
Se hai abilitato l’RSSI, devi usare receiveMessageRSSI
.
Gestire la struttura
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 = e220ttl.sendMessage(&messaggione, sizeof(Messaggione));
Serial.println(rs.getResponseDescription());
e dall’altra parte puoi ricevere il messaggio così
ResponseStructContainer rsc = e220ttl.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
.
Leggi struttura parziale
Se vuoi leggere la prima parte del messaggio per gestire più tipologie di struttura, puoi 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 = e220ttl.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 = e220ttl.receiveMessage(sizeof(Messaggione));
struct Messaggione messaggione = *(Messaggione*) rsc.data;
rsc.close();
Modalità fissa invece della modalità normale
Allo stesso modo, creo una serie di metodi da utilizzare con la trasmissione fissa.
Trasmissione fissa
È necessario modificare solo il metodo di invio perché il dispositivo di destinazione non riceve il preambolo con Indirizzo e Canale quando si imposta la modalità fissa.
Quindi, per il messaggio String, hai
ResponseStatus sendFixedMessage(byte ADDH, byte ADDL, byte CHAN, const String message);
ResponseStatus sendBroadcastFixedMessage(byte CHAN, const String message);
e per la struttura, hai
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 );
Qui c’è un semplice esempio
ResponseStatus rs = e220ttl.sendFixedMessage(0, 0, 0x17, &messaggione, sizeof(Messaggione));
// ResponseStatus rs = e220ttl.sendFixedMessage(0, 0, 0x17, "Ciao");
La trasmissione fissa ha più scenari
Se si invia a un dispositivo specifico (secondo scenario Trasmissione fissa), è necessario aggiungere ADDL, ADDH e CHAN per identificarlo direttamente.
ResponseStatus rs = e220ttl.sendFixedMessage(2, 2, 0x17, "Message to a device");
Se desideri inviare un messaggio a tutti i dispositivi in un canale specifico, puoi utilizzare questo metodo.
ResponseStatus rs = e220ttl.sendBroadcastFixedMessage(0x17, "Message to a devices of a channel");
Se desideri ricevere tutti i messaggi broadcast nella rete, devi impostare il tuo ADDH
e ADDL
con BROADCAST_ADDRESS
.
ResponseStructContainer c;
c = e220ttl.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 = e220ttl.setConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE);
Serial.println(rs.getResponseDescription());
Serial.println(rs.code);
printParameters(configuration);
c.close();
Grazie
Ora hai tutte le informazioni per fare il tuo lavoro, ma penso che sia importante mostrare alcuni esempi reali per capire meglio tutte le possibilità.
- Ebyte LoRa E220 LLCC68 per Arduino, esp32 o esp8266: specifiche ed utilizzo base
- Ebyte LoRa E220 LLCC68 per Arduino, esp32 o esp8266: libreria
- Ebyte LoRa E220 LLCC68 per Arduino, esp32 o esp8266: configurazione
- Ebyte LoRa E220 LLCC68 per Arduino, esp32 o esp8266: trasmissione fissa, broadcast, monitor e RSSI
- Ebyte LoRa E220 LLCC68 per Arduino, esp32 o esp8266: power saving ed invio di dati strutturati
- Ebyte LoRa E220 LLCC68 per Arduino, esp32 o esp8266: WOR il microcontrollore e lo shield per Arduino
- Ebyte LoRa E220 LLCC68 per Arduino, esp32 o esp8266: WOR il microcontrollore e lo shield per il WeMos D1 mini
- Ebyte LoRa E220 LLCC68 per Arduino, esp32 o esp8266: WOR il microcontrollore e lo shield per l’esp32 dev v1
Shield e PCB
- Mischianti Arduino LoRa shield (Open source)
- Mischianti WeMos LoRa shield (Open source)
- Mischianti ESP32 DOIT DEV KIT v1 shield (Open source)