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