domingo, 21 de abril de 2019

"Hello World" telegráfico en Raspberry Pi Zero

Hace algo menos de 40 años atrás escribía en la entonces recientemente salida revista K64 mi primer artículo, se trataba de emitir código Morse con una revolucionaria para la época computadora Sinclair ZX81.  El artículo causó bastante furor por entonces y fue seguido por muchos mas en una colaboración que duró varios años y produjo un par de docenas de artículos. Hace mucho que la revista dejó de salir pero yo sigo usando los dibujos pues me gustan mucho y me transportan brevemente a una época muy linda. Hay un proyecto que trata de compilar imágenes de las ediciones, así que quien tenga números en papel quizás quiera contribuir.  El dibujo que hicieron para ese artículo lo usé muchas veces en éste blog, pues aquel no fue ni el primer ni el último manipulador electrónico que diseñé, ni para la ZX81 (o TS1000 como se la conocía por aquí) ni para muchas otras plataformas que le siguieron. Esta introducción es para tratar de explicar porque tantas veces he realizado éste tipo de proyectos. En realidad cuando uno incursiona en una nueva plataforma enfrenta una curva de aprendizaje, que es bastante áspera al comienzo pues se tiene que aprender muchas cosas de golpe. 
Es una estrategia muy útil para enfrentarla hacer un "Hello World", que no es mas que un pequeño programita que hace solo eso, genera el texto "Hello World" y lo presenta por cualquiera sea el dispositivo disponible. Parece una soberana tontería, pero no lo es. Para poder lograr que un programa tan simple funcione hay que tener muy configurado el ambiente, haber entendido todas las opciones necesarias, encontrar que editor hay disponible y como usarlo, enfrentarse con problemas en casa uno de esos pasos anteriores y encontrar como solucionarlos. No es nada trivial. Y es una manera de hacer "algo" sin que la complejidad de ese "algo" sea fuente de ningún problema; es como salir con trapito rojo a "torear" a los problemas para que aparezcan ya así eliminarlos de a uno. Pero en realidad el Hello World no ayuda a mas que saber que la configuración anda, pero no permite explorar mucho del resto del ambiente, así que en mi caso usualmente hago un segundo proyecto corto, pero mas complejo, con el cual terminar de familiarizarme. Es un proyecto que conozco mucho, que no me es difícil, pero para el cual tengo que poner en juego algunas técnicas de programación y entender como funciona la entrada-salida de la plataforma "nueva", ese proyecto es y ha sido siempre un manipulador de telegrafía. Explico todo ésto para intentar compartir cuando, inevitablemente, me comenten que se puede hacer lo mismo con un integrado LM555 que no, no es lo mismo.
En este caso le tocó a la Raspberry Pi. En realidad no es el primer proyecto que hago con ésta placa, hace ya algunos años que hago cosas con ellas, pero últimamente casi todos mis proyectos están basados en ese plataforma. Contribuye que tengo que practicar CW "a mano" (habilidad que en la que me he endurecido bastante luego de usar un teclado por mas de una década) y que cuando fui a buscar mi keyer basado en un PIC 12F675 encontré que no funcionaba (vaya uno a saber porque). Las alternativas eran buscar porque no andaba y repararlo, o hacer uno nuevo. Por supuesto que es mas divertido hacer uno nuevo, y eso hice, porque de eso se trata un hobby, de divertirse.
Como he comentado varias veces he construido un cluster de placas Rasbpberry Pi que las uso para experimentación de distinto tipo, balizas multimodo, monitor de WSPR, el nodo SatNOGS y un par que están libres para otros usos y desarrollos. Tengo también dos placas Raspberry Pi Zero, una tipo W (con Wifi) y la otra sin el. La que tiene Wifi (lambda crux) la transformé en un beacon WSPR/FT8 explicado en una entrada anterior. La otra placa (delta crux) me resulta un poco difícil encontrarle un uso permanente, es pequeña y no es fácil acomodarla en la "torre" donde está el cluster, además como adquiere Wifi mediante un "dongle" externo no siempre lo hace bien, y en ocasiones para encontrar donde está en la red tengo que "buscarla" con el utilitario nmap o incluso conectarla a un monitor/teclado cuando se niega a conectarse, un fastidio. Así que nada mejor para ella que un uso que no requiera red salvo ocasionalmente. Un manipulador (keyer) cumple esa condición, es necesario conectarse a la red para construirlo y quizás para configurarlo, o mejorarle el nivel del software o acaso hacer algún mantenimiento, pero en el uso diario es completamente independiente ("standalone" lo que en inglés significa "que se para solo"). Pero en vez de escribirlo desde cero simplemente exploré en GitHub un poco que había al respecto y me encontré con el paquete denominado iambic-keyer de Rick (N1GP), que cumplía con casi la totalidad de lo que necesitaba. El "casi" lo solucioné haciendo "fork" del paquete en mi propio espacio GitHub y haciendo una nueva versión donde hice los agregados que necesitaba (http://www.github.com/lu7did/iambic-keyer). El programa tiene una arquitectura simple, la lógica del keyer está en el módulo iambic.c (https://github.com/lu7did/iambic-keyer/blob/master/iambic.c) (el que modifiqué) mientras que la generación de tonos está en keyed_tone.c (el que no modifiqué); según el help el programa originalmente estaba implementado en una FPGA en Verilog por Phil (VK6PH).
Esas modificaciones fueron muy simples, cambiar un poco los mensajes, acomodar los puertos de salida a lo que necesitaba y agregar una función para poder cambiar la velocidad sin tener que re-lanzar el programa mediante la lectura del estado del puerto GPIO 19. Esta última trabaja de manera que si detecta la paleta en "punto" con el pulsador de velocidad a masa va disminuyendo la velocidad hasta 5 ppm y en caso de ser "raya" la incrementa progresivamente hasta 50 ppm. El circuito es realmente mínimo, todas las salidas se configuran para tener su resistencia interna de pull-up activadas por lo que solo hay que conectarlas a masa para producir un "0" mientras que la lectura en reposo dá un "1" (recordar que estos pines manejan 3.3V y muy baja capacidad de corriente). El manipulador va entre GPIO13 y GPIO15, la salida para "manipular" es GPIO12, se usa un transistor PNP para manipular poniendo a masa la base. Si se es temeroso sobre a que se conecta siempre se puede utilizar un optoaislador en lugar de un transistor. La electrónica es suficientemente simple, pero nunca está de mas utilizar un diagrama para dejar las cosas claras.
El armado he vuelto a utilizar las latitas de pastillas "Altoids" que tan prácticas son para circuitos simples, primero se ponen todos los conectores directamente en montaje "auto soportado" (araña) y luego con unos pilares pequeños de metal la placa misma; hay que cavar agujeros para los dos conectores USB (alimentación y expansión).
El programa tiene la opción de generar su propio "zumbador" utilizando un puerto GPIO de salida o de hacerlo mediante una placa de sonido. La Raspberry Pi Zero no tiene salida de audio (como si lo tienen sus primas mayores, los modelos "normales"). No encontré incómodo usar un pequeño hub USB para conectar al mismo tiempo un "dongle" Wifi y una placa de sonido USB. Para manejar el sonido se usa un paquete llamado jack el cual debe ser instalado. Para su construcción el programa utiliza la librería de manejo del GPIO denominada wiringPi, ¡muy conveniente!
En ejecución hay que realizar una serie de pasos para que todo ejecute correctamente, por lo que en esos casos es siempre útil hacer un pequeño script bash que impida los errores, al efecto hice el script keyer que es parte del paquete y que se opera con la misma interfaz que un servicio (sudo ./keyer start o sudo ./keyer stop), el programa debe ser ejecutado con sudo por el tipo de operaciones que hace para manipular el hardware. Para que el funcionamiento sea completamente "standalone" es necesario arrancar el programa cada vez que se da boot a la placa. Tuve algunas dificultades para que funcionara bien como servicio o arrancándolo como parte de la secuencia init.d del Linux por lo que usé el método de fuerza bruta, puse en el cron la sentencia de llamada a continuación de la macro "@reboot" de forma que se ejecute al boot de la placa.
Anda lindo y por cierto que ya estoy practicando mis muy oxidadas habilidades de enviar CW manualmente, cosa que el Rafa Panoni (LU3HAZ) me enseñó muy bien, pero que la comodidad del teclado hace perder, de manera que vuelvan a hacer juego con las muy afiladas de tomar CW a oido. Y si todavía alguien propone un manipulador con un 555 o integrados CMOS le concederé inmediatamente que es mas barato, le discutiré un poco que sea mas fácil y definitivamente cerraré la discusión con la invitación  a que use el manipulador para escuchar música.



domingo, 14 de abril de 2019

Baliza WSPR de 28 MHz usando filtro pasabajos de QRPLabs

Hace algún tiempo compré por correo un kit de filtro pasabajos para 10 metros (28 MHz) en QRPLabs. La idea entonces era hacer una baliza WSPR basado en un Arduino Nano, para lo que éste kit es un "sombrero" (hat).
Como era de esperarse cuando llegó, y luego de una muy desagradable cola de casi 7 horas (¡7 horas!) en el centro de distribución internacional del Correo Argentino en la calle Estonia (CABA) me hice de el, lo guardé prolijamente en la caja de "proyectos futuros" y allí durmió una siesta de varios meses, como  muchos otros proyectos donde las realidades del tiempo disponible se juntan con las buenas (y a veces no tan buenas) ideas para proyectos de construcción.
En el medio empecé, y desde hace varios meses estoy trabajando, con desarrollos de bajas señales (WSPR, FT8, etc.) sobre la plataforma Raspberry Pi mayormente usando el modelo 3B, algunas entradas recientes dan cuenta de esos proyectos y otras futuras continuarán haciéndolo; ese proyecto fue una aspiradora de tiempo libre y ningún otro proyecto avanzó mientras me dediqué a el.
En general las balizas, que gracias a la flexibilidad de una plataforma Linux, pueden implementarse fácilmente en varios "idiomas" (WSPR, FT8, CW, RTTY, PSK31 e incluso SSTV) está funcionando en forma estable en WSPR y FT8 desde hace varios meses. Simultáneamente con ese desarrollo integré a mi "cluster" de máquinas una Raspberry Pi Zero y una Raspberry Pi Zero W para evaluarlas y entenderlas un poco mejor, la principal diferencia entre ellas es que la primera no tiene WiFi ni Bluetooth incorporado mientras que la segunda si. 
La conclusión que saqué de ambas placas es que si bien la Raspberry Pi Zero es mas económica en la práctica termina saliendo mas cara al tener que comprarle un "dongle" WiFi o un adaptador Ethernet porque no se puede usar "headless" (sin monitor ni teclado ni mouse); carece de sentido práctico, al menos para mi, tener que usar un teclado, un monitor y un hub USB para poder operarla en forma permanente. La Raspberry Pi Zero W (la W es por "wireless"), en cambio, una vez configurada se puede "tirar" en cualquier lado donde tenga señal WiFi y operarla "headless" desde otra máquina. Ambas máquinas son bastante limitadas en cuanto a potencia de procesamiento, operan con una CPU de un (1) núcleo, comparado con la Raspberry Pi Modelo 3 que opera con cuatro (4) núcleos. Esta última es bastante potente por cierto, y se puede usar hasta incluso como una "desktop" de uso (muy) liviano, cosa que claramente la versión Zero no le dá. 
En las mediciones que deja reflejado en el log puedo ver que la baliza ocupa aproximadamente un 15% de CPU promedio en una Raspberry Pi Modelo 3 en el pico de procesamiento (cuando emite) o sea que en una Rapberry Pi Zero debería ocupar 4 veces mas (la cuenta no es tan lineal, solo es una aproximación), o sea un 60% de CPU en el peor caso; lo que es razonable para una placa dedicada que no hace otra cosa. No es razonable emitir constantemente, por mas que no sea una placa de "monitor" (que reciba y reporte lo que escuche, además de emitir) no es conveniente saturar la frecuencia y para eso la cadencia de emisión es cada unos 10 minutos aproximadamente, en realidad transmite cada 5 ciclos WSPR (2 minutos cada uno) pero a continuación de la baliza WSPR emite durante dos minutos 4 frames FT8 (15 segundos de emisión y 15 segundos de escucha, alternadamente durante 2 minutos), pasados los cuales la baliza esté en reposo durante 6 minutos.
La baliza es muy sencilla de construir, una Raspberry Pi Zero W y un filtro pasabajos para 10 metros, ambos muy pequeños, lo suficiente para volver a utilizar la cajita metálica de pastillas "Altoids" como gabinete. Buena oportunidad para usar el kit de QRPLabs para lo que en definitiva era su uso original, solo que con otra configuración de proyecto. El kit es muy sencillo pero muy bien armado (la placa sobre todo) y los materiales de muy buena calidad; creo que vale la pena comprarlo por mas que sea muy sencillo de armar con piezas sueltas. El manual tiene los componentes para todas las bandas de HF, lo que es interesante para tener registrado porque es un circuito útil para casi cualquier proyecto que implique emitir RF.
El software para la baliza es el mismo que vengo usando en 14 MHz, solo que mínimamente configurado para la nueva frecuencia. A diferencia de la baliza de 14 MHz esta sale nativa desde el puerto GPIO a la antena con la mínima aislación de un capacitor en serie para evitar cortocircuitos desagradables y el filtro pasa bajos; eso es unos 10 mW de potencia de RF, que ya he probado en 20 metros que es mas que suficiente para alcances regionales (hasta 5000 Km) y ocasionalmente DX a mas distancias (10000 a 12000 Km); creo que 10 metros mostrará aperturas de esporádica E (continuamente reportadas en WSPR en Europa) y ocasionalmente en el punto mas bajo del ciclo solar en propagación ionosférica por capa F1/F2.
Lindo proyecto para una tarde de otoño, seguramente tendré que dedicarle horas para ponerla en un régimen estable, y posiblemente le encuentre un hogar fuera de mi shack una vez que esté estable para evitar interacciones con la otra baliza.





sábado, 6 de abril de 2019

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

Para terminar de comentar sobre los diferentes modos que implementé en la baliza, aunque no todos ellos quedaron programados en forma permanente por razones prácticas fuera de la experimentación en si describo ahora la implementación de RTTY.
El viejo modo de "radioteletipo" pese que ha sido objetivamente superado técnicamente sigue estando vigente, hay bastante actividad con quienes lo practican, en especial en concursos del modo.
En realidad se trata de un modo de modulación en frecuencia, toda vez que los dos simbolos binarios con que se lo representa se les asigna dos frecuencias. La separación entre las dos frecuencias se denomina "desplazamiento" (shift) y en emisiones de radioaficionado es, por convención, de 170 Hz.
Las frecuencias de los tonos serán entonces 1350 Hz y 1520 Hz. Al equipo de SSB convencional se lo puede alimentar tanto como una señal de audio (AFSK) como mediante un desplazamiento (FSK). En un ambiente virtualizado es mas conveniente el primer método. El RTTY utiliza 5 bits para emitir cada caracter utilizando una codificación denominada BAUDOT, como 5 bits alcanzan para codificar solo 32 caracteres y eso es insuficiente hasta para un código ASCII muy restringido se soluciona enviando un caracter de "escape" denominado LETRAS o FIGURAS con lo cual se indica que los caracters que siguen pertenecen a dos conjuntos diferentes, cada uno de 32 caracteres. Aun así no es tan rico como el conjunto ASCII pero sirve para transmitir casi cualquier texto, no sirve para transmitir textos complicados como pueden ser programas de computación pues le faltan algunos caracteres; hace muchisimo tiempo, con las primeras computadoras y cuando las impresoras eran muy caras, se usaban máquinas de teletipo como impresoras, aunque no servían para imprimir programas normalmente por esa misma razón.
Buscando en Internet encontré un programa denominado rpi_rtty creado hace algún tiempo por Mike Adams (G3ZLO), el que permitía dado un texto generar los tonos con el que emitirlo en RTTY para a continuación grabarlo en un formato especial del programa rpitx denominado "frecuencia-tiempo" (.ft). En ese archivo se especifican pares de "frecuencia" junto al tiempo que el tono dura. Un archivo en ese formato puede ser procesado por el "viejo" (V1) programa rpitx usando la opción "-m RF". Para mi sorpresa esa función no está mas soportada en el "nuevo" (V2) programa rpitx, el cual existe y acepta la opción pero no funciona como tal. Chequeado con Evariste (F5OEO) me confirmó que efectivamente la función no estaba implementada aún, parece que todos tenemos el mismo problemita de tiempo con nuestros proyectos :-) .
Sin embargo el programa pisstv del paquete rpitx, que sirve para emitir en SSTV y veremos a continuación, internamente genera una estructura de datos similar a la que se utiliza para el formato .ft.
Asi que fue solo cuestión de poner manos a la obra, hice un "fork" del programa pisstv, una mezcla (merge) entre el programa rpi_rtty en lo que hace a la manipulación de textos y generación de tonos junto con el programa pisstv para emitirlos, fue necesario un poco de código propio para pegotear ambos programas para que funcionaran juntos. También para adecuar el hecho que rpi_rtty es un programa escrito en C mientras que pisstv está escrito en C++. Existe la creencia que ambos lenguajes son iguales, o al menos compatibles entre si, pero no siempre es el caso. Y este no fue el caso ciertamente. Para que funcionara tuve que cambiar la forma en que internamente el programa manipulaba los punteros a las áreas de memoria, trabajo simple pero tedioso.
Como sea que fuera completé y puse en github el programa pirtty que es justo para balizas, recibe un texto como argumento y lo emite en RTTY en la frecuencia que se le indique.
Para instalar pirtty se ejecutan los siguientes comandos:

