Saltar la navegación

Comunicaciones LoRa

Envío y recepción básicos en LoRa

Se trata de enviar del emisor al receptor el tiempo que transcurre en el emisor a través de un contador, también se hace uso de la pantalla OLED. El receptor además envía el registro a puerto serie.

Programa emisor de tiempo:

//Libraries for LoRa
#include <SPI.h>
#include <LoRa.h>

//Libraries for OLED Display
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

//define the pins used by the LoRa transceiver module
#define SCK 5
#define MISO 19
#define MOSI 27
#define SS 18
#define RST 23
#define DIO0 26

//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define BAND 866E6

//OLED pins
#define OLED_SDA 21
#define OLED_SCL 22 
#define OLED_RST 16
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

//contador de tiempo
int counter=0;

//creacion de pantalla (objeto display)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);

//funciones

void envia_lora(){//Send LoRa packet to receiver
  LoRa.beginPacket();
  LoRa.print(counter);
  LoRa.endPacket();
}

void envia_oled(){
  display.clearDisplay();
  display.setCursor(0,0);
  display.println("Club Robotica Granada");
  display.setCursor(0,20);
  display.setTextSize(1);
  display.print("Paquete LoRa enviado.");
  display.setCursor(0,30);
  display.print("Contador: ");
  display.setCursor(60,30);
  display.print(counter);      
  display.display();
}


void setup() {
  //reset OLED display via software
  pinMode(OLED_RST, OUTPUT);
  digitalWrite(OLED_RST, LOW);
  delay(20);
  digitalWrite(OLED_RST, HIGH);

  //initialize OLED
  Wire.begin(OLED_SDA, OLED_SCL);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("LORA SENDER ");
  display.display();
  
  /*initialize Serial Monitor
  Serial.begin(115200);
  
  Serial.println("Prueba de envio LoRa");*/

  //SPI LoRa pins
  SPI.begin(SCK, MISO, MOSI, SS);
  //setup LoRa transceiver module
  LoRa.setPins(SS, RST, DIO0);
  
  if (!LoRa.begin(BAND)) {
    display.setCursor(0,10);
    display.print("Starting LoRa failed!");
    display.display();
    //Serial.println("Starting LoRa failed!");
    while (1);
  }
  //Serial.println("LoRa Inicializacion OK!");
  display.setCursor(0,10);
  display.print("Inicializacion OK!");
  display.display();
  delay(2000);
}

void loop() {
  envia_lora();
  envia_oled();
  counter++;
  delay(1000);
}

Programa receptor: 

Este programa será el que proponemos definitivo para recepción de datos en PC.

//Libraries for LoRa
#include <SPI.h>
#include <LoRa.h>

//Libraries for OLED Display
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

//define the pins used by the LoRa transceiver module
#define SCK 5
#define MISO 19
#define MOSI 27
#define SS 18
#define RST 23
#define DIO0 26

//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define BAND 866E6

//OLED pins
#define OLED_SDA 21
#define OLED_SCL 22
#define OLED_RST 16
#define SCREEN_WIDTH 128  // OLED display width, in pixels
#define SCREEN_HEIGHT 64  // OLED display height, in pixels

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);

String LoRaData;

void setup() {

  //reset OLED display via software
  pinMode(OLED_RST, OUTPUT);
  digitalWrite(OLED_RST, LOW);
  delay(20);
  digitalWrite(OLED_RST, HIGH);

  //initialize OLED
  Wire.begin(OLED_SDA, OLED_SCL);
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) {  // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ;  // Don't proceed, loop forever
  }

  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.print("LORA RECEIVER ");
  display.display();

  //initialize Serial Monitor
  Serial.begin(115200);

  Serial.println("LoRa Receiver Test");

  //SPI LoRa pins
  SPI.begin(SCK, MISO, MOSI, SS);
  //setup LoRa transceiver module
  LoRa.setPins(SS, RST, DIO0);

  if (!LoRa.begin(BAND)) {
    Serial.println("Starting LoRa failed!");
    while (1)
      ;
  }
  Serial.println("LoRa Initializing OK!");
  display.setCursor(0, 10);
  display.println("LoRa Inicializacion OK!");
  display.display();
}

void loop() {

  //try to parse packet
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    //received a packet
    //Serial.print("Received packet ");

    //read packet
    while (LoRa.available()) {
      LoRaData = LoRa.readString();
      Serial.print(LoRaData);
      Serial.print("\r\n");
    }

    //print RSSI of packet
    int rssi = LoRa.packetRssi();
    //Serial.print(" with RSSI ");
    //Serial.println(rssi);

    // Display information
    display.clearDisplay();
    display.setCursor(0, 0);
    display.print("CANSAT CRG");
    display.setCursor(0, 10);
    display.print("Mensaje recibido:");
    display.setCursor(0, 20);
    display.print(LoRaData);
    display.setCursor(0, 50);
    display.print("RSSI:");
    display.setCursor(30, 50);
    display.print(rssi);
    display.display();
  }
}

