Instrucciones para el dispositivo en Arduino IDE
El esquema para baliza y dispositivo propuesto para el modelo de localización usa el modelo multipunto de LoRa que usa direcciones para identificar la función de cada elemento:
- Baliza: d1,d2,d3
- Dispositivo: c1
El esquema se muestra simplificado para un solo punto, se plantea usar el dispositivo ‘C1’ como punto de captura de datos hacia un archivo tipo texto mediante la conexión USB a un computador portatil.
En el dispositivo, por cada paquete recibido se toman los datos del paquete y valores medidos, creando un registro de trama con: el tipo rx/tx, id receptor, remitente, los datos recibidos y lecturas de RSSI y SNR del paquete recibido desde el remitente que es cada baliza.
rssi_lorarx = LoRa.packetRssi();
snr_lorarx = LoRa.packetSnr();
Registro de la trama de datos
El registro de la trama de datos recibida en el computador se compone de la parte de datos recibido y las lecturas de Rssi-SNR del paquete. El orden de los datos se muestra en la tabla:
esquema de trama de datos
tipo |
receptor |
remitente |
dato1 |
dato2 |
dato3 |
Rssi recibido |
SNR recibido |
rx, tx |
c1, ff |
d1, d2, d3 |
|
|
|
medido en el dispositivo |
medido en el dispositivo |
Ejemplo de trama recibida:
rx,c1,d3,36,-62,6.00,-65,6.00
tx,ff,c1,2,-65,6.00,-65,6.00
rx,c1,d2,21,-130,6.00,-130,6.00
rx,c1,d1,138,-98,18.75,-131,10.25
Para obtener los valores de Rssi y SNR de recepción desde cada baliza, se emite periódicamente un paquete de difusión (‘ff’) desde el dispositivo c1. Los valores recibidos en la baliza se replican en los datos del próximo paquete de la baliza hacia el dispositivo c1, que corresponden a dato2 y dato3.
Para revisar la secuencia del paquete se registra un contador desde el emisor, enviado en la posición de dato1.
Configurar la función de baliza o dispositivo
se establece mediante las direcciones de envío y recepción descritas en la sección principal del algoritmo.
Para el dispositivo la dirección local
es C1 , para las balizas serán D1, D2, D3.
En el dispositivo se usa la dirección local ‘C1’, y como destino una trama de difusión ‘FF’ hacia todas las balizas de tal manera que cada baliza pueda medir el nivel de recepción de la señal emitida desde el dispositivo.
// Direcciones Enviar mensaje
byte dir_local = 0xC1; // Concentrador 1
byte dir_destino = 0xFF; // Broadcast para medir Rssi
byte msjtxContador = 0;
En las balizas, la dirección local de la baliza es D1, D2, D3, y la dirección destino es el dispositivo.
// Direcciones Enviar mensaje
byte dir_local = 0xD1; // Baliza 1
byte dir_destino = 0xC1; // Dispositivo
Otros parámetros como tiempo entre paquetes, se configuran de acuerdo a las lecturas que se tomarán en un intervalo de tiempo. El parámetro t_ciclotx
establece el intervalo de tiempo en que cada dispositivo o baliza emite un paquete.
Para LoRa, los tiempos de envio de paquetes son bastante largos de acuerdo al diseño básico de la red estándar, sin embargo durante el experimiento para tomar las lecturas más rápido en cada ubicación de prueba se puede reducir a por ejemplo, 10 segundos (10000ms)
int t_ciclotx =10000;
otros detalles de configuración del dispositivo se pueden revisar en la sección de referencias al final de la hoja.
Módulos LoRa
El prototipo se implentó con los módulos de desarrollo Heltec Lora 32 V2 disponibles al momento de las pruebas. Los módulos son de 915MHz, y se usaron también con las pruebas de conexión multipunto descritas en LoRa Multipunto – Esquema
Instrucciones en Arduino
Las instrucciones del dispositivo escritas usando el IDE Arduino se presentan en secciones o bloques:
- Principal: LoRa_Listener02
- Receptor: LoRaReceptor
- Transmisor: LoRaTransmisor
- Sensor: Sensores
Sección principal
/* Pruebas de Rssi y SNR multipunto, esquema de triangulación
Nodo- Receptor. http://blog.espol.edu.ec/girni/
Septiembre-2020 */
#include "heltec.h"
// SENSOR Parpadeo
String sensorBlink = "ON"; // inicializa on/off: 1/0
// Direcciones Enviar mensaje
byte dir_local = 0xC1; // Concentrador 1
byte dir_destino = 0xFF; // Broadcast para medir Rssi
byte msjtxContador = 0;
int t_ciclotx = 10000;
long t_anterior = 0;
int t_intervalo = 3000;
// Direcciones Mensaje Recibido
byte dir_envio = 0xC1;
int dir_remite = 0xFF;
String paqueteRcb = "";
byte paqrcbID = 0;
byte paqrcbEstado = 0;
// 0:vacio, 1: nuevo, 2:incompleto
// 3:otro destinatario, 4:Broadcast
int rssi_lorarx = 0;
float snr_lorarx = 0;
// Mensajes por Puerto Serial
volatile boolean serial_msj = true;
#define BAND 915E6 // 868E6,915E6
void setup() {
Heltec.begin(false /*DisplayEnable Enable*/,
true /*Heltec.LoRa Disable*/,
serial_msj /*Serial Enable*/,
true /*PABOOST Enable*/,
BAND /*long BAND*/);
LoRa.setSpreadingFactor(8);
LoRa.receive();
}
void loop() {
// LoRa enviar mensajes entre intervalos
long t_ahora = millis();
long t_transcurrido = t_ahora - t_anterior;
if (t_transcurrido >= t_intervalo){
t_anterior = t_ahora;
t_intervalo = t_ciclotx + random(1000);
// sensorParpadea(); //actualiza sensor
sensorBlink = String(rssi_lorarx)+","+String(snr_lorarx);
String paqueteEnv = String(sensorBlink).c_str() ;
enviarlora(dir_destino, dir_local,
msjtxContador, paqueteEnv);
yield();
// mensaje a serial
if (serial_msj==true){
// muestra todos paqrcbEstado
Serial.print("tx,");
Serial.print(String(dir_destino,HEX)+",");
Serial.print(String(dir_local,HEX)+",");
Serial.print(String(msjtxContador)+",");
Serial.print(String(paqueteEnv)+",");
Serial.print(String(rssi_lorarx)+",");
Serial.println(snr_lorarx);
}
msjtxContador = msjtxContador + 1;
// LED parpadea envio LoRa
digitalWrite(LED, HIGH); delay(100);
digitalWrite(LED, LOW); delay(100);
yield(); // procesa wifi
}
// LoRa revisar mensajes entrantes
int msjRcbLoRa = LoRa.parsePacket();
if (msjRcbLoRa !=0){ //¿mensaje no vacio?
recibirlora(msjRcbLoRa);
rssi_lorarx = LoRa.packetRssi();
snr_lorarx = LoRa.packetSnr();
if (serial_msj==true){
// muestra todos los tipos
//Serial.print("Paquete recibido, Estado: ");
//Serial.println(paqrcbEstado);
Serial.print("rx,");
Serial.print(String(dir_envio,HEX)+",");
Serial.print(String(dir_remite,HEX)+",");
Serial.print(String(paqrcbID)+",");
Serial.print(String(paqueteRcb)+",");
Serial.print(String(rssi_lorarx)+",");
Serial.println(String(snr_lorarx));
}
yield(); // procesa wifi
}
}
Sección Receptor
En esta sección se revisa la trama, separando cada una de las partes del paquete recibido: dirección de envío, dirección de remitente, identificador del paquete generado por un contador de secuencia.
Se verifica que el destinatario del paquete, si el tamaño de la trama indica que el mensaje está completo, si la trama es de difusión (broadcast) usada para registrar los niveles de recepción.
void recibirlora(int tamano){
if (tamano == 0){
paqrcbEstado = 0; //vacio
return;
}
// lectura de paquete
paqueteRcb = "";
dir_envio = LoRa.read();
dir_remite = LoRa.read();
paqrcbID = LoRa.read();
byte paqrcbTamano = LoRa.read();
while(LoRa.available()){
paqueteRcb += (char)LoRa.read();
}
if (paqrcbTamano != paqueteRcb.length()){
paqrcbEstado = 2; // Tamaño incompleto
return;
}
if (dir_envio != dir_local){
if (dir_envio == 0xFF) {
paqrcbEstado = 4; // Broadcast
}else{
paqrcbEstado = 3; // otro destino
}
return;
}
paqrcbEstado = 1; // mensaje Nuevo
}
Sección de transmisor
En esta sección se verifica que el canal no se encuentre ocupado o que el dispositivo este listo para transmitir.
Se arma el paquete a enviar y se transmite.
void enviarlora(byte destino, byte remite,
byte paqueteID, String paquete) {
// espera que el radio esté listo
// para enviar un paquete
while(LoRa.beginPacket() == 0){
if (serial_msj==true){
Serial.println("Esperando radio disponible...");
}
yield(); // procesa wifi
delay(100);
}
// envio del mensaje LoRa
LoRa.beginPacket();
LoRa.write(destino);
LoRa.write(remite);
LoRa.write(paqueteID);
LoRa.write(paquete.length());
LoRa.print(paquete);
LoRa.endPacket();
}
Sección Sensor
La sección del sensor no es requerida para el registro de Rssi y SNR, por lo que se simula con un parpadeo de LED.
// Sensor Simulado
void sensorParpadea(){
if (sensorBlink == "ON"){
sensorBlink = "OFF";
}else{
sensorBlink = "ON";
}
return;
}
Referencias: LoRa Multipunto – Esquema