cd ~
git clone http://www.github.com/lu7did/pirtty
cd ./pirtty/src
make
sudo make install

Para ejecutarlo se lo llama con

sudo pirtty  14097000 "   RYRY CQ LU7DID/B LU7DID/B GF05TE 20 K  " 170 45.5

Esto hará que en la frecuencia de 14.097 MHz se emita el mensaje con RTTY shift de 170 Hz y 
velocidad 45.5 bauds.
Aprovechando la mención  también se puede comentar como transmitir SSTV en forma automática.
El estandar que usa pisstv (rpitx) para transmitir SSTV es el denominado MARTIN1, que tarda algo menos de 2 minutos para transmitir una imagen a color.  SSTV emite una señal de variación analógica de frecuencia para transmitir la distinta información de luminancia (intensidad) y crominancia (color), utilizando frecuencias extremas del segmento de audio para representar los sincronismos horizontal y vertical.
El programa toma una imagen en formato "RGB" (formato crudo) y lo emite en la frecuencia indicada; como el formato RGB no es la forma mas común de almacenar archivos se debe primero convertir la imagen desde otro formato, por ejemplo .JPG, para su emisión. El script que hace eso viene en el paquete rpitx y se denomina testsstv.sh su contenido es:

#!/bin/sh
convert -depth 8 BBC.jpg picture.rgb
sudo ./pisstv picture.rgb "$1"

Aqui el archivo BBC.jpg es el emitido y lo hace en la frecuencia que indica el argumento con el que es llamado el script, por ejemplo:

/home/pi/rpitx/testsstv 14235000

El funcionamiento es excelente, pero probablemente SSTV no es un modo práctico para una baliza de solo 100 mW excepto quizás en un entorno local o quizás como parte de un experimento en bandas de VHF o UHF; es un modo relativamente sensible a la relación señal al ruido deteriorada. Adicionalmente una figura tarda casi dos minutos en emitirse, y se difícil encontrar una secuencia de emisión que no "empuje" la relación transmisión-recepción de la estación monitora y la proporción entre los distintos modos fuera de valores razonables. Nada impide no tener en cuenta esta facilidad para algún proyecto futuro (¿globo?¿satélite?¿baliza dedicada?). ¡Quien sabe!