
RPi
Pico WSPR-Sender
Elektronik-Labor
Projekte
Mikrocontroller
Raspberry
WSPR-Sender erreichen mit kleinen Leistungen sehr große Reichweiten. Es gibt bereits seit langem eine Lösung für den Rapberry Pi, aber der RPi Pico schafft das auch. Ich konnte dabei auf Versuche mit dem Elektor SDR-Shield zurückgreifen, und natürlich auf die VFO-Software für den Pico.
Das WSPR-Signal verwendet vier Frequenzen im Abstand von jeweils 1,46
Hz. Man kommt also nicht mit der VFO-Auflösung von 1 Hz aus. In den 32
Bit der Variable periods ist unten noch reichlich Platz für eine
genauere Unterteilung. Hier wird der Abstand dwsfr zwischen zwei
WSPR-Signalen berechnet, um dann die vier genauen Frequenzen in
wsfr festzulegen. JTEencode bereitet dann den Puffer tx_buffer mit 162
Einträgen 0...3 vor. Sie bestimmen beim eigentlichen Sendedurchlauf,
welche der vier Frequenzen gerade ausgebeben werden soll. Jeder Zustand
bleibt für 683 ms stehen. Einschließlich Restwartezeit werden zwei
Minuten für einen Durchgang benötigt.
//PicoWSPR 40m/30m
#include "vfo2.pio.h"
#include "pico/stdlib.h"
#include "pico/multicore.h"
#include <JTEncode.h>
JTEncode jtencode;
char call[] = "T2EST"; //Rufzeichen
char loc[] = "JO31"; //Lacotor
uint8_t dbm = 10; //10 mW
uint8_t tx_buffer[255];
uint32_t clk_khz = 125000;
volatile uint32_t f=7040100; //40m
//volatile uint32_t f=10140200; //30m
volatile uint32_t periods;
void setup(void){
set_sys_clock_khz(clk_khz,true);
Serial.begin(9600);
}
void set_freq(void){
uint64_t ratio = (uint64_t)clk_khz*1000LL *(1<<24)/(uint64_t)f;
periods=(uint32_t)ratio;
}
void encode(){
uint32_t wsfr[4];
set_freq();
uint32_t dwsfr= 146L * (periods/f)/ 100L ;
wsfr[0]= periods-(10<<24); // + 3 x Abstand 1,46 Hz
wsfr[1]= wsfr[0]-dwsfr;
wsfr[2]= wsfr[1]-dwsfr;
wsfr[3]= wsfr[2]-dwsfr;
memset(tx_buffer, 0, 255);
jtencode.wspr_encode(call, loc, dbm, tx_buffer);
uint16_t n=0;
while(1){
for(uint8_t i = 0; i < 162; i++)
{
periods=wsfr[tx_buffer[i]];
delay(683);
}
periods = 200<<24;
n++;
delay(9350); //Restzeit bis 2 Min
if (n>2){delay(360000);} //6 Min Pause
}
}
void loop(){
delay (50);
encode();
while(1){}
}
void setup1(void){
uint16_t t;
uint32_t delta;
PIO pio = pio0;
gpio_init(0);
gpio_set_dir(0, GPIO_OUT);
pio_gpio_init(pio0, 15);
uint offset = pio_add_program(pio0, &vfo_program);
pio_sm_set_consecutive_pindirs(pio0, 0, 15, 1, true);
pio_sm_config c = vfo_program_get_default_config(offset);
sm_config_set_set_pins(&c, 15,
1);
pio_sm_init(pio0, 0, offset, &c);
pio_sm_set_enabled(pio0, 0, true);
set_freq();
periods=periods-10L<<24;
for(;;){
t = (periods+delta) >> 24;
pio_sm_put_blocking(pio0, 0, t);
delta += periods-(t << 24);
}
}
void loop1(){}
Die entscheidenden Parameter werden als Konstanten festgelegt. Darunter
ist auch das Rufzeichen, das aber nur lizensierte Funkamateure haben.
Damit mein eigenes Rufzeichen nicht versehentlich aus anderen Antennen gehört wird,
habe ich das Rufzeichen "T2EST" erfunden und dabei sorgfältig darauf
geachtet, dass es dieses nicht real gibt. Ohne eigenes Rufzeichen zu senden, ist streng verboten. Aber man kann den Pico ohne
angeschlossene Antenne neben einen Empfänger stellen und das Signal im
Nahfeld empfangen. Wenn die Daten korrekt empfangen werden, weiß man,
dass alles funktioniert.
Das
Empfangsergebnis zeigt, dass jeweils sechs Minuten zwischen den
Aussendungen liegen. Nur die ersten drei Durchläufe haben keine
zusätzlichen Pausen, damit man in Ruhe eine Antenne abstimmen kann und
möglichst schnell zu ersten Empfangsergebnissen kommt. Das Programm
muss zwei Sekunden nach dem Anfang einer geraden Minute gestartet
werden. Es läuft dann beliebig lange autonom weiter. Die nötigen
Verzögerungen wurden allein mit delay() erzeugt, wobei erst nicht klar
war, ob die Genauigkeit reicht. In der Praxis hat sich jedoch gezeigt,
dass die WSPR-Bake über mehr als drei Stunden laufen kann, ohne dass
man eine merkliche Abweichung erkennt.

Wenn man das Ausgangsignal in einem SDR anschaut und die höchste
mögliche Frequenzauflösung einstellt, kann man das Umschalten in die
verschieden Signalfrequenzen direkt verfolgen. Nur mit dem Gehör nimmt man
die engen Frequenzsprünge kaum wahr.
Für einen realen Sendeversuch habe ich das Signal ohne Verstärker
direkt vom Pin 19 des Pico über 22 nF ausgekoppelt und an ein
vorhandenes Pi-Filter zur Antennenpassung übergeben. Im 40m-Band wird
ein endgespeister Dipol verwendet. Die Ausgangsleistung beträgt dann
nur ca. 10 mW. Trotzdem konnte ich am Nachmittag damit zahlreiche
Stationen in Deutschland und fünf weiteren Ländern erreichen. Bei
dieser geringen Leistung muss ich nicht befürchten, dass jemand durch
30 dB schwächere Nebenausstrahlungen gestört wird. Ein Endverstärker
mit 1 W oder mehr könnte allerdings schon problematisch werden. Macht
aber nichts, Versuche mit extrem kleiner Sendeleistung sind besonders
spannend. Im 30m-Band konnte ich damit bereits 1000 km überbrücken. Die
Verbindung nach Schweden sieht man im Bild ganz oben.
Download:
PicoWSPR.zip
Alternative WSPR-Lösungen für den Pico:
https://github.com/RPiks/pico-WSPR-tx/tree/main/WSPRbeacon
https://github.com/Jochen-bit/pico-WSPR-tx
Beacon HF von Anthony F4GOH
Gerade erst bei Github entdeckt: Anthony, F4GOH hat meinen kleinen
WSPR-Sender aufgebohrt und zu einer Funkbake erweitert, die neben WSPR
auch mit RTTY oder CW senden kann. Außerdem sind eine eigene Platine,
ein OLED, ein Uhrenbaustein und ein GPS-Modul dazugekommen. Die
Quelltexte sind gut kommentiert, und man findet jetzt Kommentare auf
Französisch, Englisch und Deutsch, eine echte europäische
Zusammenarbeit.
Elektronik-Labor
Projekte
Mikrocontroller
Raspberry