ESP32 LoRa for dummys - Baliza (Beacon)

En esta entrada vamos a ver las posibilidades de crear una baliza o "beacon"  usando una placa de desarrollo ESP32-LoRa.

Una baliza puede usarse para:
  • Monitorizar las condiciones de propagación  
  • Hacer seguimiento o tracker (puede transmitirse las coordenadas obtenidas por GNSS si dispone de este chip la placa)
  • Transmitir valores de telemetría o meteorológicos si se dota a la placa de desarrollo de los dispositivos adecuados
  • Jugar a la caza del zorro ocultándola con el fin de que sea radiolocalizada y encontrada por los participantes
  • ...

De los proyectos que se han localizado (ninguno de ellos está mantenido) en uno se configura por programa y en el otro via serie, se ha seleccionado MORSE BEACON.

PASOS
  • Clonar la librería del proyecto, para ello entrar en el terminal y situaros en el directorio donde queremos que se cree la copia (p.e. arduino) y ejecutar git clone https://github.com/sergev/morse-beacon.git 
  • Entrar en Arduino IDE
  • Comprobar que está instalado Arduino GFX y actualizar o instalar segñun el caso.
  • Seleccionar la placa de desarrollo ( p.e. ESP32-PICO-D4 revision v1.1 ) y la conexión serie (p.e. wchusbserie)
  • Hacer una copia de seguridad del modulo que vamos a modificar morse-beacon.ino => morse-beacon.bak pero guardela en otro dicrectorio de lo contrario le dará l siguiente erroro "error: redefinition of 'const uint8_t Fixed8x16Bitmaps []'"
  • Borrar la memoria de l aplaca (Si hay algo de valor hacer backup previamente)
    • python3 esptool.py  --port /dev/cu.wchusbserialXXXXXXXXXXXX erase_flash
  • Cargar y modificar el módulo morse-beacon.ino
    • El código es compatible con
      • TTGO Lora32 board 
      • Heltec Lora32 board
    • Algunos parámetros modificables
      • #define FREQ_HZ     433575000   // 433.575 MHz
      • #define TX_DBM      17 // 50 mW
      • #define WPM         12
      • send_message("KK6ABQ/B QRPP 50 mW FOX HUNT");
    • Este módulo llama a los siguientes (En negrita los del proyecto)
      • #include <SPI.h>
      • #include <Wire.h> Es necesario para comuicar ESP32 por I2C con pantalla OLED
      • #include <Adafruit_GFX.h>
      • #include "Adafruit_SSD1306.h"
      • #include "Fixed8x16.h"
      • #include "LoRa.h"
  • Compilar
"El Sketch usa 321457 bytes (24%) del espacio de almacenamiento de programa. El máximo es 1310720 bytes. Las variables Globales usan 19440 bytes (5%) de la memoria dinámica, dejando 308240 bytes para las variables locales. El máximo es 327680 bytes."

  • Cargar
  • Reset 
Las primeras pruebas no mostraron nada en la pantalla y tampoco se recibió nada. 

Hay que redefinir los pines para la placa en cuestión (LiLYGO 433/470 MHz Model: LORA 32 T3_V1.6.1 que monta el ESP32-PICO-D4 y el SX1278 y CH9102) de la siguiente manera para que funcione:

// ESP32 433 LORA32 V2.1_1.6
// LED
#define LED 25
// LORA
#define LORA_SCK 5 // IO5 -- SCLK
#define LORA_MISO 19 // IO19 -- MISO
#define LORA_MOSI 27 // IO27 -- MOSI
#define LORA_SS 18 // IO18 -- CS
#define LORA_RST 23 // IO12 -- RST RESET for V2.1 (use IO14 for V2.0)
#define LORA_DI0 26 // IO26 -- DIO Interrupt Request
// OLED
#define OLED_RST NOT_A_PIN // IO16 -- RESET
#define OLED_SDA 21 // IO21 -- SDA for TTGO Lora32 board
#define OLED_SCL 22 // IO22 -- SCL

Por eso es importante cuando adquiera una placa de desarrollo ESP32 que compruebe que está disponible su definición de PINES que es básica apra que un programa pueda adaptarse a una placa en concreto.



Para monitorizarlo hay que demodular en AM por lo que un SDR es ideal y un walkie vHF/UHF presenta una recepción mediocre al demodular en FM .

Funcionamiento

