Transmisor de PSK31 con Raspberry PI

English version available here

Antecedentes. La teoría.

En la anterior entrada explicaba la modulación y codificación de PSK31. En este artículo muestro un prototipo operativo de transmisor de PSK31 basado en una Rasbperry Pi (en lo sucesivo RPi). Es un microordenador de bajo tamaño, peso, consumo y precio que puede ejecutar una distribución de Linux similar a Debian. Muchos radioaficionados la emplean, ya sea a modo de ordenador personal, o bien para usos automatizados, remotos o autónomos. En ese tipo de aplicaciones es donde, a mi juicio, la RPi realmente destaca y tiene grandes ventajas.

Tiene salida de audio y vídeo analógicos y una tira de pines con señales de propósito general (GPIO), puerto serie, I2C, SPI y, lo que es más interesante para nosotros, un sintetizador PLL incorporado en la propia CPU y capaz de generar cualquier frecuencia hasta 250 MHz. Su salida es una onda cuadrada CMOS de 3,3V.

Puertos de entrada y salida de la RPi (modelo B)

Existen programas que modulan la frecuencia y la amplitud de ese PLL para generar FM, SSB, WSPR o incluso modos de televisión digital:

[https://github.com/F5OEO/rpitx] Conjunto de programas para generar casi cualquier modulación.

[https://github.com/fotografAle/NBFM] Sencillo programa para modulación FM estrecha.

[https://www.tapr.org/kits_20M-wspr-pi.html] Baliza de WSPR.

[https://github.com/F5OEO/rpidatv] Televisión digital.

Recapitulando, queremos multiplicar una portadora de RF por una moduladora más lenta con símbolos de 32 ms que pueden ser ‘1’ constante, ‘-1’ constante o transición en forma de semiciclo de coseno de 15,625 Hz:

La salida de audio de la RPi no puede generar la moduladora de banda base porque, como muestra el esquema electrónico, hay un condensador en serie, lo cual interrumpe la DC y frecuencias bajas:

Esquema de la salida de audio
Esquema de la salida de audio

En principio sería posible puentear los condensadores C34 y C48 en la placa y sacar por la salida de audio la señal moduladora. No he probado este camino. Me facilitaron un software que puede generar la señal utilizando pines GPIO a modo de conversor digital – analógico (en lo sucesivo DAC) de tipo sigma delta: se trata de conmutar rápidamente su valor entre ‘0’ y ‘1’ pero con un valor medio que varía con el tiempo. Así, un filtro paso bajo elimina la componente de alta frecuencia y reconstruye nuestra moduladora lenta. Un conversor sigma delta es un tipo de DAC de  1 bit y su uso es común en aparatos de audio. Su funcionamiento está muy bien explicado en esta web.

Conversor sigma delta. Gráfica simulada ilustrativa.

El hardware

La señal moduladora se genera de forma diferencial en los pines 11 y 12 del conector, que se corresponden con las señales GPIO 17 y 18 de la CPU. Estos pines tienen siempre señales complementarias o negadas entre sí. Cuando uno vale ‘1’ el otro vale ‘0’ y conmutan a unos 35 kHz:

Pulsos del DAC sigma-delta. Medición real sobre pines 11 y 12.

A continuación va el siguiente circuito. Los pulsos del DAC se filtran mediante una red RC con una constante de tiempo de 4,7 ms. Opté por acoplar la moduladora a través de un amplificador diferencial AD8132. Es del tipo FDA o fully differential amplifier, es decir, tiene dos salidas balanceadas.

Modulador de PSK31

 

En bornas del condensador de 470 nF la señal tiene esta forma:

Moduladora ya filtrada

La portadora se puede generar con alguno de los programas existentes indicados más arriba o bien hacer otro que tome la parte de su código que genera el tono, sin variar su frecuencia. Un mezclador muy extendido es el SA602, que incorpora los bloques que necesitamos y además se puede alimentar a partir de 4,5 V, compatible por tanto con los 5 V presentes en la tira de pines de la RPi. Si vemos el datasheet del SA602, parece que obligan a acoplar la señal en AC con el fin de no alterar el punto de polarización:

The RF inputs (Pins 1 and 2) are biased internally. They are symmetrical. The equivalent AC input impedance is approximately 1.5k || 3pF through 50MHz. Pins 1 and 2 can be used interchangeably, but they should not be DC biased externally.

Pero si leemos la documentación del amplificador diferencial AD8132, es posible acoplarlos en DC sin alterar la polarización si ofrece una alta impedancia para el modo común:

La moduladora se genera de forma diferencial y así se filtra y se acopla. En los pines 1 y 2 del SA602 se introducen señales balanceadas alrededor de un nivel DC de 1,9V en modo común. Sería mucho más difícil hacer esto en modo sencillo o single ended que en diferencial por la precisión requerida en la polarización DC. El SA602 tiene bastante ganancia por lo que se atenúa la señal antes y basta con unos 200 mVpp por pin (400 mVpp diferencial).

Señal medida en los pines 1 y 2 del SA602

El modulador SA602 entrega unos 500 mVpp en cada uno de los terminales 4 y 5, con 1.500 ohm de impedancia de salida. La ganancia entre «RF» y «OUT» depende de la amplitud del oscilador. A continuación puse una etapa de seguidor de emisor y un sencillo amplificador en emisor común. El conjunto es capaz de entregar unos 20 y 50 mW en 14 y 7 MHz respectivamente. Este circuito tiene margen de mejora.

Circuito amplificador

En los esquemas se han obviado los condensadores de desacoplo pero todos los puntos de alimentación a 5V deben llevar un condensador cerámico de 100 nF a masa.

Monté el circuito como muestra la foto, en una plaquita que se inserta en la RPi mediante una tira de pines hembra. Se alimenta a 5V proporcionados por la propia RPi y consume unos 130mA, lo mismo que un dongle WiFi por usb. El oscilador sale del pin 7 y la moduladora diferencial de los pines 11 y 12 del conector, esto corresponde a 4, 17 y 18 según la numeración GPIO de la CPU.

Prototipo de transmisor PSK31 para Raspberry Pi

El software

Descargar los archivos Makefile.txt, varicode.c y psk31.c y copiarlos a una carpeta nueva de la RPi. Renombrar «Makefile.txt» por «Makefile» sin extensión.

Makefile.txt md5sum: 04636b0d03a7f4b4ec675ba25c832f2c

varicode.c md5sum: 923d027791bca3dbcd4bf6d5cee10d94

psk31.c  md5sum: 1d94cf3c893014de1b0b9f6255394b3c

Ejecutar «make». Tarda unos 8 segundos en compilar para generar dos ejecutables: «psk31» y «varicode».

El modo de empleo es el siguiente. Debemos ejecutar «psk31» con permisos de root y con los parámetros deseados para lanzar el servicio, que permanecerá en ejecución. Podemos obtener ayuda de este modo:

pi@raspberrypi ~/psk31 $ ./psk31 --help
Options:
 --amplitude=<n> Signal amplitude (0 .. 1]
 --clock-div=<n> Fractional divisor for carrier [4096 .. 16773120]
 Note: frequency = 500 MHz / (clock-div / 4096)
 --frequency=<f> Carrier frequency, in MHz [0.125 .. 500]
 Note: this is overridden by clock-div
 --help Show this help
 --mash=<n> Set number of MASH stages [0 .. 3]
 --pcm Use PCM clock instead of PWM clock for signal generation
 --rc=<f> Set signal filter RC value (s)
 --timeout=<n> Number of zeros before switching off. 0 for infinite.

Normalmente la amplitud será la máxima. El parámetro «mash» permite valores fraccionales del pll y en caso de poner ‘0’ no es posible seleccionar bien la frecuencia. El valor del filtro RC será el del circuito que hayamos construido. Tras ejecutar el programa con estos parámetros, empezamos a emitir una portadora sin modular:

sudo ./psk31 --mash=1 --rc=0.0047 --timeout=20 --frequency=7.042

Para transmitir un texto no hacen falta permisos de root. Lo haremos volcando el contenido en el búfer de transmisión a través del dispositivo /dev/psk31.data por ejemplo con:

echo "CQ CQ" > /dev/psk31.data

cat fichero.txt > /dev/psk31.data

o bien con

cat > /dev/psk31.data

y de forma interactiva podemos escribir en la consola y, al pulsar <Entrar>, esa línea se envía al búfer.

Para conocer el estado del servicio podemos ejecutar:

nc -U /dev/psk31.stat

Que nos devuelve:

amplitude 0.900000
rc 0.004700
clock_div 290826
clock_mash 1
clock_freq 7.042011
timeout 20
pending_char 53

El servicio se para con:

sudo killall psk31

El valor real del divisor de reloj no es el número mostrado en «clock_div». El pll parte de una referencia de 500 MHz y aplica una división con parte entera y parte fraccional de 12 bits. Es decir, divide en fracciones 2^12 o 4096 más pequeñas que la unidad. En este caso la cifra de 290826 significa que divide 500 entre 71 + 10/4096. Hemos ejecutado el programa para que transmita en 7.042 y lo obtiene como 500 · 4096 / 290826 = 7.042.

Esto también significa que la resolución (los pasos de frecuencia que puede dar) no son fijos sino que dependen de la frecuencia de partida. ‘N’ es un número entero entre 2^13 y 2^23 o sea 8.192 y 8.388.608 que mediante esta ecuación:

F = 500e6/(N/4096) [Hz]

nos da frecuencias entre 244 kHz y 250 MHz. El resto de dividir el divisor N entre 4096 (2¹²) es la parte fraccional.

La resolución sería:

f1-f2 = 500e6/(N/4096) – 500e6/((N+1)/4096))

Haciendo algunos números queda:

f1 – f2 = f1² / (500e6*4096) [Hz]

Lo que significa que la resolución es proporcional al cuadrado de la frecuencia.

Por ejemplo, en 145 MHz tendríamos 10 kHz de resolución.
En 50 MHz tendríamos 1,2 kHz.
En 28 MHz tendríamos 382 Hz.
En 7 MHz tendríamos 24 Hz.

Este vídeo muestra el funcionamiento del transmisor (sin el amplificador montado) y su recepción a corta distancia:

Conclusiones y posibles mejoras

He conseguido que reciban mi señal en 20 y 40 m a unos 5 km de distancia. Este circuito se puede mejorar desde el esquema hasta la fabricación del pcb, pasando por la elección de los componentes, pero su objetivo era demostrar la viabilidad de la idea. No pretende ser práctico para realizar QSOs ya que se necesita un receptor aparte pero podría ser útil como baliza de telemetría o para estudio de la propagación. Además, las ideas del sigma-delta y del acoplamiento del 602 en banda base se pueden reutilizar para otros proyectos.

El circuito es posible mejorarlo de varias maneras: el pin 16 (gpio 23) se pone a nivel alto cuando está ejecutándose el programa. Se podría utilizar para polarizar la base del transistor 2N2222 y evitar que consuma corriente cuando no es necesario. El oscilador tiene forma cuadrada y se debería utilizar un filtro adecuado para cada frecuencia. Así mismo, la salida diferencial del SA602 sería mejor acoplarla mediante un transformador para reducir distorsión y obtener más ganancia. El mismo circuito se puede utilizar con los programas indicados más arriba para transmitir otras modulaciones, salvo porque el rpitx emplea el pin 12 (gpio 18) para el oscilador y habría que intercambiar esas señales.