Sometimes it is nice to have local source for tuning and testing. So i decided to build a low power source, based on multiplication from a known (GPS) locked frequency source. To reach 122 Ghz There is several multiplication factors possible:
IF | LO | RF | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
144,4 | 122500,4 | 122644,8 | 61322,4 | 40881,6 | 30661,2 | 24528,96 | 20440,8 | 17520,69 | 15330,6 | 13627,2 | 12264,48 | 11149,53 | 10220,4 |
144,4 | 122500,4 | 122356 | 61178 | 40785,33333 | 30589 | 24471,2 | 20392,67 | 17479,43 | 15294,5 | 13595,11 | 12235,6 | 11123,27 | 10196,33 |
144,4 | 122356 | 122500,4 | 61250,2 | 40833,46667 | 30625,1 | 24500,08 | 20416,73 | 17500,06 | 15312,55 | 13611,16 | 12250,04 | 11136,4 | 10208,37 |
144,4 | 122356 | 122211,6 | 61105,8 | 40737,2 | 30552,9 | 24442,32 | 20368,6 | 17458,8 | 15276,45 | 13579,07 | 12221,16 | 11110,15 | 10184,3 |
I decided to use multiplication factor 12, as i already had a surplus multiplicator from 2.5Ghz x4 to 10GHz, so the setup looks like this:
From bottom left there is a Arduino Leonardo which programs an ADF4153 PLL, the PLL board is feed with a 10MHz high stability rubidium reference. The output of +0dbM is amplified in a SPF5189 amplifier to appx +12dBm and feed to x4 multiplier , output from this is +15dBm. The final x4 multiplier is an 40GHz multiplier CMA382400AUP, available on ebay.It is mounted in the top cover , so not visible on this picture. I have build the beacon such that the output from the PLL is available on a SMA connector, also the 10GHz is available. In that way the beacon can also be used for other bands. I used the Leonardo ucontroller beacuse it interfaces directly to 3.3V SPI bus used by the ADF4351 board. Frequency can be selected by a 4 position switch , 3 positions are fixed frequencies, and one is used to enter frequency from a terminal window, using the USB interface. The Blokdiagram looks like this:
// ADF4351 & 10MHz reference + control with Leonardo
// 4 position switch selects 3 fixed frequencies and one position enables serial input for frequency control
// OZ2TG
// Website – http://oz2tg.dk
// Email
// Revison 1.5 April 9, 2021
- include
//————————————————————————————-
// SPI PIN DEFINIIONS
//————————————————————————————-
- define ADF4351_LE 10 //LATCH ENABLE
- define DATA_OUT 16 //MOSI
- define LD 14 //LD
- define SPI_CLOCK 15 //Clock
//————————————————————————————-
// Switch PIN DEFINITONS
//————————————————————————————-
- define SW1 2 //Switch1
- define SW2 3 //Switch2
- define SW3 4 //Switch3
- define SW4 5 //Switch4
//——————————————————————————–
// USB VIRTUAL COM PORT SERIAL DEFINITONS
//——————————————————————————–
String Input_String = “”; // a string to hold incoming data
boolean String_Complete = false; // whether the string is complete
//——————————————————————————–
unsigned long Program_Register[6];
float set_freq [7]={1296.900,2555.100,2549.0825,2552.0925,2546.075,3400.900,432.800};
float sw [5] = {0,1,2880.4,2400.2,2592.2};
unsigned long Register_Value;
unsigned int i = 0;
boolean Invalid_Value = false;
unsigned long Default_Register_Values [6] = {0x408228, 0x8321, 0x18005E42, 0x2004B3, 0x15003C, 0x580005}; // 1296.9 MHz with a 10 MHz Reference Clock
unsigned long LO_1 [6] = {0x7F8198, 0x8321, 0x18005E42, 0x2004B3, 0x5003C, 0x580005}; // Values for 2555.1000 MHz/122500,4 mode B
unsigned long LO_2 [6] = {0x7F38C8, 0xBE81, 0x18005E42, 0x2004B3, 0x5003C, 0x580005}; // Values for 2549.0825 MHz/122500,4 mode B
unsigned long LO_3 [6] = {0x7F9058, 0xCE21, 0x18005E42, 0X2004B3, 0x5003C, 0x580005}; // Values for 2552.0925 MHz/122356 mode A
unsigned long LO_4 [6] = {0x7F0798, 0x8C81, 0x18005E42, 0x2004B3, 0x5003C, 0x580005}; // Values for 2546.0750 MHz/122356 mode A
unsigned long LO_5 [6] = {0xAA0048, 0x8321, 0x18005E42, 0x2004B3, 0x5003C, 0x580005}; // Values for 3400.9 MHz 9cm Band
unsigned long LO_6 [6] = {0x158038, 0x80C9, 0x18005E42, 0x2004B3, 0x35003C, 0x580005}; // Values for 432.8 MHz 70cm Band
unsigned long SW_2 [6] = {0x900008, 0x80C9, 0x18005E42, 0x2004B3, 0x5003C, 0x580005}; // Values for 2880.4/5760.8 MHz 6cm Band
unsigned long SW_3 [6] = {0x780008, 0x8191, 0x18005E42, 0X2004B3, 0x5003C, 0x580005}; // Values for 2400.2 MHz 13cm Band
unsigned long SW_4 [6] = {0x818058, 0x8191, 0x18005E42, 0x2004B3, 0x5003C, 0x580005}; // Values for 2592.2/10368.8MHz 3cm Band
//————————————————————————————-
// SETUP SECTION
//————————————————————————————-
void setup()
{
//————————————————————————————
// SPI SETUP
//————————————————————————————
pinMode(ADF4351_LE, OUTPUT);
pinMode(DATA_OUT, OUTPUT);
// pinMode(DATA_IN, INPUT);
pinMode(SPI_CLOCK, OUTPUT);
digitalWrite(ADF4351_LE, HIGH);
digitalWrite(DATA_OUT,LOW);
digitalWrite(SPI_CLOCK,HIGH);
SPI.begin();
SPI.setBitOrder (MSBFIRST);
//——————————————————————————–
// SERIAL SETUP
//——————————————————————————–
// initialize serial:
// reserve 200 bytes for the inputString:
Input_String.reserve(200);
//——————————————————————————–
// LOCK DETECT SETUP
//———————————————————————————
pinMode(LD,INPUT);
digitalWrite (LD,HIGH);
//———————————————————————————
// Selector Switch setup
//———————————————————————————
pinMode(SW1, INPUT);
digitalWrite (SW1,HIGH);
pinMode(SW2, INPUT);
digitalWrite (SW2,HIGH);
pinMode(SW3, INPUT);
digitalWrite (SW3,HIGH);
pinMode(SW4, INPUT);
digitalWrite (SW4,HIGH);
//———————————————————————————-
// Set Serial Baudrate
//———————————————————————————-
Serial.begin (1200);
// while (!Serial);
// Serial.println(“Serial OK”);
}
// Finish setup
//* // MAIN LOOP //*
void loop()
{
boolean loop_flag = true;
int X=0,OLD=0;
delay(1);
while(loop_flag = true)
{
X=PIND&31;
if (X==17) // SW pos1
{
//Serial.println(“SW POS1”);
//Initial_Display();
Serial_Event();
if (String_Complete)
{
Decode_Frequency_Select ();
Initial_Display();
Input_String = “”; // clear the string:
String_Complete = false;
}
}
else if (X==18)
{
Serial.print(“SW pos2=”);
Serial.print(sw[2],3);
Serial.println(“MHz”);
memcpy (Program_Register, SW_2, 6sizeof(unsigned long)); Write_Registers(); } else if (X==3) { Serial.print(“SW pos3=”); Serial.print(sw[3],3); Serial.println(“MHz”); memcpy (Program_Register, SW_3, 6sizeof(unsigned long));
Write_Registers();
}
else if (X==19)
{
Serial.print(“SW pos4=”);
Serial.print(sw[4],3);
Serial.println(“MHz”);
memcpy (Program_Register, SW_4, 6*sizeof(unsigned long));
Write_Registers();
}
else
{
delay(1);
Serial.println(“error”);
}
if (not(X==17))
{
OLD=X;
while(X==OLD) //check for new switch position
{
delay(10);
X=PIND&31;
delay(10);
}
//Serial.println("X/OLD=");
//Serial.println(X);
//Serial.println(OLD);
if (X==17)
{
Initial_Display();
Initialize_Registers();// default values programmed
}
}
else
{
OLD=0;
}
}
}
//——————————————————————————————–
void Initial_Display ()
{
Serial.println(“OZ2TG program for ADF4153 Ver.1.5 // 09042021”);
Serial.println(“Sw1=> Enter frequency number/default at power on”);
Serial.println(“Sw2,3,4=fixed frequency setting”);
Serial.println(“ENTER VALID FREQUENCY # : 0=default , 1,2,3,4,5,6”);
Serial.println(“”);
delay(3);
}
//————————————————————————————-
void Initialize_Registers() // Write Initial Default Values to Program Registers
{
for (int i = 5; i >= 0; i–)
{
(Program_Register [i]) = (Default_Register_Values[i]);
}
Write_Registers();
Serial.print (“Default Registers Programmed to: “);
// Serial.println (” “);
}
//———————————————————————————–
void Decode_Frequency_Select ( )
{
Invalid_Value = false;
int S=Input_String.toInt();
if (S == 0)
{
Initialize_Registers();
}
else if (S == 1)
{
memcpy (Program_Register,LO_1, 6*sizeof(unsigned long));
}
else if (S == 2)
{
memcpy (Program_Register, LO_2, 6*sizeof(unsigned long));
}
else if (S == 3)
{
memcpy (Program_Register, LO_3, 6*sizeof(unsigned long));
}
else if (S == 4)
{
memcpy (Program_Register, LO_4, 6*sizeof(unsigned long));
}
else if (S == 5)
{
memcpy (Program_Register, LO_5, 6*sizeof(unsigned long));
}
else if (S == 6)
{
memcpy (Program_Register, LO_6, 6*sizeof(unsigned long));
}
else
{
Invalid_Value = true;
Serial.println (“Invalid Value”);
Serial.println (” “);
}
if (Invalid_Value == false)
{
Serial.print (“Freq_Out{MHz] = “);
Serial.println(set_freq[S],3);
Serial.println(Input_String);
Write_Registers();
}
}
//———————————————————————————–
void Write_Registers() //Program the 32 bit registers
{
for (int i = 5; i >= 0; i–) // loop 6 times to write the Program Registers
{
Register_Value = (Program_Register [i]);
Serial.print ("Register ");
Serial.print (i);
Serial.print (" = ");
Serial.println (Program_Register [i],HEX);
digitalWrite(ADF4351_LE, LOW);
for (int i = 3; i >= 0; i--) // loop 4 times and transfer 8 bits per loop
{
SPI.transfer((Register_Value >> 8 * i) & 0xFF); // Mask and Shift
delay(1);
}
digitalWrite(ADF4351_LE, HIGH);
delay(1);
digitalWrite(ADF4351_LE, LOW);
}
delay(20);
// Check for LOCK
if ((digitalRead(LD)==1))
Serial.println(“LOCKED”);
else Serial.println(“NO LOCK”);
Serial.println("----------------------------------------") ;
}
//———————————————————————————————
// SERIAL CAPTURE
//———————————————————————————————
/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/
void Serial_Event()
{
int inByte=0;
if (Serial.available()>0)
{
// wait for ready
// char inChar = (char)Serial.read(); // get the new byte:
inByte=Serial.read();
// Serial.println(inByte,DEC);
char inChar=(char)inByte ;
Input_String += inChar; // add it to the inputString:
// if the incoming character is a enter (CR), set a flag
// so the main loop can do something about it:
if (inChar == '\r')
{
String_Complete = true;
}
}
}
//———————————————————————————————