El programa emite el mensaje en CW a la velocidad especificada, de forma continua, con la potencia y  en la frecuencia parametrizada. Simultanea lo muestra en pantalla.

 

Espectro de la señal modulada en CW con LoRa  monitorizada con SDR++



El lenguaje de programación de Arduino

Los archivo del lenguaje de programación de Arduino con el que se escriben los bocetos (Sketch) llevan la extensión .INO 

Este lenguaje de programación  está basado en Wiring; y es similar a C/C++. 

Para aprender mas sobre este lenguaje consulte los tutoriales

Algunas pistas

// comentario
/* abre comentario de varias lineas
*/  cierra comentario de varias líneas
; terminación de una instrucción
void setup () {} Función que se ejecuta una vez
void loop () {}  Función que se ejecuta en bucle o de forma continua

Modificaciones al programa

Una vez que consiga que funcione, haga una copia de seguridad y  seguro que le vienen muchas posibles modificaciones.

¿Funcionará en 866 MHZ? 

Sí , basta con modificar la frecuencia, compilar para la placa ESP32 que tengamos (LILYGO ® TTGO LoRa32 V2.1_1.6 versión 433/868/915Mhz ESP32 LoRa OLED 0,96 pulgadas tarjeta SD Bluetooth WIFI módulo inalámbrico ESP-32 SMA SX1276) , en nuestro caso  ESP32 Dev Module y cargar

// EU863 863-870 MHz
#define FREQ_HZ 866500000 // 866.500 MHz

 ¿Funcionará en 144 MHZ? 

En principio con una tarjeta LILYGO ® TTGO LoRa32 V2.1_1.6 versión 433 debe poder trabajar en 144 MHZ (Tengo que probarlo)

¿Cuál es la potencia máxima? ¿Se puede modificar?

Según la especificación es de 20 dBm que corresponde a 100 mW
Sí, se puede modificar hasta el maximo o disminuirlo.  
Recuerde que +3dB es duplicar la potencia y -3dB es la mitad

#define TX_DBM 20

¿Cual es la longitud máxima del mensaje?

Indefinida pero en la pantalla solamente caben 64 caracteres por lo que habría que implementar un contador para que cuando llegue a este valor la borre o cualquier otra solucion.

Una solución rapida es incluir tantas lineas de mensajes de 84 con su borrado y reubicación del cursor, como se desse 

send_message(" ");
display.clearDisplay();
display.setCursor(0, Fixed8x16.yAdvance); 

¿Se pueden generar caracteres de forma aleatoria para practicar?

Hay que definir la semilla para la generación aleatoria y la lista de caracteres

randomSeed(analogRead(0)); // Semilla aleatoria 
const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,;:/?=";
const int alphabetLength = sizeof(alphabet) - 1; // -1 para evitar el carácter nulo 

Y sustituir el codigo de envio de un mensaje por 

int randomIndex = random(0, alphabetLength);char randomLetter[2]; // Arreglo para almacenar la letra y el terminador nulrandomLetter[0] = alphabet[randomIndex];   
randomLetter[1] = '\0'; // Terminador nulo 
send_message(randomLetter);  

Para grupos de 5 caracteres una modificación sencilla es esta
   
int randomIndex1 = random(0, alphabetLength); 
int randomIndex2 = random(0, alphabetLength); 
int randomIndex3 = random(0, alphabetLength); 
int randomIndex4 = random(0, alphabetLength); 
int randomIndex5 = random(0, alphabetLength); 
char randomLetter[6]; 
randomLetter[0] = alphabet[randomIndex1];
randomLetter[1] = alphabet[randomIndex2];
randomLetter[2] = alphabet[randomIndex3];
randomLetter[3] = alphabet[randomIndex4];
randomLetter[4] = alphabet[randomIndex5];
randomLetter[5] = '\0'; 
send_message(randomLetter); 
delay(1000); 

Otras ideas de mejora que requieren algo de programación

  • Emisión con saltos de frecuencia para cazas del zorro con handicap
  • Emisión de una señal de tiempo ( para placas con GPS) 
  • Emisión de las coordenadas ( para placas con GPS) 
  • Emisión de jinggle jugando con el tono
  • ...


Referencias

Comentarios

Entradas populares de este blog

SDR - Software Defined Radio - IIIb: Receptores RSP o MSI (MSI3001: MSI2500 + MSI001)

Amplificadores LNA compactos

Ayudas a la navegación aerea: NDB, VOR, ILS y ATIS