Objetivos
Material requerido.
Un M5Stack | |
Una radio LORAWAN para M5stack |
Empezando con LORAWAN
Hemos visto en la última sesión que era LORA y como podíamos usarlo de forma práctica con nuestro muy amado entorno Arduino / ESP32 usando un M5STACK y un módulo LORA. Enviamos y recibimos algunos mensajes de un equipo a otra de un modo de lo mas sencillo (Para cualquiera que programe un poco en C++)
Y naturalmente en cuanto alguien empieza a hablar de LORA alguien levanta el brazo y pregunta… ¿Y qué hay de LORAWAN? Y claro, al final teníamos que hablar del asunto, pero de momento hemos conseguido deciros ya que LORA permite comunicaciones punto a punto entre nodos iguales, a baja velocidad, pero largo alcance y además con muy poco consumo, lo que le hace ideal para la IOT y para aplicaciones en áreas poco pobladas o donde el dotar de comunicaciones cableadas o áreas son relativamente caras.
Pero LORA se queda escandalosamente corta en aplicaciones de grupo que requieran consolidada datos. Imagínate una red de sensores de humedad, temperatura y presión, repartidas por los montes (Que de hecho existe) y separadas por varios Km de distancia. ¿Cómo envían los datos con los que nos dan el parte meteo? Pues normalmente por satélite o bien por enlaces de microondas rurales (Ambas cosas son caras y requieren antenas especiales)
Por eso, la tecnología estaba pidiendo a gritos un protocolo de red que corriese sobre LORA y que permitiese reportar esos datos remotos a un concentrador, que aquí se llama Gateway, y que los pasase a internet de forma transparente y no nos complique la vida a los que queremos programar Arduinos.
LORAWAN permite montar un Gateway en estrella con el que todos los nodos LORA pueden conectarse y transferir, las escasas medidas de temperatura y demás, a internet de forma transparente y con un mínimo de complicaciones. LORAWAN es un protocolo de acceso a la red, con capacidad de gestionar la transmisión de los mensajes en cualquier dirección sin preocuparte de pensar a nivel de nodo.
Las redes LORAWAN suelen constar de uno o más Gateways con el que enlazan los nodos y enrutan el resultado a los servidores de internet para su posterior proceso. Además, encriptan las comunicaciones entre nodo y Gateway (Que en LORA están desprotegidas) y permiten la conexión remota de los nodos a través del aire para registrarse en el Gateway
Ventajas de LORAWAN
He visto que hay redes LORAWAN de acceso más o menos públicas, en muchos puntos del mundo incluyendo en España, aunque no tengo muy claro como conectar con ellas. Aquí os dejo un link para que veáis si tenéis un acceso LORAWAN cerca de casa: https://www.thethingsnetwork.org/map
Ejemplo de programa de conexión
Para conectar a una red LORAWAN necesitamos acceso a un Gateway y lamentablemente no dispongo de uno, así que, para la parte práctica de esta sesión, vamos usar los módulos LORAWAN de M5Stack con un ejemplo de comunicaciones en abierto entre dos nodos.
- Si a alguno de los lectores le sobra un Gateway LORAWAN y desea donarlo a la ciencia, que me llame y enseguida montaremos unos tutos de ejemplo, pero me temo que hasta entonces no vamos a tener más remedio que usar el sistema del pobre. .[/fancy-ul] [/three-fourth]
Vamos a montar un ejemplo de uso de los M5stack con LORAWAN basado en el único ejemplo que he conseguido encontrar por ahí, el de M5stack, y que hace las veces de enviar y recibir, de un modo bastante sencillo, aunque no he podido resistirme a retocarlo un poco para facilitar el ejemplo.
Vamos a hacer un programa LORAWAN que envíe y reciba mensajes entre dos nodos sin usar un Gateway, (Que no tenemos, claro) como en LORA, pero usando las librerías LORAWAN para ilustrar su uso.
Usaremos los botones del M5 para borrar la pantalla cuando queramos y para cambiar la velocidad de transmisión de 433 a 866 MHz por aquello de enredar un poco.
Programando LORAWAN con M5Stack
Empecemos con las librerías que no van a sorprender a nadie:
#include <M5Stack.h> #include <LoRaWan.h>
Normalmente en cuanto arrancamos un módulo LORAWAN es interesante buscar un Gateway que nos provea de claves de encriptación, para garantizar la comunicación segura y para eso debe de ser esta función, que me sale por todos sitios, pero de la que no he conseguido ninguna información:
void key_scan(void *arg) { while (1) { onReceive(); delay(10); // lora.loraDebug(); } vTaskDelete(NULL); }
Vamos a por el setup :
M5.begin(); M5.Power.begin(); Serial.begin(9600); // Lora es lento, no necesitamos mas lora.init(); delay(2000); // must delay for lorawan power on
Las dos primeras líneas inicializan el M5 y la gestión de energía de la batería como siempre para después arrancar el Serial a 9600. Recuerda que la velocidad del LORAWAN es bastante más baja que eso. Por último, iniciamos lora.
lora.initP2PMode(433, SF12, BW500, 8, 8, 20); M5.Lcd.setTextFont(2); M5.Lcd.println("Device B"); M5.Lcd.setTextColor(BLUE); int core = xPortGetCoreID(); // M5.Lcd.println(core); xTaskCreatePinnedToCore(key_scan, "key_scan", 3096, NULL, 5, NULL, 0);
Algunas de las líneas de arriba son bastante oscuras porque no he encontrado documentación, pero parece que funciona, así que a ser buenos y a dejarlas como están, pero está claro que la primera línea arranca el LORA en modo point to point con la frecuencia 433 MHz y las de M5 nos ponen unas letras que podamos leer en pantalla.
En el loop básicamente leemos los botones del M5 para cambiar la frecuencia de la radio
void loop(void) { if (M5.BtnA.wasPressed()) // Borra la pantalla { M5.Lcd.setCursor(0, 18); M5.Lcd.fillRect(0, 18, 320, 222, BLACK); } }
Nada nuevo hasta aqui. Simplemente borramos la pantalla cuando pulsamos el Boton A.
if (M5.BtnB.wasPressed()) //send data (433MHz) { flag_test_868 = 0; M5.Lcd.setTextColor(BLUE); lora.initP2PMode(433, SF12, BW500, 8, 8, 20); // Cambiar frecuencia de la radio send_data(); delay(300); Serial2.print("AT+TEST=RXLRPKT\r\n"); M5.Lcd.println("433M Init and Send \"Hello World\"..."); }
Con el código de arriba lo que hacemos es cambiar la frecuencia de la radio a 433 MHz y definimos los parámetros de la comunicación, después llamamos a la función send_data() para que envíe un mensaje básico y por último la siguiente línea merece una explicación propia:
Serial2.print("AT+TEST=RXLRPKT\r\n");
No he encontrado demasiada información al respecto pero parece que el fabricante recomienda usar el módulo LORAWAN mediante comandos AT que para los seguidores de Prometec son bastante familiares.. Básicamente esta línea pone el módulo en modo TEST (Que no estoy muy seguro de lo que es, pero parece ser un modo de recibir información de la radio sin peligro de modificar sus parámetros) y después da la orden de espera la recepción de paquetes de comunicación, y cuando recibimos uno de estos paquete entra en marcha la función onReceive()
Para el caso de que pulsemos el botón C, el código es completamente similar:
if (M5.BtnC.wasPressed()) //send data (868MHz) { flag_test_868 = 1; M5.Lcd.setTextColor(YELLOW); lora.initP2PMode(868, SF12, BW500, 8, 8, 20); send_data(); delay(300); Serial2.print("AT+TEST=RXLRPKT\r\n"); M5.Lcd.println("868M Init and Send \"Hello World\"..."); } M5.update();
Después de lo visto, nos faltan por definir las funciones send_data() para enviar mensajes y la función onReceive() para cuando entre un mensaje. Vamos con ello.
La función send_data() es lo más simple del mundo. Únicamente emvía un mensaje “Hello world” cuando se activa, (que será al pulsar uno de los botones B o C) y de paso vemos como mandamos un mensaje de texto a través de la radio:
void send_data() { lora.transferPacketP2PMode("hello world"); }
Para la función onReceive el fabricante nos recomienda usar este codigo código:
void onReceive() { short length = 0; short rssi = 0; memset(buffer, 0, 128); length = lora.receivePacketP2PMode(buffer, 128, &rssi, 1);
Vamos a imprimir la longitud y la frecuencia en pantalla y lanzamos un mensaje con las características:
if (length) { Serial.print("Length is: "); Serial.println(length); Serial.print("RSSI is: "); Serial.println(rssi); Serial.print("Data is: "); if (flag_test_868) { M5.Lcd.print("868M Recv: "); } else { M5.Lcd.print("433M Recv: "); }
Imprimimos en pantalla la frecuencia de recepción y ya podemos leer el mensaje al buffer que creamos más arriba
for (unsigned char i = 0; i < length; i++) { Serial.print((char)buffer[i]); M5.Lcd.print((char)buffer[i]); // Serial.print("0x"); // Serial.print(buffer[i], HEX); // Serial.print(" "); } Serial.println(); M5.Lcd.println();
Aquí os dejo el programa completo: Programa LORAWAN para M5stack
Y eso es todo. Me ha parecido bastante sencillo de manejar, aunque algunas instrucciones han resultado un tanto obscuras de comprender en detalle pero al final, la idea de usar librerías es precisamente que nos liberen de bajar al fango a mancharnos los pantalones, por lo que no me puedo quejar mucho ya que siempre he pensado que ser vago es una virtud. Sirve para hacer el mejor trabajo con el mínimo esfuerzo (También le llaman eficiencia)
Aquí va un mini video con el resultado: