
Standalone SDR-VFO für CW und WSPR
Elektronik-Labor
Projekte
AVR
Der Elektor-SDR
wird hier stand-alone betrieben, also nicht unbedingt über einen PC
abgestimmt sondern allein über Tasten und LCD. Dabei werden zwei Ziele
verfolgt:
1. Der Empfänger soll zugleich auch den VFO für einen
QRP CW-Sender realisieren. Die VFO-Frequenz liegt beim Empfang immer
800 Hz unter der Sendefrequenz. Deshalb reicht ein CW-Filter mit 800 Hz
um die Empfangssignale zu verarbeiten. Der Sende-VFO wird
eingeschaltet, indem man den Pin8 (PB0) auf Masse zieht. Dann erscheint
am Ausgang CLK2 des SI5351 das TX-Signal. Man muss es nur noch weich
tasten und auf den Sendeverstärker führen.
2. Die Taste
S1 soll nun einen schnellen Bandwechsel ermöglichen. Der Empfänger
springt jeweils exakt auf die WSPR-Frequenz eines Bandes. Zum
Dekodieren wird zwar immer noch der PC benötigt, aber die genaue
Abstimmung war bisher immer recht aufwendig. Wenn man gerade etwas
anderes als WSPR empfangen will, ist man immerhin schon mitten im interessanten Bereich eines Bandes.
Für das Programm wird eine neue Library verwendet: Si5351Arduino-master
von Jason Milldrum und Dana H. Myers. Der entscheidende Grund
dafür war, dass ich mit dieser Library jeden der drei möglichen
Ausgänge getrennt ein- und ausschalten kann. Das ist für das
QRP-Senderprojekt entscheidend. Außerdem bietet diese Library eine effektive Möglichkeit zur
Kalibrierung der Frequenz. Und schließlich wird die Abstimmung in feiner Auflösung direkt unterstützt.
Bei
der Initialisierung gibt man die genaue Quarzfrequenz an. An dieser
Stelle hat man die Möglichkeit, den VFO zu kalibrieren. Im vorliegenden
Fall war die Frequenz um 2,127 kHz zu tief.
si5351.init(SI5351_CRYSTAL_LOAD_10PF, 25002127); //Quarz 2,1 kHz über 25 MHz
Für
die Kalibrierung stellt man den Empfänger auf eine bekannte Frequenz
ein. Dazu kann ein Rundfunksender verwendet werden, weil da meist eine
ausreiche Genauigkeit erreicht wird. Dann misst man die Abweichung und
rechnet sie linear auf die Quarzfrequenz 25 MHz um. Die neue Frequenz
trägt man in die init-Funktion ein und lädt das Programm neu. Wie genau
die Kalibrierung gelungen ist, kann man auch durch den Vergleich mit
anderen Empfängern sehen, die im WSPR-Net ihre Empfangsergebnisse
veröffentlichen. Mit dieser Software kann man weiterhin den VFO in
20-Hz-Schritten oder größeren Schritten mithilfe des Potis und Taster
S2 einstellen.
Download: si5351vfo8tx.zip
//SI5351_vfo + LCD + TX output Clk2 @ Pin8 =0
//RX/TX offset = 800 Hz
//S1 Band, WSPR 600m ...10m
#include "si5351.h"
#include "Wire.h"
#include <LiquidCrystal.h>
Si5351 si5351;
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
unsigned long freq = 10100;
unsigned long freqHz;
int pot;
long fstep;
long fstepOld;
int rx;
int rxOld;
int band;
void setup(void)
{
Serial.begin(9600);
Serial.println("Si5351 Clockgen"); Serial.println("");
// Start serial and initialize the Si5351
si5351.init(SI5351_CRYSTAL_LOAD_10PF, 25002127); //Quarz 2,1 kHz über 25 MHz
// Set CLK0 to output 14 MHz with a fixed PLL frequency
si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
si5351.set_freq(4040000000ULL, SI5351_PLL_FIXED, SI5351_CLK1);
si5351.set_freq(1010000000ULL, SI5351_PLL_FIXED, SI5351_CLK2);
si5351.output_enable(SI5351_CLK1, 1);
si5351.output_enable(SI5351_CLK2, 1);
freq = 10100;
freqHz = freq * 1000;
setfreq (freqHz);
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print(freq);
pinMode(A0, INPUT_PULLUP);
pinMode(A1, INPUT_PULLUP);
pinMode(8, INPUT_PULLUP);
band = 0;
}
void setfreq (unsigned long freqHz)
{
uint64_t f2;
uint64_t f3;
uint64_t f4;
uint64_t f5;
unsigned long div2;
// unsigned int Teiler2;
unsigned int rdiv;
if (freqHz > 0) {
f2 = (freqHz) * 4;
si5351.set_freq(f2*100, SI5351_PLL_FIXED, SI5351_CLK1);
f2 = freqHz-800;
si5351.set_freq(f2*100, SI5351_PLL_FIXED, SI5351_CLK2);
if (digitalRead(8) == 1) {
si5351.output_enable(SI5351_CLK2, 0);
}
else {
si5351.output_enable(SI5351_CLK2, 1);
}
}
}
void loop(void)
{
pot = analogRead(A3);
fstep = 0;
if (pot < 200) fstep = 100000;
if (pot > 200) fstep = 2000;
if (pot > 300) fstep = 50;
if (pot > 400) fstep = 20;
if (pot > 500) fstep = 0;
if (pot > 600) fstep = -20;
if (pot > 700) fstep = -50;
if (pot > 800) fstep = -2000;
if (pot > 900) fstep = -100000;
if (fstep != fstepOld) {
lcd.setCursor(1, 1);
lcd.print(fstep);
lcd.print (" ");
}
fstepOld = fstep;
if (Serial.available()) {
freq = Serial.parseInt();
if (freq > 0) {
lcd.setCursor(0, 0);
freqHz = freq * 1000 - 12000;
lcd.print(freq);
lcd.print (" ");
setfreq (freqHz);
}
}
if (digitalRead(A0) == 0) {
band = band + 1;
if (band > 11) band=1;
if (band == 1) freqHz = 502400;
if (band == 2) freqHz = 1836600;
if (band == 3) freqHz = 3592600;
if (band == 4) freqHz = 5287200;
if (band == 5) freqHz = 7038600;
if (band == 6) freqHz = 10138700;
if (band == 7) freqHz = 14095600;
if (band == 8) freqHz = 18104600;
if (band == 9) freqHz = 21094600;
if (band == 10) freqHz = 24924600;
if (band == 11) freqHz = 28124600;
lcd.setCursor(0, 0);
//freq=freqHz/1000;
lcd.print(freqHz);
setfreq (freqHz);
lcd.print (" ");
delay (50);
}
if (digitalRead(A1) == 0) {
freqHz = freqHz + fstep;
lcd.setCursor(0, 0);
//freq=freqHz/1000;
lcd.print(freqHz);
setfreq (freqHz);
lcd.print (" ");
delay (50);
}
rx = digitalRead(8);
if (rx != rxOld) {
setfreq (freqHz);
delay (200);
setfreq (freqHz);
}
}
Elektronik-Labor
Projekte
AVR