viernes, 22 de marzo de 2019

Transceptor de señales débiles, bit a bit (Parte 6)

Es relativamente trivial configurar los scripts para que arranquen en cualquier modo, basta alterar los parámetros para que la cadena receptora funcione en 14095.6 MHz (WSPR) o 14074 MHz, o cualquier otra frecuencia y banda por caso. Mi estación monitora opera en 20 metros porque el filtro y amplificador de salida está en esa banda, pero el principio de funcionamiento es el mismo no importa cual sea la banda que se utilice. Pero por mas que apile modos sigo teniendo dos placas Raspberry Pi (una para receptor y otra para transmisor) y una antena; es decir que de alguna forma hay que coordinar todo.
Mi primer intento fue, casi obvio, hacer andar todo en una placa. Aparte del beneficio de usar solo una placa la coordinación de actividades es un poco mas simple, pero muy poco en realidad. Sin embargo la cadena receptora utiliza el clock de la máquina para establecer las ventanas (rigurosas) de los modos de baja señal, y está sincronizado mediante el protocolo NTP para ser preciso. Sin embargo, el procesamiento de la cadena SDR toma algún tiempo, dos segundo y medio aproximadamente. Eso basta para que la performance de recepción se degrade enormemente pues es muy crítico que los algoritmos funcionen sincronizado en tiempo, para solucionar eso se "corre" el reloj de forma que atrase 2.5 segundos a pesar de estar sincronizados por NTP (es decir, sincroniza la hora exacta y le resta 2.5 segundos) que es el tiempo que retarda la cadena de procesamiento SDR, con lo cual el receptor está dentro de medio segundo de la ventana de tiempo sincronizada y la recepción mejora enormemente. Ese mismo atraso es, sin embargo, perjudicial para la cadena transmisora, pues su retardo es casi despreciable y por lo tanto emite fuera de ventana y perjudica sus chances de ser decodificado correctamente por otras estaciones. Busqué soluciones a ese problema y encontré algunas, pero ninguna fue satisfactoria. La solución fue entonces correr el script de baliza (emisor) en una placa y el de monitor (receptor) en la otra. Santo remedio. Pero .. si era difícil coordinar ambos scripts cuando estaban en la misma placa ... ¿como hacerlo ahora que están en dos placas diferentes?. Mis primeros intentos fueron justamente buscar formas de sincronizarlos, y probé con esquemas un tanto rebuscados utilizando sea un socket TCP (ncat) sea  puertos series virtuales (pipe) u otros esquemas tanto o mas atravesados. Nuevamente, funcionaron, pero eran solo marginalmente satisfactorios. La simplicidad terminó dominando la solución (criterio de Occam se lo suele llamar). La forma mas simple de resolver una conmutación compleja es ..... no hacerla. En efecto, por sofisticada que fuera la solución mientras la baliza transmite, por mas que lo haga con solo 100 mW (o incluso con 10 mW) el receptor queda "sordo". Y de todas maneras solo asigno una antena al conjunto, así que por mas que hiciera una conmutación rara al final tengo que conmutar físicamente la antena a uno u otro. Entonces la solución mas simple es colocar un relay que activado por el script de emisión de la baliza se conmute la antena cuando va a transmitir y la libere cuando deja de hacerlo. En emisión el monitor no puede hacer nada relevante, o a lo sumo decodificar la señal que está emitiendo la baliza, pero tampoco corre riesgos al no tener antena conectada de resultar dañado por su potencia u otro efecto indeseable.
El circuito de conmutación es extremadamente simple, básicamente un relay de +5V conmutado por un transistor NPN (siempre uso 2N3904, pero es .. cualquiera) alimentado por la linea GPIO27 de la placa emisora; la señal de control tiene +3.3V y difiere de la del relay que es +5V pero el circuito es seguro, no obstante podría hacerse con un opto-aislador si se prefiriera mas aislación. El relay es uno común y silvestre, no uno coaxial que son mucho mas caros, Marcelo Gruber (LU1IBL, en grupo Facebook TECNICA-LU) había hecho la medición demostrando que por debajo de 30 MHz el deterioro de performance de un relay común es casi despreciable (y la diferencia de costo no lo es).
Desde el punto de vista software es aún mas simple, al comenzar hay que configurar el puerto GPIO27 como de salida con:

gpio mode 27 out  2>&1 | tee -a $DPATH$LOG

Y luego, cada vez que se quiere activar el relay (antes de emitir):

gpio -g write 27 1 2>&1 | tee -a $DPATH$LOG

Y al terminar

gpio -g write 27 0 2>&1 | tee -a $DPATH$LOG

