lora_logger.py

Arduino MKR WAN 1300 · Archivo : lora_logger.py · Lenguaje : Python · Uso : Archiver et tracer les trames LoRa reçues sur PC

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.")

← Volver a la ficha