Contenido del curso
Fundamentos de LoRa
Configuración del proyecto
LoRa con ESP32
Aplicaciones con LoRa
Redes LoRa
Recibir mensajes LoRa en ESP32 con FreeRTOS
Resumen
Recibir mensajes con LoRa en ESP32 implica poner el radio en modo escucha, leer paquetes entrantes y mostrar datos como la intensidad de señal en una pantalla OLED. Si estás aprendiendo desarrollo con FreeRTOS y módulos LoRa, esta guía te muestra cómo armar la lógica de recepción dentro de una tarea, con buenas prácticas para evitar errores comunes en C.
¿Cómo poner el radio LoRa en modo de escucha?
Antes de leer cualquier paquete, el radio necesita estar activo y atento. Eso lo logras con la función LoRa.receive() que vive dentro del archivo LoRa.h del componente.
Dentro de la tarea encargada de recibir, justo después de abrir el for infinito, llamas a LoRa.receive(). Con esa línea ya tienes el radio escuchando continuamente, listo para detectar cualquier transmisión cercana que use el mismo protocolo.
¿Qué hace LoRa.receive()? Pone el módulo de radio en modo escucha para que detecte paquetes entrantes. Sin esta llamada, el radio no captura nada.
¿Por qué usar un while para detectar mensajes entrantes?
Una vez en modo escucha, necesitas reaccionar solo cuando llegue algo. Para eso usas un while con la función LoRa.received() (ojo, termina en d), que retorna distinto de cero cuando hay datos disponibles.
Si retorna cero, el bloque se salta y la tarea continúa. Si hay datos, entras al while y procesas el mensaje. Recuerda que en C, cualquier valor positivo se evalúa como verdadero, por eso esta función encaja natural dentro de la condición.
¿Cómo leer un paquete LoRa recién llegado?
Para extraer el contenido del paquete usas LoRa.receivePacket(buffer, tamaño). Esta función devuelve el número de bytes recibidos y necesita dos argumentos: un buffer donde guardar el mensaje y el tamaño máximo de ese espacio en memoria.
El buffer debe ser de tipo uint8_t, es decir, entero de 8 bits sin signo. Como vas a reutilizar ese mensaje en otras partes del programa, conviene declararlo como variable global junto a la pantalla.
¿Qué tamaño debe tener el buffer del mensaje?
Un paquete LoRa admite hasta 240 caracteres aproximadamente. En lugar de escribir ese número suelto por todo el código, defines una macro:
c #define MESSAGE_LENGTH 240 uint8_t msg[MESSAGE_LENGTH];
Además necesitas dos variables auxiliares más: packets para contar cuántos mensajes han llegado y rssi para guardar la intensidad de señal en dBm. Ambas inician en cero.
¿Qué es el RSSI en LoRa? Es la intensidad con la que llega la señal al receptor, medida en dBm. Valores menos negativos indican mejor recepción.
¿Por qué necesitas un carácter de finalización en C?
Las cadenas de texto en C terminan con un carácter cero. Si no lo agregas, el lenguaje sigue leyendo memoria más allá del mensaje real y arrastra basura o ruido de iteraciones anteriores.
El truco es simple: si la función te devolvió que llegaron length caracteres, marcas la posición msg[length] = 0. Así, aunque el buffer tenga 240 espacios, la cadena se corta exactamente donde termina el mensaje real.
c int length = LoRa.receivePacket(msg, MESSAGE_LENGTH); msg[length] = 0;
¿Cómo mostrar el RSSI y el conteo de paquetes en la OLED?
La pantalla OLED de 128x64 píxeles se actualiza con la función screen_print(texto, renglón) que ya tenías creada. Pero solo recibe cadenas, no enteros, así que primero conviertes los números con sprintf.
Declaras dos buffers de 64 caracteres dentro de la tarea pero fuera del for, para que mantengan su valor entre iteraciones:
c char packets_count[64]; char rssi_string[64]; sprintf(packets_count, "count %d", packets); sprintf(rssi_string, "rssi: %d dBm", rssi); screen_print(packets_count, 0); screen_print(rssi_string, 1);
El valor de rssi lo obtienes con LoRa.packetRssi(), que retorna el RSSI del último paquete recibido. El contador packets simplemente se incrementa con packets++ cada vez que entras al while.
¿Por qué siempre debes incluir un vTaskDelay en FreeRTOS?
Este detalle es fácil de olvidar y rompe todo. Dentro de cualquier tarea de FreeRTOS, antes de cerrar el for infinito, debes incluir al menos una pausa mínima.
Sin esa pausa, la tarea se cicla eternamente y el sistema operativo no puede ceder tiempo a otros procesos. El resultado es un error en RTOS. La solución cabe en una línea:
c vTaskDelay(1);
Con el valor mínimo de 1 ya garantizas que el scheduler pueda intervenir. También recuerda llamar a LoRa_config_init() desde tu app_main, porque si no, nada de esto se ejecuta y solo verás el "Hola, mundo" original.
Compila el ejercicio y revisa que no haya errores antes de pasar a la emisión de mensajes. ¿Ya lograste capturar algún paquete en tu zona? Cuéntame en los comentarios qué RSSI estás viendo.