Tipo de señal

Los módulos TTG LoRa ESP32 pueden enviar y recibir señales LoRa (LongRange). LoRa es una tecnología de comunicación patentada, que está pensada para comunicaciones con un bajo consumo de energía, largo alcance y buena inmunidad frente al ruido, lo que la hace ideal para aplicaciones IoT.

El sistema de comunicación LoRa esta basado en la modulación CSS (Chirp Spread Spectrum), que es una técnica de modulación de banda ancha, que utiliza chirps (pitidos), para codificar la información. Los chirps son como pitidos de un tono cuya frecuencia incrementa o decrementa linealmente con el tiempo a lo largo del ancho de banda utilizado (BW), simétrico a la frecuencia central y cada chirp representa un símbolo, que puede tener 2F valores, donde F representa el Spread Factor.

En el sistema LoRa se transmiten paquetes de datos y estos paquetes de datos están formados por:

  • Preámbulo (preamble), que está formado por un número de chirps variables y una palabra de sincronización (Sync Word). En recepción se comprueba si el preámbulo recibido coincide con el programado y si no coincide desecha el resto del mensaje.
  • Cabecera, que puede ser explícita o implícita y en el caso de que sea explícita, contendrá información sobre el número de datos a enviar, la tasa de codificación de errores y la presencia de un código de verificación de errores.
    Carga útil, que es la información neta que se desea transmitir. En Lora el número máximo de es de 255 bytes.

Parámetros de transmisión en LoRa.

Inicialización del módulo LoRa

Nos permite inicializar el módulo LoRa para una frecuencia central determinada y nos fija una serie de parámetros por defecto, que son los siguientes:

  • TxPower =14
  • SpreadingFactor= 7
  • Bandwith= 125E3 (125kHz)
  • CodingRate= 5
  • PreambleLength= 8
  • SyncWord= 0x34
  • EnableCRC= disable

En el programa de Emisión o recepción queda definida por la línea de código siguiente colocada en setup:

LoRa.begin (866E6);

que indica que hemos comenzado una comunicación LoRa emitiendo o recibiendo a una frecuencia de 866MHz, y nos devuelve 1 si sucede y 0 si no. Podríamos cambiar el valor incluso con decimales según normativa entre 863 MHz y 870 MHz.

Ejemplo de comienzo de emisión y recepción a 866.3 Mhz:

LoRa.begin (866.3E6);

En el programa podemos modificar cualquiera de estos parámetros con las siguientes llamadas a la librería:

TX Power

Define la potencia de la transmisión de decibelios (dB) de nuestro dispositivo LoRa.

La instrucción según nuestra librería para cambiar la potencia de transmisión es:

  • LoRa.setTxPower(txPower); , dónde toma un valor por defecto de 17 dB, y se le puede asignar un rango de valores entre 2 y 20 dB.

Un ejemplo que se pondría en el setup de nuestro programa para cambiar la potencia de emisión a 18 dB sería este:

LoRa.setTxPower(18);
Frecuencia (portadora)

Define la frecuencia portadora del medio utilizado tanto para las operaciones de transmisión como para las de escucha. También depende de la región operativa: en Europa, la frecuencia portadora operativa de LoRa es la banda ISM de la UE 863-870MHz.

Podemos cambiar la frecuencia de la transmisión con la siguiente orden de la librería:

  • LoRa.setFrequency(frequency);

Un ejemplo de cambio de frecuencia a 868Mhz podría ser:

LoRa.setFrequency(868E6);
Ancho de banda (BandWidth)

Representa el ancho de las señales de radiofrecuencia LoRa, es en realidad un rango de frecuencia que oscila respecto a la frecuencia base dónde se concentra la mayor potencia de la señal, que se usa para la transmisión de datos. Por lo general, se establece en 125 kHz, pero se puede aumentar hasta 250 kHz o incluso 500 kHz en algunas regiones para parámetros de modulación particulares.

Un ancho de banda más alto proporciona una velocidad de datos más alta (por tanto, un tiempo más corto en el aire), pero una sensibilidad más baja (debido a la integración de ruido adicional).

Un ancho de banda más bajo proporciona una sensibilidad más alta, pero una velocidad de datos más baja.