El funcionamiento general se explicó previamente, pero los scripts de detalle son simples. En transmisión el script de la baliza es lanzado cada minuto por crontab, es un script re-entrante y re-usable que termina si encuentra que ya está corriendo (no sin registrar la telemetría primero); pero cuando detecta que no está corriendo previamente se queda ejecutando el ciclo del beacon, que lo voy variando pero es que emita WSPR cada 10 minutos, seguido de FT8 durante un minuto (dos llamadas) y seguido de CW. En breve estará funcionando probablemente también en PSK31 y/o RTTY (y SSTV y ...), obviamente que cuanto mas modos le ponga mas voy a tener que espaciar las emisiones para dar lugar a que ocurra la parte del monitoreo, pues por mas que volemos alto la antena seguiría siendo una (y si le asignara otra antena quedaría sordo el monitor mientras emite la baliza).
El receptor es otra historia, básicamente se trata de tener corriendo en forma permanente al programa WSJT-X con la cadena SDR que oficia de receptor explicada en entradas anteriores; el programa no prende y apaga, solo tiene o no tiene antena. En este momento lo tengo recibiendo (monitoreando) FT8 entre las 1500Z y las 2300Z mientras que el resto del tiempo monitorea WSPR, los horarios son bastante volátiles aún pues estoy tratando de ajustar que las ventanas maximicen de alguna forma las estaciones monitoreadas en función de la propagación y la actividad, es probable que en ocasiones tenga un modo funcionando en forma permanente por sobre el otro; mucha experimientación sobre el tema sigue teniendo lugar.
Para ejecutarlo llamo al script launchWSJTX que es bien simple y de acuerdo al horario lanza la cadena receptora configurada para WSPR o FT8, el script es lanzado mediante su inclusión en el archivo 

/home/pi/.config/lxsession/LXDE-pi/autostart

agregando una linea como

@/home/pi/whisper/launchWSJTX

El contenido de ese archivo es ejecutado cada vez que arranca el GUI, que básicamente es cada vez que se da reboot. Debido a ello para cambiar de modo solo hay que dar reboot en el horario apropiado, cosa que es facil de implementar mediante el crontab.
El reporte del beacon en WSPR se obtiene en el sitio wsprnet.orghttp://www.wsprnet.org mientras que en FT8 en www.pskreporter.info. Al momento de escribir esta entrada el sitio wsprnet reporta tanto al beacon como lo que el monitoreo recibe, sin embargo PSKReporter solo muestra estaciones que me escuchan pero no logro aún que mi propio monitoreo se vea reflejado. También estoy trabajando en forma muy experimental en reportar en el Reverse Beacon Network la actividad FT8, esta plataforma que realmente revolucionó los modos digitales está adoptando en forma muy cauta el reporte de FT8, sus responsables han visto con asombro que el número de spots de ese modo rápidamente transforman el número total de todos los otros modos en una fracción del total. Al momento FT8 no es reportada en el sitio Web sino solamente mediante el acceso telnet. Todos esos esfuerzos tienen todavía tela para cortar y resumirá conclusiones mas adelante (básicamente, cuando las tenga). Para implementar en la placa del beacon las distintas emisiones utilizo WsprryPi (WSPR),

sudo $WSPRPATH$WSPR $TXOPTS $CALLSIGN $GRID $POWER $BAND 2>&1 | tee -a $DPATH$LOG

ft8pi que es parte del paquete ritx que emite mensajes en FT8 (es un programa con muchisima tela para cortar experimentando), donde básicamente se le coloca un texto a transmitir y el programa define si lo puede canalizar mediante un mensaje standard de FT8 o debe enviar un mensaje especial, el formato para invocarlo es:

sudo $RPITXPATH$FT8 -f "$FFT8" -m "CQ $CALLSIGN $GRID" -o "$OFFSET" -s "$SLOT" 2>&1 | tee -a $DPATH$LOG

PiCW para CW (provisoriamente en 14.099 MHz) aunque con una señal tan miserable es improbable que sea escuchado excepto en forma muy local, no tengo reportes al menos.

sudo $CWPATH$CW --freq $FCW --wpm 20 "CQ DE $CALLSIGN/B $GRID $POWER $TLM K" 2>&1 | tee -a $DPATH$LOG

En entradas posteriores comentaré como mediante la manipulación de la señal utilizando técnicas de SDR mediante el utilitario csdr es posible generar básicamente cualquier modulación, pero en particular aplicado a PSK31, RTTY y SSTV.

Un experimento que estoy haciendo es agregar cuando es posible  un mensaje de telemetría codificado como se lo haría en WSPR si fuera un globo, es mas que nada para jugar con los algoritmos para generar esa codificación. La misma la hago con un programa en python llamado wsprtlm.py. Este frame de telemetría permite emitir la temperatura, el voltaje y la posición mas exacta (últimos dos caracteres del grid locator). También emite la altura, que en un globo es relevante pero en mi caso no, por lo que quizás se pueda utilizar eso para codificar otra cosa, como por ejemplo el status del procesador, el porcentaje de CPU o de espacio en disco (o todas esas cosas juntas con la codificación apropiada).

Si bien una cosa es emitir un mensaje corto con una baliza y otra operar un QSO arbitrario en realidad es bastante facil pasar de los scripts que hagan una cosa a los que hagan otra; o aplicando la estrategia que utiliza el programa qtcsdr ir invocando los programas que necesitamos para generar la señal que queremos en un momento dado.

No hay comentarios:

Publicar un comentario