lora_logger.py
En el ordenador, este script pyserial consume la pasarela LoRa, escribe cada trama en un CSV con marca de tiempo y muestra un histograma del RSSI en caracteres. Sigues en directo el alcance de las estaciones y el efecto de mover una antena, sin software propietario.
Hardware
Una Arduino MKR WAN 1300 (microcontrolador SAMD21, módem LoRa Semtech SX1272 para enlaces punto a punto, sin pila LoRaWAN integrada, antena de 868/915 MHz). PC con Python 3 + pyserial, la pasarela MKR WAN conectada por USB, estaciones emitiendo cerca.
Cableado
Nada más que el cable USB de la pasarela; el script salta la cabecera CSV que emite el sketch.
Funcionamiento
El bucle for sobre el objeto serie itera línea a línea; el reparto por punto y coma separa metadatos y carga. El RSSI se mapea a una barra # para seguimiento visual inmediato.
Ejecución
Instala Arduino SAMD Boards y la librería MKRWAN, selecciona la placa y carga. Hacen falta DOS placas LoRa (dos MKR WAN 1300, o una 1300 y una 1310) para ver los intercambios; fija el mismo plan de frecuencias en el código.
Variantes
Traza con matplotlib para las curvas de alcance o ejecuta el script con systemd en un Raspberry Pi para registro permanente.
lora_logger.py
#!/usr/bin/env python3
"""Lit la passerelle LoRa (passerelle-usb.ino) et journalise en CSV.
Usage : python lora_logger.py [port]
"""
import csv
import sys
import time
import serial
PORT = sys.argv[1] if len(sys.argv) > 1 else "/dev/ttyACM0"
def principal() -> None:
with serial.Serial(PORT, 115200, timeout=1) as carte, \
open("lora.csv", "a", newline="") as fh:
ecrivain = csv.writer(fh)
for ligne in carte:
l = ligne.decode(errors="replace").strip()
if l.count(";") < 3 or l.startswith("millis"):
continue
t_carte, rssi, snr, *trame = l.split(";")
horloge = time.strftime("%H:%M:%S")
ecrivain.writerow([horloge, t_carte, rssi, snr,
";".join(trame)])
fh.flush()
barres = "#" * max(0, (int(float(rssi)) + 130) // 2)
print(f"{horloge} {rssi} dBm {barres} {';'.join(trame)}")
if __name__ == "__main__":
try:
principal()
except KeyboardInterrupt:
print("\nJournalise a l'arret.")