EByte RF E70 CC1310: andiamo ad esplorare la libreria (esp32, esp8266, STM32, Arduino, Raspberry Pi Pico)
Il mondo della comunicazione wireless è stato rivoluzionato dall’avvento delle tecnologie RF a lunga distanza, che offrono una combinazione di capacità a lungo raggio e basso consumo energetico. Il modulo EByte RF E70 si distingue come un attore prominente tra i vari moduli emergenti. Questo articolo esplora le caratteristiche, le applicazioni e le modalità operative dell’EByte E70, fornendo approfondimenti sulle sue capacità e sui suoi potenziali utilizzi.
L’E70 è basato sul dispositivo della serie CC1310. Questo dispositivo non è solo un microcontrollore (MCU); è un MCU wireless completamente integrato progettato specificamente per applicazioni wireless a basso consumo e lungo raggio. Il CC1310 combina un potente processore ARM Cortex-M3 con una radio sub-1 GHz altamente efficiente, rendendolo una soluzione ideale per una vasta gamma di applicazioni, dai contatori intelligenti all’automazione industriale e al monitoraggio ambientale.
Introduzione all’EByte RF E70
L’EByte E70 è un modulo RF progettato per la comunicazione wireless a lungo raggio. Opera nelle bande di frequenza sub-gigahertz, rendendolo ideale per varie applicazioni che richiedono comunicazioni a lungo raggio e basso consumo energetico. La sua versatilità ed efficienza lo hanno reso una scelta popolare nelle applicazioni IoT (Internet of Things), nei progetti di città intelligenti e nell’automazione industriale.
Caratteristiche principali dell’EByte E70
- Comunicazione a lungo raggio: Il modulo E70 è noto per il suo raggio d’azione eccezionale, in grado di trasmettere dati su diversi chilometri, a seconda delle condizioni ambientali.
- Basso consumo energetico: È ottimizzato per un basso consumo energetico, prolungando la durata della batteria dei dispositivi, cruciale per le applicazioni IoT.
- Modalità operative multiple: L’E70 supporta diverse modalità come la modalità trasparente, modalità fissa, modalità continua e modalità sub-pacchetto, offrendo flessibilità in diversi casi d’uso.
- Parametri configurabili: Gli utenti possono configurare parametri come frequenza, potenza di uscita e velocità di trasmissione dati, rendendoli adattabili a varie esigenze di comunicazione.
- Correzione d’errore in avanti (FEC): La FEC è un metodo per il controllo degli errori nella trasmissione dei dati. Aggiunge ridondanza alle informazioni trasmesse utilizzando un algoritmo predefinito. Questa ridondanza consente al ricevitore di rilevare e correggere gli errori senza la necessità di una ritrasmissione.
Specifiche del dispositivo
- Distanza di comunicazione testata fino a 1.5/6 km
- Potenza massima di trasmissione di 1W, regolabile su più livelli tramite software
- Supporto di velocità di trasmissione via aria da 2,5 kbps a 168 kbps
- Basso consumo energetico per applicazioni alimentate a batteria
- Può raggiungere una trasmissione continua di frame a 115200bps con lunghezza di pacchetto illimitata
- Supporto di alimentazione a 2,6~5,5 V, con più di 5V per garantire le migliori prestazioni
- Progettazione secondo lo standard industriale, supporto per temperature di lavoro da -40 a 85 °C per lunghi periodi
Installazione della libreria
Puoi trovare la libreria su GitHub.
Per semplicità, l’ho anche aggiunta al gestore delle librerie di Arduino.
Varianti RF E70
L’E70 è disponibile in vari formati, con design e specifiche che cambiano.
E70-433T30S:
- Tensione di livello logico: supporto 3.3v e 5v
- Potenza di trasmissione: 30dBm (maggiore potenza, capace di trasmissione a lunga distanza)
- Sensibilità di ricezione: -107 a -109 dBm
- Distanza di riferimento: 6000m
E70-433T14S:
- Tensione di livello logico: solo 3.3v
- Potenza di trasmissione: 14dBm (potenza inferiore rispetto al T30S)
- Sensibilità di ricezione: -109 a -111 dBm per T14S e -108 dBm per T14S2 (leggermente migliore per il T14S)
- Distanza di riferimento: 1500m
E70-433T14S2:
- Tensione di livello logico: solo 3.3v
- Aggiornamento della versione S.
- Sensibilità di ricezione: -109 a -111 dBm per T14S e -108 dBm per T14S2 (leggermente migliore per il T14S)
- I fattori di forma sono più semplici da gestire.
E70-433MT14S:
- Tensione di livello logico: solo 3.3v
- Potenza di trasmissione: 14dBm (come T14S e T14S2)
- Sensibilità di ricezione: -108 dBm (come T14S2)
- Distanza di riferimento: 1500m (come T14S e T14S2)
Parametri RF
Parametri RF | Unità | Modello | Osservazioni | |||
---|---|---|---|---|---|---|
E70-433T30S | E70-433T14S | E70-433T14S2 | E70-433MT14S | |||
Potenza di trasmissione | dBm | 30 | 14 | 14 | 14 | |
Sensibilità di ricezione | dBm | -107~-109 | -109~-111 | -108 | -108 | La velocità dell’aria è 2.5kbps |
Distanza di riferimento | m | 6000m | 1500m | 1500m | 1500m | La probabilità di danneggiamento è minore quando usato a breve distanza |
Antenna 5dBi, altezza 2.5 metri, velocità dell’aria 2.5kbps | ||||||
Banda di frequenza operativa | MHz | 425~450.5 | La frequenza predefinita di fabbrica è 433MHz e supporta la banda ISM | |||
Velocità di trasmissione | bps | 2.5k~168k | Controllo programmabile dall’utente | |||
Potenza di blocco | dBm | 10 | Vedi dettagli nei modi di trasferimento | |||
Lunghezza della trasmissione | / | Specificata in modalità di trasmissione | Vedi dettagli nei modi di trasferimento |
Parametro elettrico
Consumo di potenza istantaneo | Unità | Modello | Osservazioni | ||||
E70-433T30S | E70-433T14S | E70-433T14S2 | E70-433MT14S | ||||
Tensione operativa | V | 2.6~5.5 | 2.2~3.8 | 2.2~3.8 | 2.2~3.8 | Spegni via software | |
Livello di comunicazione | V | 3.3 | Utilizzare TTL a 5V comporta un rischio di danneggiamento | ||||
Consumo di potenza | Corrente di emissione | mA | 530 | 27 | 36 | 32 | Utilizzare TTL a 5V comporta un rischio di danneggiamento |
Corrente di ricezione | mA | 14 | 8 | 8 | 9 | ||
Corrente in sleep | μA | 4 | 1 | 1.2 | 1.7 | Consumo di potenza istantaneo | |
Temperatura | Il modulo E70-433T30 brucia permanentemente se usato sopra i 5.5 V, e gli altri tre modelli sopra i 3.8 V | ℃ | -20~+85 | Grado industriale | |||
Temperatura operativa | -40~+125 |
Parametri hardware
Parametri hardware | Modello | Osservazione | |||
E70-433T30S | E70-433T14S | E70-433T14S2 | E70-433MT14S | ||
Chip | CC1310 | ||||
Capacità cache | 2048 Byte | Definito dall’utente | |||
FLASH | 128 KB | ||||
RAM | 8 KB | ||||
Kernel | Cortex-M3 (MCU) + Cortex-M0 (RF) | ||||
Interfaccia di comunicazione | UART porta seriale | Livello TTL | |||
Metodo di modulazione | GFSK | ||||
Metodo di incapsulamento | SMD | ||||
Interfaccia antenna | IPEX/stamp hole | IPEX/stamp hole | IPEX/stamp hole | Stamp hole | Impedenza caratteristica circa 50 ohm |
Dimensioni | 24*38.5 mm | 16*26 mm | 14*20 mm | 10*10 mm | Il modello E70-433T14S2 non include SMA |
Pinout E70 xxxT14S2
Per il mio test, utilizzerò una versione E70 S2 perché ha un fattore di forma comodo con un’antenna SMA integrata.
Note sulle connessioni
Puoi trovare tutti i diagrammi di cablaggio negli articoli precedenti della serie.
Come puoi vedere, ho anche collegato i pin M0, M1 e M2, ma non sono necessari; puoi selezionare una modalità operativa impostando i valori su questi pin.
Modalità (0-7) | M2 | M1 | M0 | Descrizione modalità | Osservazione |
---|---|---|---|---|---|
0 Modalità RSSI | 0 | 0 | 0 | Il modulo emette il valore RSSI ogni 100ms tramite UART. | La velocità di trasmissione aerea può essere regolata automaticamente in base alla velocità di baud. La velocità di baud deve essere la stessa sia sul ricevitore che sul trasmettitore. È applicabile per la trasmissione continua di dati ad alta velocità. |
1 Modalità continua | 0 | 0 | 1 | UART aperta. Wireless chiuso e disponibile la trasmissione trasparente a pacchetto. | UART aperta. Wireless chiuso e disponibile la trasmissione trasparente continua. |
2 Modalità a pacchetto | 0 | 1 | 0 | UART aperta. Wireless chiuso e parametri configurabili. | La velocità dell’aria e la velocità di baud possono essere regolate separatamente. È applicabile per la trasmissione di pacchetti di dati. |
3 Modalità configurazione | 0 | 1 | 1 | La velocità di baud è fissata a 9600 8N1. | UART aperta. Wireless chiuso e disponibile la trasmissione trasparente a pacchetto. |
4 Modalità WOR | 1 | 0 | 0 | La trasmissione non è disponibile in questa modalità. Può essere risvegliato da un trasmettitore in modalità 4 per ottenere una ricezione a basso consumo energetico. | La ricezione non è disponibile in questa modalità. Un codice di preambolo sarà aggiunto proattivamente prima della trasmissione per risvegliare il ricevitore in modalità 6. |
5 Modalità configurazione (Come modalità 3) | 1 | 0 | 1 | – | – |
6 Modalità risparmio energetico | 1 | 1 | 0 | Qualsiasi bordo di discesa di M2, M1 o M0 può risvegliarlo. | UART chiuso. Il wireless funziona in modalità di risparmio energetico WOR. Sono configurabili più gradi di tempo. |
7 Modalità sleep | 1 | 1 | 1 | Qualsiasi bordo di discesa di M2, M1 o M0 può risvegliarlo. | UART chiuso, disponibile la trasmissione wireless, e la modalità sleep è attiva. |
Per questo esperimento, devi impostare i dispositivi in modalità a pacchetto.
- M0: BASSO
- M1: ALTO
- M2: BASSO
Costruttore
Ho creato una serie di costruttori perché possiamo avere più opzioni e situazioni da gestire.
RF_E70(byte txE70pin, byte rxE70pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
RF_E70(byte txE70pin, byte rxE70pin, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
RF_E70(byte txE70pin, byte rxE70pin, byte auxPin, byte m0Pin, byte m1Pin, byte m2Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
La prima serie di costruttori è stata creata per delegare la gestione dei pin Serial e altri alla libreria.
txE70pin
erxE70pin
sono i pin da collegare all’UART. Sono obbligatori.auxPin
è un pin che verifica lo stato di funzionamento, trasmissione e ricezione (spiegheremo meglio in seguito). Questo pin non è obbligatorio; se non lo imposti, applico un ritardo per permettere l’operazione di completarsi (con latenza, se hai problemi, come un dispositivo che si blocca, devi mettere una resistenza pull-up da 4.7k o, meglio ancora, collegarla al dispositivo).m0pin
,m1Pin
em2Pin
sono i pin per cambiare la modalità operativa (vedi tabella sopra); credo che questi pin in “produzione” verranno collegati direttamente a HIGH o LOW. Tuttavia, per il test, sono utili per la libreria per la gestione.bpsRate
è il baud rate di SoftwareSerial, solitamente 9600 (l’unico baud rate in modalità programmazione/sleep).
Ecco un semplice esempio:
#include "RF_E70.h"
RF_E70 e70ttl(2, 3); // e70 TX e70 RX
// RF_E70 e70ttl(2, 3, 5, 6, 7); // e70 TX e70 RX
Possiamo usare un SoftwareSerial direttamente con un altro costruttore:
RF_E70(HardwareSerial* serial, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
RF_E70(HardwareSerial* serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
RF_E70(HardwareSerial* serial, byte auxPin, byte m0Pin, byte m1Pin, byte m2Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
L’esempio precedente con questo costruttore può essere realizzato così:
#include <SoftwareSerial.h>
#include "RF_E70.h"
SoftwareSerial mySerial(2, 3); // e70 TX e70 RX
RF_E70 e70ttl(&mySerial);
// RF_E70 e70ttl(&mySerial, 5, 6, 7, 8);
L’ultima serie di costruttori è per consentire l’utilizzo di un HardwareSerial invece di un SoftwareSerial.
RF_E70(SoftwareSerial* serial, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
RF_E70(SoftwareSerial* serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
RF_E70(SoftwareSerial* serial, byte auxPin, byte m0Pin, byte m1Pin, byte m2Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600);
Per esp32, ci sono tre costruttori aggiuntivi che consentono la gestione dei pin per HardWare serial:
RF_E70(byte txE70pin, byte rxE70pin, HardwareSerial* serial, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600, uint32_t serialConfig = SERIAL_8N1);
RF_E70(byte txE70pin, byte rxE70pin, HardwareSerial* serial, byte auxPin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600, uint32_t serialConfig = SERIAL_8N1);
RF_E70(byte txE70pin, byte rxE70pin, HardwareSerial* serial, byte auxPin, byte m0Pin, byte m1Pin, byte m2Pin, UART_BPS_RATE bpsRate = UART_BPS_RATE_9600, uint32_t serialConfig = SERIAL_8N1);
Inizializzazione
Il comando begin()
viene utilizzato per avviare Serial e impostare i pin in modalità input e output.
void begin();
Ecco come viene eseguito:
// Startup all pins and UART
e70ttl.begin();
Configurazione e metodi per ottenere informazioni
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 di risposta
Per semplificare la gestione delle risposte, ho creato una serie di contenitori che sono molto utili per gestire gli errori e restituire dati generici.
ResponseStatus
ResponseStatus
è un contenitore di stato e ha due semplici punti di accesso. Con questo è possibile 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
Il codice è:
E70_SUCCESS = 1,
ERR_E70_UNKNOWN, /* something shouldn't happened */
ERR_E70_NOT_SUPPORT,
ERR_E70_NOT_IMPLEMENT,
ERR_E70_NOT_INITIAL,
ERR_E70_INVALID_PARAM,
ERR_E70_DATA_SIZE_NOT_MATCH,
ERR_E70_BUF_TOO_SMALL,
ERR_E70_TIMEOUT,
ERR_E70_HARDWARE,
ERR_E70_HEAD_NOT_RECOGNIZED,
ERR_E70_NO_RESPONSE_FROM_DEVICE,
ERR_E70_WRONG_UART_CONFIG,
ERR_E70_WRONG_FORMAT,
ERR_E70_PACKET_TOO_BIG,
ERR_E70_NO_STREAM_FOUND
ResponseContainer
Questo contenitore è stato creato per gestire le risposte sotto forma di stringhe e ha due punti di accesso: data
, che contiene la stringa restituita dal messaggio, e status
, che è un’istanza di ResponseStatus
.
ResponseContainer rs = e70ttl.receiveMessage();
String message = rs.data;
Serial.println(rs.status.getResponseDescription());
Serial.println(message);
Ma questo comando legge tutti i dati nel buffer. Se ricevi tre messaggi, li leggerai tutti in una volta. Una soluzione semplice è usare un carattere di fine da inviare alla fine del messaggio, per impostazione predefinita uso \0 (carattere nullo).
ResponseContainer rs = e70ttl.receiveMessageUntil();
// You can specify a custom delimiter also
// ResponseContainer rs = e70ttl.receiveMessageUntil('|');
String message = rs.data;
Serial.println(rs.status.getResponseDescription());
Serial.println(message);
ResponseStructContainer
ResponseStructContainer
è il contenitore più “complesso” che utilizzo per gestire le strutture. Ha gli stessi punti di accesso di ResponseContainer
, ma data
è un puntatore void
per gestire strutture complesse.
ResponseStructContainer c;
c = e70ttl.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();
Ogni volta che usi un ResponseStructContainer
, devi chiuderlo con close()
.
getConfiguration e setConfiguration
Il primo metodo è getConfiguration
, che puoi utilizzare per recuperare tutti i dati memorizzati sul dispositivo.
ResponseStructContainer getConfiguration();
Qui un esempio di utilizzo:
ResponseStructContainer c;
c = e70ttl.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 contiene tutti i dati relativi alle impostazioni, e ho aggiunto una serie di funzioni per ottenere tutte le descrizioni di un singolo dato.
configuration.ADDL = 0x00; // First part of address
configuration.ADDH = 0x00; // Second part
configuration.SPED.uartBaudRate = UART_BPS_9600; // Serial baud rate
configuration.SPED.airDataRate = AIR_DATA_RATE_000_025; // Air baud rate
configuration.SPED.uartParity = MODE_00_8N1; // Parity bit
configuration.CHAN.CHAN = 4;
configuration.CHAN.subPacketSetting = SPS_0064_010;
configuration.OPTION.fec = FEC_1_ON; // Packet size
configuration.OPTION.fixedTransmission = FT_TRANSPARENT_TRANSMISSION; // Need to send special command
configuration.OPTION.transmissionPower = POWER_30; // Device power
configuration.OPTION.ioDriveMode = IO_D_MODE_PUSH_PULLS_PULL_UPS; // IO Drive
configuration.OPTION.wirelessWakeupTime = WAKE_UP_1000; // Wake up time
Hai funzioni equivalenti per tutti gli attributi per ottenere tutte le descrizioni:
void printParameters(struct Configuration configuration) {
Serial.println("----------------------------------------");
Serial.print(F("Configuration packet: "));
byte* byteArray = (byte*)&configuration; // Cast the address of config to a byte pointer
for (int i = 0; i < sizeof(Configuration); i++) {
if (byteArray[i] < 16) {
Serial.print('0'); // Print a leading zero for single-digit hex values
}
Serial.print(byteArray[i], HEX); // Print each byte of the struct in hexadecimal
Serial.print(" ");
}
Serial.println(F(" "));
Serial.print(F("HEAD : ")); Serial.print(configuration.COMMAND, HEX);Serial.print(" ");
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.CHAN, DEC); Serial.print(" -> "); Serial.println(configuration.CHAN.getChannelDescription());
Serial.print(F("Packet size : ")); Serial.print(configuration.CHAN.subPacketSetting, BIN); Serial.print(" -> "); Serial.println(configuration.CHAN.getSubPacketSetting());
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("OptionFECPacketSett: ")); Serial.print(configuration.OPTION.fec, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getFECDescription());
Serial.print(F("OptionTranPower : ")); Serial.print(configuration.OPTION.transmissionPower, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getTransmissionPowerDescription());
Serial.print(F("OptionIODrive: ")); Serial.print(configuration.OPTION.ioDriveMode, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getIODroveModeDescription());
Serial.print(F("OptionFixedTransmission: ")); Serial.print(configuration.OPTION.fixedTransmission, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getFixedTransmissionDescription());
Serial.print(F("OptionWirelessWakeUPTime: ")); Serial.print(configuration.OPTION.wirelessWakeupTime, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getWirelessWakeUPTimeDescription());
Serial.println("----------------------------------------");
}
Allo stesso modo, setConfiguration
richiede una struttura di configurazione, quindi il modo migliore per gestire la configurazione è recuperare quella corrente, applicare solo le modifiche necessarie e impostarla nuovamente.
ResponseStatus setConfiguration(Configuration configuration, PROGRAM_COMMAND saveType = WRITE_CFG_PWR_DWN_LOSE);
configuration
è la struttura mostrata in precedenza, saveType
ti consente di scegliere se il cambiamento diventa permanente o solo per la sessione corrente.
ResponseStructContainer c;
c = e70ttl.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 = 0x00; // First part of address
configuration.ADDH = 0x00; // Second part
configuration.SPED.uartBaudRate = UART_BPS_9600; // Serial baud rate
configuration.SPED.airDataRate = AIR_DATA_RATE_000_025; // Air baud rate
configuration.SPED.uartParity = MODE_00_8N1; // Parity bit
configuration.CHAN.CHAN = 4;
configuration.CHAN.subPacketSetting = SPS_0064_010;
configuration.OPTION.fec = FEC_1_ON; // Packet size
configuration.OPTION.fixedTransmission = FT_TRANSPARENT_TRANSMISSION; // Need to send special command
configuration.OPTION.transmissionPower = POWER_30; // Device power
configuration.OPTION.ioDriveMode = IO_D_MODE_PUSH_PULLS_PULL_UPS; // IO Drive
configuration.OPTION.wirelessWakeupTime = WAKE_UP_1000; // Wake up time
// Set configuration changed and set to not hold the configuration
ResponseStatus rs = e70ttl.setConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE);
Serial.println(rs.getResponseDescription());
Serial.println(rs.code);
printParameters(configuration);
c.close()
Opzioni di configurazione di base
Nome | Descrizione | Indirizzo |
---|---|---|
ADDH | Byte dell’indirizzo alto del modulo (di default 00H) | 00H |
ADDL | Byte dell’indirizzo basso del modulo (di default 00H) | 01H |
SPED | Informazioni sulla velocità dei dati, bit di parità e velocità dell’aria | 02H |
OPTION | Tipo di trasmissione e velocità | 03H |
CHAN | Canale di comunicazione (410M + CHAN*1M), di default 17H (433 MHz),valido solo per il dispositivo a 433 MHz | 04H |
Dettaglio SPED
Bit di parità UART: La modalità UART può essere diversa tra le parti comunicanti
Bit di parità UART | Valore costante |
---|---|
8N1 (default) | MODE_00_8N1 |
8O1 | MODE_01_8O1 |
8E1 | MODE_10_8E1 |
8N1 (equivalente a 00) | MODE_11_8N1 |
Velocità baud UART: La velocità baud UART può essere diversa tra le parti comunicanti (ma non raccomandato). La velocità baud UART non ha nulla a che fare con i parametri di trasmissione wireless e non influenzerà le caratteristiche di trasmissione/ricezione wireless.
Velocità baud UART TTL (bps) | Valore costante |
---|---|
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 |
Velocità dei dati dell’aria: Più bassa è la velocità dei dati dell’aria, maggiore sarà la distanza di trasmissione, migliore la prestazione anti-interferenza, ma maggiore sarà il tempo di trasmissione. La velocità dei dati dell’aria deve essere costante per entrambe le parti di comunicazione.
Velocità dei dati dell’aria (bps) | Valore costante |
---|---|
2.5k (default) | AIR_DATA_RATE_000_025 |
5k | AIR_DATA_RATE_001_050 |
12k | AIR_DATA_RATE_010_120 |
28k | AIR_DATA_RATE_011_280 |
64k | AIR_DATA_RATE_100_640 |
168k | AIR_DATA_RATE_101_168 |
168k | AIR_DATA_RATE_110_168 |
168k | AIR_DATA_RATE_111_168 |
Dettaglio CHAN
Canale
Puoi vedere il CANALE
Impostazione del pacchetto secondario
Questa è la lunghezza massima del pacchetto.
Quando i dati sono inferiori alla lunghezza del pacchetto secondario, l’uscita seriale del lato ricevente è un’uscita continua senza interruzioni. Il lato ricevente seriale emetterà il pacchetto secondario quando i dati sono superiori alla lunghezza del pacchetto secondario.
Dimensione pacchetto | Valore costante |
---|---|
16 byte | SPS_0016_000 |
32 byte | SPS_0032_001 |
64 byte (default) | SPS_0064_010 |
128 byte | SPS_0128_011 |
256 byte | SPS_0256_100 |
512 byte | SPS_0512_101 |
1024 byte | SPS_1024_110 |
2048 byte | SPS_2048_111 |
FEC
FEC: dopo aver disattivato FEC, aumenta il tasso di trasmissione effettivo dei dati, ma la capacità anti-interferenza diminuisce. Anche la distanza di trasmissione è relativamente breve, e entrambe le parti di comunicazione devono concordare sul fatto di attivare o disattivare FEC.
Bit di abilitazione FEC | Valore costante |
---|---|
Disattiva FEC | FEC_0_OFF |
Attiva FEC (default) | FEC_1_ON |
Modalità di pilotaggio IO
La modalità di pilotaggio IO è utilizzata per la resistenza di pull-up interna del modulo. Aumenta anche l’adattabilità del livello in caso di drain aperto. Tuttavia, in alcuni casi, potrebbe essere necessaria una resistenza pull-up esterna.
Modalità pilotaggio IO (default 1) | Valore costante |
---|---|
TXD e AUX push-pull outputs, RXD pull-up inputs | IO_D_MODE_PUSH_PULLS_PULL_UPS |
TXD, AUX open-collector outputs, RXD open-collector inputs | IO_D_MODE_OPEN_COLLECTOR |
Ciclo WOR
Se WOR è in trasmissione: dopo che il ricevitore WOR ha ricevuto i dati wireless e li ha emessi tramite la porta seriale, attenderà 1000ms prima di entrare nuovamente in WOR. Gli utenti possono inserire i dati della porta seriale e restituirli via wireless durante questo periodo. Ogni byte seriale aggiornerà l’intervallo di 1000ms. Gli utenti devono trasmettere il primo byte entro 1000ms.
- Periodo T = (1 + WOR) * 500ms, massimo 4000ms, minimo 500ms
- Più lungo è il periodo di monitoraggio WOR, minore è il consumo medio di energia, ma maggiore è il ritardo dei dati.
- Entrambi, il trasmettitore e il ricevitore, devono essere sincronizzati (molto importante).
Tempo di risveglio wireless | Valore costante |
---|---|
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 |
Potenza di trasmissione
Puoi cambiare questo set di costanti applicando una define come segue:
#define E70_22 // valore predefinito senza impostazione
Applicabile per E70 con 22dBm come potenza massima.
La trasmissione a bassa potenza non è raccomandata a causa della bassa efficienza dell’alimentazione.
Potenza di trasmissione (approssimativa) | Valore costante |
---|---|
22dBm (default) | POWER_22 |
17dBm | POWER_17 |
13dBm | POWER_13 |
10dBm | POWER_10 |
Applicabile per E70 con 30dBm come potenza massima.
La trasmissione a bassa potenza non è raccomandata a causa della bassa efficienza dell’alimentazione.
#define E70_30
Potenza di trasmissione (approssimativa) | Valore costante |
---|---|
30dBm (default) | POWER_30 |
27dBm | POWER_27 |
24dBm | POWER_24 |
21dBm | POWER_21 |
Puoi configurare anche la frequenza del canale con questa define:
// One of
#define FREQUENCY_433
#define FREQUENCY_868
#define FREQUENCY_900
#define FREQUENCY_915
Verifica del buffer
Prima dobbiamo introdurre un metodo semplice ma pratico per controllare se qualcosa è nel buffer di ricezione.
int available();
Restituisce semplicemente il numero di byte presenti nello stream corrente.
Invio e ricezione dei 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, che spiegheremo in dettaglio:
ResponseStatus sendMessage(const String message);
ResponseContainer receiveMessage();
Il primo metodo è sendMessage
, che invia una stringa a un dispositivo in modalità Normale.
ResponseStatus rs = e70ttl.sendMessage("Prova");
Serial.println(rs.getResponseDescription());
Dall’altra parte, il dispositivo esegue nel loop:
if (e70ttl.available() > 1){
ResponseContainer rs = e70ttl.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, devi usare ResponseContainer rs = e70ttl.receiveMessageUntil();
con un delimitatore inserito alla fine del messaggio inviato.
Gestire le 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 strutture, ad esempio:
struct Messaggione {
char type[5];
char message[8];
bool mitico;
};
struct Messaggione messaggione = {"TEMP", "Peple", true};
ResponseStatus rs = e70ttl.sendMessage(&messaggione, sizeof(Messaggione));
Serial.println(rs.getResponseDescription());
E dall’altro lato, puoi ricevere il messaggio così:
ResponseStructContainer rsc = e70ttl.receiveMessage(sizeof(Messaggione));
struct Messaggione messaggione = *(Messaggione*) rsc.data;
Serial.println(messaggione.message);
Serial.println(messaggione.mitico);
rsc.close();
Leggere una struttura parziale
Se desideri leggere la prima parte del messaggio per gestire più tipi di strutture, puoi utilizzare questo metodo:
ResponseContainer receiveInitialMessage(const uint8_t size);
L’ho creato per ricevere una stringa con il tipo o altre informazioni 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 = e70ttl.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 = e70ttl.receiveMessage(sizeof(Messaggione));
struct Messaggione messaggione = *(Messaggione*) rsc.data;
rsc.close();
Modalità fissa invece di modalità normale
Allo stesso modo, ho creato una serie di metodi per utilizzare con la trasmissione fissa.
Trasmissione fissa
Devi cambiare solo il metodo di invio, poiché il dispositivo destinatario non riceverà il preambolo con indirizzo e canale quando imposti la modalità fissa.
Quindi, per il messaggio stringa, 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 );
Ecco un semplice esempio:
ResponseStatus rs = e70ttl.sendFixedMessage(0, 0, 0x17, &messaggione, sizeof(Messaggione));
// ResponseStatus rs = e70ttl.sendFixedMessage(0, 0, 0x17, "Ciao");
La trasmissione fissa ha più scenari:
Se invii a un dispositivo specifico (secondo scenario Trasmissione fissa), devi aggiungere ADDL, ADDH e CHAN per identificarlo direttamente.
ResponseStatus rs = e70ttl.sendFixedMessage(2, 2, 0x17, "Messaggio a un dispositivo");
Se vuoi inviare un messaggio a tutti i dispositivi su un canale specifico, puoi usare questo metodo:
ResponseStatus rs = e70ttl.sendBroadcastFixedMessage(0x17, "Messaggio a tutti i dispositivi su un canale");
Se desideri ricevere tutti i messaggi broadcast nella rete, devi impostare i tuoi ADDH
e ADDL
su BROADCAST_ADDRESS
.
ResponseStructContainer c;
c = e70ttl.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 = e70ttl.setConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE);
Serial.println(rs.getResponseDescription());
Serial.println(rs.code);
printParameters(configuration);
c.close();
Modalità continua
L’E70 offre la modalità continua impostando lo stesso ADDH, ADDL e CHAN. Puoi trasmettere una grande quantità di dati o dati continui.
Modalità Continua
- Operazione: In modalità continua, il modulo EByte E70 invia o riceve dati in un flusso continuo. Ciò significa che, una volta avviata la trasmissione, continuerà a inviare dati fino a quando non verrà fermata. È simile a una trasmissione radio tradizionale.
- Utilizzo: Questa modalità è utile per applicazioni in cui è necessario un flusso costante di informazioni, senza interruzioni. È ideale per la trasmissione di dati in tempo reale, come lo streaming audio o la telemetria.
- Vantaggi:
- Trasmissione dati in tempo reale: Utile per applicazioni che richiedono aggiornamenti in tempo reale.
- Nessuna interruzione: Flusso continuo di dati senza la necessità di riassemblare i pacchetti o gestirli.
- Sfide:
- Consumo energetico: La modalità continua consuma generalmente più energia a causa della trasmissione costante.
- Utilizzo della larghezza di banda: Può utilizzare più larghezza di banda, il che potrebbe non essere ideale in ambienti RF affollati.
Modalità a Pacchetti
- Operazione: Nella modalità a pacchetti, i dati vengono suddivisi in pacchetti più piccoli prima della trasmissione. Ogni pacchetto viene inviato separatamente e quindi riassemblato dal ricevitore.
- Utilizzo: Questa modalità è ideale per applicazioni che non richiedono trasmissioni in tempo reale e possono tollerare un certo ritardo, come l’invio di dati sensoriali a intervalli.
- Vantaggi:
- Efficienza energetica: Più efficiente dal punto di vista energetico, poiché il modulo può andare in modalità a basso consumo tra le trasmissioni.
- Gestione degli errori: Più facile implementare il controllo e la correzione degli errori, poiché viene fatto su base per pacchetto.
- Velocità di trasmissione adattativa: Può regolare la velocità dei dati per ogni pacchetto a seconda delle condizioni della rete.
- Sfide:
- Latenza: C’è un ritardo nell’assemblaggio dei dati, che potrebbe non essere adatto per applicazioni in tempo reale.
- Complessità: Richiede una logica più complessa per la gestione e l’assemblaggio dei pacchetti.
Differenze Chiave
- Metodo di trasmissione dei dati: La modalità continua trasmette dati in un flusso costante, mentre la modalità a pacchetti suddivide i dati in pacchetti più piccoli.
- Consumo energetico: La modalità continua generalmente consuma più energia a causa della trasmissione costante.
- Capacità in tempo reale: La modalità continua è migliore per esigenze di dati in tempo reale, mentre la modalità a pacchetti è adatta per trasmissioni di dati ritardati o periodici.
- Gestione degli errori e flessibilità: La modalità a pacchetti offre maggiore flessibilità nella gestione degli errori e nell’adattarsi alle condizioni di rete.
Quando utilizzi la modalità di trasmissione continua, il modulo invia un flusso continuo di dati. Per indirizzare questi dati a un indirizzo specifico, di solito configureresti il mittente e il ricevitore con indirizzi corrispondenti. Ciò significa che sia il modulo trasmittente che quello ricevente devono essere configurati per riconoscere e utilizzare questi indirizzi specificati.
Flusso semplice
Per inviare un flusso semplice (senza preambolo) puoi usare:
ResponseStatus RF_E70::streamMessage(Stream *streamLocal)
Una possibile implementazione potrebbe essere il flusso di un file.
File inputFile = SPIFFS.open(input);
if (!inputFile) {
Serial.println("There was an error opening the file for reading");
} else {
ResponseStatus rs = e70ttl.streamMessage(&inputFile);
// Check If there is some problem of succesfully send
Serial.println(rs.getResponseDescription());
}
Prende un flusso come parametro. Per riceverlo, puoi attendere i dati.
if (e70ttl.available()>0) {
Serial.println("Start!");
// open file in write
File output = SPIFFS.open("/tmp.png", FTP_FILE_WRITE_CREATE);
while (e70ttl.available()>0) {
while (e70ttl.available()>0) {
if (output.write(e70ttl.read())==0) {Serial.println("ERROR WRITE!"); };
}
delay(10);
}
output.close();
Serial.println("Complete!");
}
Come puoi vedere, puoi usare read
, che è un classico stream.read()
.
Flusso con preambolo
Non tutte le situazioni possono essere un flusso continuo; a volte abbiamo bisogno di inviare dati come un array di byte; in questa situazione, hai bisogno di un preambolo con le informazioni sul file, e puoi usare il comando:
ResponseStatus RF_E70::streamStructMessage(const void *message, const uint8_t size, Stream *streamLocal)
Puoi identificare che la prima parte del metodo di invio è la stessa del send struct
descritto prima; l’ultimo parametro è il flusso da inviare.
Per riceverlo tutto, prima devi chiamare il comando per ottenere la struttura (preambolo).
ResponseStructContainer RF_E70::receiveStreamMessage(const uint8_t size)
Quindi, ricevi il flusso come descritto in precedenza.
Grazie
- EByte RF E70 433/868/900 T14S2: piedinatura, datasheet e specifiche (1.5Km)
- Adattatore per Modulo RF EByte E70: PCB, Soluzione Stampata in 3D per breadboard e configurazione
- Collegare l’EByte E70 (CC1310) ai dispositivi ESP32 c3/s3 ed un semplice sketch di esempio
- Collegamento dell’EByte E70 ai dispositivi Arduino SAMD (Nano 33, MKR…) e un semplice sketch di esempio
- Collegamento dell’EByte E70 ai dispositivi STM32 (black/blue pill) e un semplice sketch di esempio
- Collegamento dell’EByte E70 ai dispositivi Raspberry Pi Pico (rp2040) ed un semplice sketch di esempio
- Esplorazione delle potenzialità del modulo EByte RF E70 (esp32, STM32, Arduino, Raspberry Pi Pico)
- EByte RF E70 CC1310: andiamo ad esplorare la libreria (esp32, esp8266, STM32, Arduino, Raspberry Pi Pico)
- Configurazione del Modulo RF EByte E70 (esp32, STM32, Arduino, Raspberry Pi Pico)