Llevo algún tiempo trabajando con redes LoRa y LoRaWAN, tanto en temas de trabajo, como finalmente desde el punto de vista profesional. En este último ámbito voy a tener que hacer un estudio de cobertura de una red LoRaWAN para uno de nuestros clientes: la idea es registrar una serie de parámetros de los equipos que se van a instalar en una planta de producción, para lo que es necesario determinar los puntos más adecuados para instalar los gateways que encaminarán la información de los dispositivos. Todo esto implica recorrerse la planta, realizando pruebas de ubicación de los mismos y registrar estos parámetros.
Para ello voy a utilizar, dado que la red LoRaWAN del cliente aún no está constituida, la red The Things Network, que ofrece toda la información que necesito. Sin embargo, la red TTN es una red de transporte, y aunque muestra la información que necesito, no la consolida. Al fin y al cabo se trata de eso, de transportar. El tema del almacenaje ha de realizarse por otro lado. Podría apuntar estos valores a mano, pero he encontrado una manera más divertida de realizarlo: registrar los parámetros y la información de la red con Google Spreadsheet. Ojo, este mecanismo está muy bien para pruebas preliminares y análisis como el que estoy buscando, pero no debe ser usado en un entorno en producción, ya que no se establecen (es más, se eliminan) mecanismos de seguridad de las comunicaciones o de la información alguno.
El artículo que enlazo explica perfectamente cómo hacerlo, pero dejo aquí los pasos generales:
// 2017 by Daniel Eichhorn, https://blog.squix.org
// Inspired by https://gist.github.com/bmcbride/7069aebd643944c9ee8b
// Create or open an existing Sheet and click Tools > Script editor and enter the code below
// 1. Enter sheet name where data is to be written below
var SHEET_NAME = "Sheet1";
// 2. Run > setup
// 3. Publish > Deploy as web app
// - enter Project Version name and click 'Save New Version'
// - set security level and enable service (most likely execute as 'me' and access 'anyone, even anonymously)
// 4. Copy the 'Current web app URL' and post this in your form/script action
var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service
// If you don't want to expose either GET or POST methods you can comment out the appropriate function
function doGet(e){
return handleResponse(e);
}
function doPost(e){
return handleResponse(e);
}
function handleResponse(e) {
var lock = LockService.getPublicLock();
lock.waitLock(30000); // wait 30 seconds before conceding defeat.
try {
// next set where we write the data - you could write to multiple/alternate destinations
var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
var sheet = doc.getSheetByName(SHEET_NAME);
// we'll assume header is in row 1 but you can override with header_row in GET/POST data
//var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow()+1; // get next row
var row = [];
var headerRow = [];
// loop through the header columns
var jsonData = JSON.parse(e.postData.contents);
headerRow.push("jsonData.app_id");
headerRow.push("jsonData.dev_id");
headerRow.push("jsonData.hardware_serial");
headerRow.push("jsonData.port");
headerRow.push("jsonData.counter");
headerRow.push("jsonData.payload_raw");
headerRow.push("jsonData.payload_decoded");
headerRow.push("jsonData.metadata.time");
headerRow.push("jsonData.metadata.frequency");
headerRow.push("jsonData.metadata.modulation");
headerRow.push("jsonData.metadata.data_rate");
headerRow.push("jsonData.metadata.coding_rate");
headerRow.push("jsonData.metadata.downlink_url");
for (var i = 0; i < jsonData.metadata.gateways.length; i++) {
var gateway = jsonData.metadata.gateways[i];
headerRow.push("gateway.gtw_id");
headerRow.push("gateway.timestamp");
headerRow.push("gateway.channel");
headerRow.push("gateway.rssi");
headerRow.push("gateway.snr");
headerRow.push("gateway.latitude");
headerRow.push("gateway.longitude");
headerRow.push("gateway.altitude");
}
sheet.getRange(1, 1, 1, headerRow.length).setValues([headerRow]);
row.push(jsonData.app_id);
row.push(jsonData.dev_id);
row.push(jsonData.hardware_serial);
row.push(jsonData.port);
row.push(jsonData.counter);
row.push(jsonData.payload_raw);
var raw = Utilities.base64Decode(jsonData.payload_raw);
var decoded = Utilities.newBlob(raw).getDataAsString();
row.push(decoded);
row.push(jsonData.metadata.time);
row.push(jsonData.metadata.frequency);
row.push(jsonData.metadata.modulation);
row.push(jsonData.metadata.data_rate);
row.push(jsonData.metadata.coding_rate);
row.push(jsonData.metadata.downlink_url);
for (var i = 0; i < jsonData.metadata.gateways.length; i++) {
var gateway = jsonData.metadata.gateways[i];
row.push(gateway.gtw_id);
row.push(gateway.timestamp);
row.push(gateway.channel);
row.push(gateway.rssi);
row.push(gateway.snr);
row.push(gateway.latitude);
row.push(gateway.longitude);
row.push(gateway.altitude);
}
// more efficient to set values as [][] array than individually
sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
// return json success results
return ContentService
.createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))
.setMimeType(ContentService.MimeType.JSON);
} catch(e) {
// if error return this
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error": e}))
.setMimeType(ContentService.MimeType.JSON);
} finally { //release lock
lock.releaseLock();
}
}
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
SCRIPT_PROP.setProperty("key", doc.getId());
}
Y con esto, la información generada por nuestros dispositivos LoRaWAN registrados en TTN pasará a almacenarse de manera automática en nuestra hoja de cálculo:
Etiquetas: google spreadsheet, lorawan, the things network
Comentaba en un artículo anterior de la serie que había implementado un gateway LoRa*. Y no me faltaba razón. Estaba haciendo uso del protocolo LoRa de enlace basado en 868 MHz para enviar señales de entre un nodo emisor y un receptor, y de este último a un servidor MQTT. ¿Cuál es la diferencia? La más importante es que no estaba realizando ningún tipo de verificación de nodos, sin ni siquiera molestarme en verificar cuál es el emisor y cuál el receptor. Y ni hablemos de cifrado de comunicaciones ni nada que se le parezca. Pero para las pruebas preliminares que venía efectuando, en lo que el aspecto importante era verificar alcance entre nodos, sobraba y bastaba. Por cierto, para ver más detalles de las diferencias entre LoRa y LoRaWAN, tengo otro artículo dedicado a tal efecto.
Pero para este proyecto necesitaba dar un paso más allá, e implementar un verdadero gateway LoRaWAN. Y eso implicaba hacer uso de una red LoRaWAN, que proporcione su servidor de procesado de tráfico de red, y te permita explotar los datos enviados desde los dispositivos. Cuando te enfrentas a esto, tienes dos posibilidades: o te implementas la red, o te conectas a una ya existente. Sobre la primera opción ya hablaremos más adelante, en un artículo al respecto, pero para salir rápidamente del paso hice uso de la segunda. Existe una red pública a la que puedes conectar gateways y dispositivos LoRaWAN, que es la red The Things Network, o TTN. Cuando te registras como usuario, puedes añadir a la red tanto dispositivos como gateways. Si haces lo primero, dependes de que haya algún gateway cercano a ti para que tus dispositivos envíen datos a la red. Pero si no tienes ningún gateway a tu alcance, no te queda otra que implementar un gateway, y conectarlo a la red. Que es precisamente de lo que va esta serie.
Tengo que decir algo desde un principio: estoy haciendo trampas. Una de las especificaciones del protocolo LoRaWAN es que a la hora de establecer un enlace entre dispositivo y gateway se puede utilizar de manera aleatoria cualquier canal de la banda que estés utilizando. En el caso de Europa, la banda es la de 868 MHz, y existen 9 canales dedicados a tal efecto (aunque en realidad son 8+1). La razón para ello es evitar la congestión en cualquiera de los canales, siendo la red la encargada de analizar esta circunstancia, y la responsable de tomar las medidas necesarias (cambio de canal) para solucionarlo. Para ello, la idea es que cuando se configura un nuevo gateway, tu hardware tiene que estar preparado para operar en estos canales. El problema, en mi caso, es que el hardware del que dispongo sólo es capaz de funcionar en un solo canal. ¿Y cuál es este hardware? Nuestro viejo amigo el Heltec LoRa 32.
Tras trastear un poco por Internet, encontré un proyecto bastante interesante de Things4U que consiste exactamente en eso: implementar un gateway de un solo canal. Por supuesto, es un proyecto experimental que no debe usarse en un sistema en producción, pero para mis propósitos de investigación basta y sobra. La instalación es bastante sencilla: tan simple como descargar el código (viene con todas sus librerías), y en el caso de Arduino, hacer lo siguiente:
Captura de pantalla de la web de administración del gateway
Si todo ha ido bien, tu gateway se conectará a la red TTN (donde es preciso configurar tu gateway, aunque por lo que he visto no parece interactuar demasiado bien con la información de estado del mismo), y es cuestión de encender un dispositivo, empezar a emitir, y ver entrar los paquetes en tu aplicación:
…sí claro. Ojalá. Y es que hay un pequeño problema. Con esto hemos configurado nuestro gateway para que trabaje en un solo canal, pero por defecto nuestro dispositivo trabajará en cualquier canal de la banda, de manera aleatoria. Y esto implica que sólo vamos a recibir, estadísticamente hablando, 1 de cada 9 paquetes enviados. Una tasa bastante baja. ¿Cuál es la solución? Obviamente, forzar al dispositivo a emitir en una sola banda. Existe un tutorial de Sparkfun que lo explica bastante bien, pero para el caso de los dispositivos Heltec LoRa es necesario trastear un poco más, y especificar los valores del dispositivo:
const lmic_pinmap lmic_pins = {
.nss = 18,
.rxtx = LMIC_UNUSED_PIN,
.rst = 14,
.dio = {26, 35, 33},
};
…y con eso, ¡listos! Bueno, casi. Para los Heltec LoRa 32 vale, pero por desgracia no para los Cube Cell que estoy empleando, ya que las implementaciones de la librería LMIC que he encontrado no parecen funcionar bien con estos dispositivos. ¿La solución? Ser un poco más imaginativo. En mi caso, he modificado los parámetros de la librería LoRaWan_APP del fabricante, para hacer que todas las definiciones de la banda de 868 MHz trabajen exactamente en la frecuencia del canal 0, que es que se utiliza por parte del servidor. En concreto, se trata de localizar el fichero RegionEU868.h (en el directorio packages\CubeCell\hardware\CubeCell\1.x.0\cores\asr650x\loramac\mac\region), y modificar lo siguiente:
#define EU868_LC1 { 868100000, 0, { ( ( DR_5 < < 4 ) | DR_0 ) }, 1 }
/*!
* LoRaMac default channel 2
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
*/
#define EU868_LC2 { 868100000, 0, { ( ( DR_5 < < 4 ) | DR_0 ) }, 1 }
/*!
* LoRaMac default channel 3
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
*/
#define EU868_LC3 {868100000, 0, { ( ( DR_5 < < 4 ) | DR_0 ) }, 1 }
#define EU868_LC4 { 868100000,0, { ( ( DR_5 < < 4 ) | EU868_TX_MIN_DATARATE ) }, 0 }
#define EU868_LC5 { 868100000,0, { ( ( DR_5 < < 4 ) | EU868_TX_MIN_DATARATE ) }, 0 }
#define EU868_LC6 { 868100000,0, { ( ( DR_5 < < 4 ) | EU868_TX_MIN_DATARATE ) }, 0 }
#define EU868_LC7 { 868100000,0, { ( ( DR_5 < < 4 ) | EU868_TX_MIN_DATARATE ) }, 0 }
#define EU868_LC8 { 868100000,0, { ( ( DR_5 < < 4 ) | EU868_TX_MIN_DATARATE ) }, 0 }
Sí, es una ñapa. Pero una ñapa que funciona. Una vez hecho esto y subido el código al Cube Cell, todo va como la seda. Y aprovechando que me encontraba en Córdoba, me decidí a hacer algunas pruebas adicionales de transmisión de datos: un verdadero (bueno, de aquella manera) gateway LoRaWAN conectado a la red TTN, y un dispositivo emitiendo de manera periódica una información sencilla (00 01 02 03). La idea era probar la transmisión en un entorno urbano, con orografía acusada, y sin visibilidad directa, y con el emisor haciendo uso de las antenas por defecto que proporciona el fabricante. Nada de antenas avanzadas. Y el resultado fue bastante mejor del esperado. EL sistema pudo cubrir sin interrupciones todo el parque de la Asomadilla con un único gateway, incluso en zonas donde la curvatura del terreno oculta de manera total el emisor del receptor.
Emisor en el punto más alejado del parque
Como comentaba, el sistema fue capaz de proporcionar cobertura en todo el Parque de la Asomadilla de Córdoba.
Imagen de la zona cubierta
Es de esperar que en una zona con una ubicación óptima (zona alta del parque) la zona de cobertura fuera muy superior. Pero eso ya quedará para otro día.
Etiquetas: 868 MHz, arduino, cubecell, heltec, lora, lorawan, the things network, ttn
Llevo ya un par de artículos sobre las pruebas que he estado efectuando con enlaces soportados con tecnología LoRa, y no podía postergar más el hablar sobre una tecnología que va un paso más alla: LoRaWan. LoRaWan, en líneas generales, es un protocolo de comunicaciones que, haciendo uso de tecnología LoRa, permite proporcionar conectividad a múltiples dispositivos que se basan en LoRa. La idea básica es que LoRa proporciona los enlaces punto a punto, mientras que LoRaWan proporciona una red de comunicaciones. Para ello se apoya en la definición de dos tipos de dispositivos, los nodos y los gateways. Los primeros son los dispositivos individuales -por lo general IoT- que actúan como clientes, enviado y recibiendo información de la red. Los segundos, por su lado, conforman la infraestructura que enlaza los clientes individuales con el resto del sistema, actuando como pasarela con redes convencionales como puede ser Internet.
En toda esta introducción la palabra importante es red. Mientras que en mis pruebas anteriores hacía uso de un par de dispositivos enlazados, aquí se trata de dar un paso más allá. ¿Y cómo haces uso de una red? Bueno, hay dos maneras: o la construyes, o usas una ya existente. La primera opción es viable en el caso de querer construir una red privada, para algún cliente o un proyecto concreto, pero en la mayoría de los casos no es un escenario realista. Pero en cuanto a la segunda, es esta la parte realmente interesante de los sistemas LoRaWan. Existen redes, tanto públicas como privadas, a las que es posible conectarse y hacer uso de las mismas. Y una de las redes abiertas más conocidas a nivel mundial es The Things Network, también conocida como TTN.
Cuando, de nuevo hace ya un par de años largos, adquirí mis dispositivos LoRa, cometí un error de novato. Pedí un dispositivo de 868 MHz y otro de 433. Algo que hacía perfectamente inútiles los intentos de comunicación entre ellos. Esa fue la razón para adquirir un segundo dispositivo de 433 MHz para mis pruebas de enlace punto a punto. ¿Pero qué hacer con el kit de 868 MHz? Podía comprar un segundo y hacer lo mismo, pero fue entonces cuando tuve noticias de TTN. Una red LoRaWan que permite el acceso gratuito a la misma para la transmisión y recepción de mensajes (aunque con límites de capacidad -fair use-), pero que para una transmisión de pruebas de un sistema IoT era más que sobrado. La pregunta es: ¿existía un despliegue de esa red en Sevilla? Y la respuesta es que sí.
Como se puede ver en el mapa de gateways, hay un buen nivel de cobertura de la red TTN en Sevilla capital y el Aljarafe… salvo en Santiponce. En efecto, hice algunas pruebas en casa, con resultados completamente infructuosos. Pero en la Isla de La Cartuja, donde está mi oficina, había cobertura teórica, y dos gateways en las inmediaciones, a unos 1500 y 1700 metros de distancia. Cerca del límite teórico del alcance de los Heltec, y más dentro de un edificio. Pero era cuestión de hacer la prueba. Así que aprovechando un día, al comienzo del confinamiento, en que tuve que desplazarme a la oficina por razones de continuidad de negocio, aproveché para hacer algunas pruebas de conexión.
Para ello hice uso de una librería específica que Heltec ha desarrollado para las conexiones LoraWan, además de registrar -paso obligado- mi dispositivo para obtener una licencia de uso de Heltec. Además de esto, es necesario registrarse en TTN y configurar una aplicación para poder hacer uso de la red, además de registrar tu dispositivo a fin de obtener una serie de identificadores únicos para los dispositivos que se habrán de conectar a la red. Se pueden seguir los pasos en el siguiente artículo: Heltec ESP32 Board + The Things Network. Y tras algunas pruebas, ajustes y apretar -metafórico- de tuercas…
…conseguí establecer de manera exitosa sendos enlaces con dos de los gateways cercanos a la Isla de La Cartuja. En concreto, a los ubicados en la Alameda de Hércules y la Plaza de la Encarnación, con una distancia máxima de algo más de 1700 metros desde mi ubicación, como se puede apreciar en la siguiente imagen:
La prueba no dio para mucho más, ya que tenía otros menesteres de los que ocuparme en la oficina, pero sirvió para demostrar que era posible trabajar con TTN y dispositivos Heltec, incluso haciendo uso de la antena de fábrica en condiciones adversas. En fechas posteriores, visto el éxito de la prueba en la oficina, realicé algunas nuevas pruebas de larga distancia desde Santiponce, tanto con antenas de fabricación propia (hasta la base está sacada con la impresora 3D)…
…como con antenas fabricadas por terceros:
En ninguno de los casos logré un enlace con ninguna de las redes de TTN en Sevilla o el Aljarafe. No es sorprendente, ya que la más cercana se encuentra a 7 km. de distancia de mi domicilio, y obstaculizadas por la orografía del terreno, y edificios que se interponen en la línea de visión directa. Además, en todos los casos he usado antenas omnidireccionales. Queda por realizar una prueba con antenas direccionales (estoy pensando en una tipo yagi), pero antes de eso, aún tengo que hacer pruebas con línea directa de visión y las antenas de las que actualmente dispongo. El lugar perfecto es el cerro de Santa Brígida, en Camas. Estoy deseando que podamos realizar más deplazamientos para acercarme con la bici y hacer estas pruebas.
Etiquetas: 868 MHz, esp32, heltec, impresora 3d, lora, lorawan, santiponce, sevilla, the things network, ttn, yagi