La instrucción según nuestra librería para cambiar el ancho de banda es:

  • LoRa.setSignalBandwidth(signalBandwidth), dónde el valor de ancho de banda toma un valor por defecto de 125E3 (125KHz), pero se le pueden dar el siguiente rango de valores (7.8E3, 10.4E3, 15.6E3, 20.8E3, 31.25E3, 41.7E3, 62.5E3, 125E3, 250E3, y 500E3).

Ejemplo que se pondría en setup para que el ancho de banda sea de 250 KHz:

LoRa.setSignalBandwidth(250E3);
Spreading Factor (SF), factor de propagación o factor de ensanchamiento

Representa el parámetro de propagación del chirp*, que define cuántos chirps se envían por segundo. Oscila entre SF6 y SF12. En detalle, un SF grande aumenta el tiempo en el aire del símbolo (dato a transmitir) y el consumo de energía, mejorando así el rango de comunicación, pero reduciendo la velocidad de datos disponible y el tamaño de la carga útil de los mensajes.

Cada aumento en el factor de ensanchamiento (SF) reduce a la mitad la velocidad de transmisión y, por lo tanto, duplica la duración de la transmisión y, en última instancia, el consumo de energía.

La instrucción según nuestra librería para cambiar el spreading factor es:

  • LoRa.setSpreadingFactor(spreadingFactor);, dónde toma un valor por defecto de 7, pero se le pueden dar un rango de valores entre 6 y 12.
    Ejemplo que se pondría en setup para el spreading factor sea 8:
LoRa.setSpreadingFactor(8);

* (chirp): son pulsos de frecuencia (ascendente o descendente), la secuencia de los mismos se usan para enviar símbolos (datos). 

Coding Rate o razón de código:

Es la razón (cociente) de Forward Error Correction (FEC) usada por LoRa. FEC es el proceso donde son añadidos bits de corrección de error a los datos trasmitidos. La Razón de Código se refiere a la proporción de bits transmitidos que realmente llevan información con respecto a los totales. LoRa permite los siguientes valores \(CR=\{\frac{4}{5},\frac{4}{6},\frac{4}{7},\frac{4}{8}\}\), los cuales son calculados de la siguiente manera:
\(CR=\frac{4}{4+CR}\) donde \(CR=\{1,2,3,4\}\)

La instrucción según nuestra librería para cambiar el coding rate es:

  • LoRa.setCodingRate4(codingRateDenominator);, dónde toma un valor por defecto de 5, pero se le pueden dar un rango de valores entre 5 y 8.
    Ejemplo que se pondría en setup para el coding rate sea 6:
LoRa.setCodingRate4(6); 
Preamble Length

Son un numero de símbolos que se envían al principio de cada información enviada en LoRa.

La instrucción según nuestra librería para cambiar el preamble length es:

  • LoRa.setPreambleLength(preambleLength); , dónde su valor por defecto son 8, pero se les puede dar un rango entre 6 y 65535 símbolos.

Un ejemplo que se pondría en el setup de nuestro programa para cambiar el Preamble Length a 10 sería este:

LoRa.setPreambleLength(10);
 Sync word

Establece la palabra de sincronismo de la comunicación de radio LoRa.

La orden que usa la librería para establecerla es:

  • LoRa.setSyncWord(syncWord); , es un byte en hexadecimal cuyo valor por defecto es 0x12, y puede tomar un rango de valores entre 0 y 0xFF

Un ejemplo para establecer la palabra de sincronismo en el setup de nuestro programa a 0xF3, sería: 

LoRa.setSyncWord(0xF3);
CRC

La verificación por redundancia cíclica​ (CRC) es un código de detección de errores usado frecuentemente en redes digitales y en dispositivos de almacenamiento para detectar cambios accidentales en los datos. Comprueba aritméticamente que los datos recibidos concuerdan con los enviados.

En la librería que usamos de LoRa el CRC está deshabilitado y su habilitación o no, se hace con las siguientes instrucciones:

  • LoRa.enableCrc();
  • LoRa.disableCrc();

Un ejemplo para habilitar el CRC, en el setup de nuestro programa sería:

LoRa.enableCrc();

Comunicación efectiva entre dispositivos LoRa

Para que una comunicación pueda establecerse punto a punto entre dos dispositivos LoRa se debe cumplir todos estos requisitos:

  • Que trabajen con los mismos valores simultáneamente de:
    • Frecuencia.
    • Ancho de banda.
    • Coding Rate.
    • Spreading Factor.
    • Preamble Length.
    • Sync Word.
    • CRC lo tengan igual (activado o desactivado)

Creado con eXeLearning (Ventana nueva)