Fun with GHz signals

Status
Not open for further replies.

TelephoneBill

Well-known member
There are some impressive PCBs on the market these days. Various low cost “copy” Evaluation Boards in particular offer tremendous functionality. I was therefore delighted recently to stumble across the ADF4351 board on eBay, which is a signal generator PCB capable of generating all frequencies from 34 MHz to 4.4 GHz. I always wanted to play with GHz, just for the sheer fun, and at under $20 (including postage) this was too good to miss.

This evaluation board gives direct access to registers inside the ADF4351 chip. So using a Teensy 3.1 as the master controller, I hooked these two boards together via the SPI bus, and that gave me a very wide ranging signal source that was immediately under my own fine program control.

However, one problem immediately arises when you begin to play around with GHz type frequencies – how can you examine what is actually happening inside an experiment in real time? Such extreme frequencies quickly get beyond the power of ordinary 100 MHz scopes to display events. So you need some alternative method of signal monitoring. That is where another evaluation board – the AD8317 – comes in. This little $13 beauty will accept suitable input signals across the range 1 MHz to 10 GHz via an SMA connector and coax cable, and will output a d.c. voltage proportional to the amplitude of the input signal. The output can either be read directly on a simple multimeter, or some other low frequency display if you prefer.

The AD8317 is a very sensitive logarithmic signal detector. It can detect signals down to almost millivolt amplitudes peak to peak (-55 dBm) or up as high as hundreds of millivolts (0dBm). Also, the d.c. output from it is relatively independent of the input signal frequency, so has a nearly flat response over a very wide range. It can therefore easily measure the highest GHz frequency available from the ADF4351 and across a wide range of amplitudes.

These two boards working together form a great GHz experimental pair and they both accept +5 volts as a power supply. I use the Teensy 3.1 USB supply for the ADF4351 and a 12 volt lead acid battery into a 7805 regulator for the AD8317.

Experiment (1) – Test the true bandwidth of a Rigol DS1104 100 MHz scope:

In the first picture below you see the ADF4351 mounted on plywood, together with a Teensy 3.1 controller. Three orange wires implement the SPI bus connection. There are two output SMA connectors. I have one SMA (Out+) coupled via thin RG316 50 ohm cable to the AD8317 and the other (Out-) coupled via black RG58 to a 50 ohm termination resistor soldered to the cable inner and outer ends. Across the resistor is the scope lead with its probe set to X10. These two outputs have identical amplitude signals but the second is 180 deg inverted wrt to the first. The frequency was slowly increased in 1 MHz increments above 100 MHz until the signal on display started to peak and then drop rapidly. It was then backed off to the point where it peaked at 139 MHz and the snapshot taken.

ADF4351.jpg ScopeBWTest.jpg

With the AD8317 detector also connected, I was able to monitor the signal level from the ADF4351 generator independently at the same time by observing the output d.c. voltage. You can see this in the picture on the multimeter as 0.523 volts. Even when the frequency increased beyond 139 MHz and the displayed amplitude was dropping, the d.c. voltage measured remained constant. This gave me confidence that the reduction was down to the scope and its probe and not due to any significant change in the generator output. The X10 probe is quoted as 7pF input capacitance, which at 139 MHz equals a reactive impedance of 163 ohms. This will affect the presented 50 ohm resistive load to some extent but not explain the sudden rapid drop seen at 141 MHz and beyond (which was dramatic).

I conclude therefore that the Rigol DS1104 has a true bandwidth of 140 MHz using my cheap and cheerful probes which came with it. The probes spec itself puts them at 150 MHz.

I was also keen to know that the AD8317 readings could be trusted. So I separately plotted a graph of signal level against d.c. output voltage at a much lower frequency of 1 MHz (and other frequencies up to 25 MHz). This graph is shown below. The remarkable thing was that a d.c. voltage of 0.523 corresponds on my graph to about -7 dBm. Looking up the peak to peak voltage on a table for -7dBm it gives 282 mV pk-pk. The scope display showed 290 mV pk-pk at 139 MHz.

This is obviously “beginner’s luck” to get such close agreement (at 1 MHz and 139 MHz), but it is reassuring to know that the AD8317 is not in significant disagreement with the scope display below the frequency 3 dB point.

AD8317 Graph 1MHz.jpg

In another post, when I have tidy-ed it up a bit, I will show my Teensy code for directly controlling the ADF4351. Not only can you set the frequency, but you can alter the output power levels too – in four discrete jumps. I’m using the lowest power setting in the above experiment. I’ll also include another interesting experiment. This time at 1 GHz with some amplitude modulation.
 
The code I use for the ADF4351 control is listed below. I use a Teensy 3.1 via the SPI bus but other Teensy boards should work. Note in the code that I shift the SPI Clock pin from pin 13 to pin 14. This is just so I can use the LED on pin 13 as a blink diagnostic. The CS (Chip Select) signal is on pin 15 and this is designated "LE" (Load Enable) in the code to conform with the ADF4351 data sheet terminology.

Code:
//Teensy31 - ADF4351 - 34MHz to 4.4GHz PLL Signal Generator (ADF4351 2v00)
//========================================================================
//Date: Wed 06 MAR 2019 - Experiments with ADF4351 signal generator. Uses SPI to communicate with board.
//The following code is derived from ideas presented by KD0CQ, OE6OCG and the ADF4351 data sheet.
//(IMPORTANT NOTE - All frequencies are divided by 10 to fit into 32 bits, e.g. 4.4 GHz is stored as 440000000.
//If it was stored as a full exact Hz integer, it would exceed 32 bits).
//ADF4351 is a FRACTIONAL-N type of PLL. See http://www.ti.com/lit/an/swra029/swra029.pdf for theory.

//general commands: (see Keyboard routine for others)
//---------------------------------------------------
//v - prints the program version number.
//s1234 - sets the Target Frequency to 1234 MHz. Requires 4 digits - e.g. s0050 sets to 50 MHz.
//f1234567 - sets the Target Frequency to 1234.567 MHz. Requires 7 digits - e.g. f0050500 sets to 50.5 MHz.
//p3 - sets the power level to 3. Requires 1 digit - p0 = -4 dBm, p1 = -1 dBm, p2 = +2 dBm, p3 = +5 dBm.
//r - RF Enable toggled either ON or OFF. Default is ON.
//m - modulation toggled either ON or OFF. Default is OFF.

//declarations
#include  <stdint.h>
#include <SPI.h>
#define  LED_ON     GPIOC_PSOR=(1<<5)
#define  LED_OFF    GPIOC_PCOR=(1<<5)

char ProgramVersion[] = "ADF4351 Program Version 2v00";       //command 'v' will print the program version number
byte Byte1, Byte2, Byte3, Byte4, Byte5, Byte6, Byte7, Byte8;  //for keyboard input via incoming serial data
bool ModulationOn;                                            //command 'm' will amplitude modulate output
unsigned int LoopCount;       //main loop counter
const int LE = 15;            //uses Pin15 for controlling LE (Load Enable) line of ADF4351
uint32_t Register[6];         //ADF4351 internal registers (R0 to R5)
int32_t TargetFreq;           //used as desired frequency setpoint for ADF4351 (NOTE - TargetFreq value is divided by 10 to fit max value into 32 bits)
int32_t RefFreq = 2500000;    //input reference frequency (on board ADF4351 25 MHz crystal). (NOTE - 25 MHz is 25 followed by five noughts not six - it is divided by 10)
int32_t ChanSpacing = 625;    //channel frequency spacing = 6.25KHz (NOTE - this too is divided by 10 and stored as 625, not 6250)
int RFOutputPower = 0;        //0 = -4 dBm, 1 = -1 dBm, 2 = +2 dBm, 3 = +5 dBm power levels
int RFOutputEnable = 1;       //enable the RF output as default
byte SPIByte;                 //byte sent over SPI to ADF4351

//Program Setup
//-------------
void setup() {
  //initialise general hardware
  PORTC_PCR5 = PORT_PCR_MUX(0x1);   //LED PC5 pin 13, config GPIO alt = 1
  GPIOC_PDDR = (1<<5);              //make this an output pin
  LED_OFF;                          //start with LED off
  Serial.begin(115200);
  delay(1000);
  pinMode(LE, OUTPUT);
  digitalWrite(LE, HIGH);           //ensure LE signal high to start with (SPI bus not enabled)
  SPI.setSCK(14);                   //change default SCK (Clock) from Pin13 (LED) to Pin14 (allows blink on Pin13)
  SPI.begin();                      //initialise SPI routines
  delay(500);
  LoopCount = 0;                    //zero the loop counter

  //set default target frequency
  TargetFreq = 10000000;            //start frequency = 100 MHz
  UpdateADF4351();                  //initialise frequency of ADF4351 to 100 MHz
 
  //blink 4 times (diagnostic to show that Teensy has been reset and functioning
  Blink(); delay(400);
  Blink(); delay(400);
  Blink(); delay(400);
  Blink(); delay(400);
} //end of setup

//Main Program Loop
//-----------------
void loop() {
  //read key input (if any)
  KeyInput();                         //read key input (if any)

  //modulate signal if required
  if (ModulationOn) {
    if (RFOutputEnable==true) {
      RFOutputEnable = false;
      UpdateADF4351();
    }
    else {
      RFOutputEnable = true;  
      UpdateADF4351();
    }
    delay(900);
  }
  
  //increment loop counter every loop
  LoopCount++;
  if (LoopCount%10 == 0) {          //increments of LoopCount
    Blink();                        //indicate loop is working OK
  }
  delay(100);                           
} //end of Main Loop

//SUBROUTINES
//===========

//Blink Routine
void Blink() {
  //blink the LED
  LED_ON;
  delay(10);
  LED_OFF;
}

//Update Routine
void UpdateADF4351() {
  //reset new register values and send to ADF4351
  BuildRegisters();
  WriteRegViaSPI(5);
  WriteRegViaSPI(4);
  WriteRegViaSPI(3);
  WriteRegViaSPI(2);
  WriteRegViaSPI(1);
  WriteRegViaSPI(0);
}

//Write to ADF4351 Registers
void WriteRegViaSPI(int RegNumber) {
  //write 4 bytes of register value (32 bits total) over SPI bus to ADF4351
  digitalWrite(LE, LOW);
  SPIByte = Register[RegNumber] >> 24;
  SPI.transfer(SPIByte);
  SPIByte = Register[RegNumber] >> 16;
  SPI.transfer(SPIByte);
  SPIByte = Register[RegNumber] >> 8;
  SPI.transfer(SPIByte);
  SPIByte = Register[RegNumber] >> 0;
  SPI.transfer(SPIByte);
  digitalWrite(LE, HIGH);
}

//Print Target Frequency to Monitor Routine
void PrintFreq() {
  //create a printable form of Target Frequency for serial textbox display
  int MHzDigits = TargetFreq / 100000;
  int KHzDigits = (TargetFreq - (MHzDigits * 100000)) * 10;
  Serial.print("Frequency (MHz) = "); Serial.print(MHzDigits); Serial.print("."); Serial.printf("%06d\r\n", KHzDigits);
}

//Prepare ADF4351 Registers Routine
void BuildRegisters() 
{
  //Register R0 (32 bits)
  //-------------------------------
  int R0_Control = 0;      //3  bit
  int R0_FRAC = 0;         //12 bit
  int R0_INT = 0;          //16 bit
  int R0_Reserved = 0;     //1  bit

  //Register R1 (32 bits)
  //-------------------------------
  int R1_Control = 1;      //3  bit
  int R1_MOD = 0;          //12 bit
  int R1_Phase = 1;        //12 bit
  int R1_Prescaler = 0;    //1  bit
  int R1_PhaseAdj = 0;     //1  bit
  int R1_Reserved = 0;     //3  bit

  //Register R2 (32 bits)
  //-------------------------------
  int R2_Control = 2;      //3  bit
  int R2_CounterReset = 0; //1  bit
  int R2_CP3State = 0;     //1  bit
  int R2_PowerDown = 0;    //1  bit
  int R2_PDPolarity = 1;   //1  bit
  int R2_LPD = 0;          //1  bit
  int R2_LPF = 1;          //1  bit
  int R2_ChgPump = 7;      //4  bit
  int R2_DoublBuf = 0;     //1  bit
  int R2_RCounter = 1;     //10 bit
  int R2_RefDivBy2 = 0;    //1  bit
  int R2_RefDoubler = 0;   //1  bit
  int R2_MuxOut = 0;       //3  bit
  int R2_LowNoiseSpur = 0; //2  bit
  int R2_Reserved = 0;     //1  bit

  //Register R3 (32 bits)
  //-------------------------------
  int R3_Control = 3;      //3  bit
  int R3_ClockDiv = 150;   //12 bit
  int R3_ClockMode = 0;    //2  bit
  int R3_Reserved1 = 0;    //1  bit
  int R3_CSR = 0;          //1  bit
  int R3_Reserved2 = 0;    //2  bit
  int R3_ChargeCancel = 0; //1  bit
  int R3_ADB = 0;          //1  bit
  int R3_BandSelCMode = 0; //1  bit
  int R3_Reserved3 = 0;    //8  bit

  //Register R4 (32 bits)
  //-------------------------------
  int R4_Control = 4;      //3  bit
  int R4_OutputPower = 0;  //2  bit
  int R4_RFEnable = 1;     //1  bit
  int R4_AuxOutPower = 0;  //2  bit
  int R4_AuxOutEnable = 0; //1  bit
  int R4_AuxOutSelect = 0; //1  bit
  int R4_MTLD = 0;         //1  bit
  int R4_VCOPowerDown = 0; //1  bit
  int R4_BdSelClock = 200; //8  bit
  int R4_RFDivSel = 3;     //3  bit
  int R4_FeedBack = 1;     //1  bit
  int R4_Reserved = 0;     //8  bit

  //Register R5 (32bits)
  //----------------------------
  int R5_Control = 5;      //3  bit
  int R5_Reserved1 = 0;    //16 bit
  int R5_Reserved2 = 0;    //2  bit
  int R5_Reserved3 = 0;    //1  bit
  int R5_LDPinMode = 1;    //2  bit
  int R5_Reserved4 = 0;    //8  bit

  //Calculate BandSelect and RF Dividers
  //------------------------------------
  R4_RFDivSel = 0;        //selection of chip VCODivider in register R4 - default 0 for TargetFreq >= 2200 MHz 
  int VCODivider = 1;     //corresponding software VCODivider variable - default 1 for TargetFreq >= 2200 MHz

  //test if TargetFreq below VCO range of 2.2 GHz to 4.4 GHz, activate RF output divider if needed
  //(Note - VCO always runs in the physical range 2.2 GHz to 4.4 GHz)
  if (TargetFreq < 220000000) { R4_RFDivSel = 1; VCODivider = 2;}     //Band = 1100 MHz to 2200 MHz
  if (TargetFreq < 110000000) { R4_RFDivSel = 2; VCODivider = 4;}     //Band =  550 MHz to 1100 MHz
  if (TargetFreq <  55000000) { R4_RFDivSel = 3; VCODivider = 8;}     //Band =  275 MHz to 550 MHz
  if (TargetFreq <  27500000) { R4_RFDivSel = 4; VCODivider = 16;}    //Band =  137.5 MHz to 275 MHz
  if (TargetFreq <  13750000) { R4_RFDivSel = 5; VCODivider = 32;}    //Band =  68.75 MHz to 137.5 MHz
  if (TargetFreq <   6875000) { R4_RFDivSel = 6; VCODivider = 64;}    //Band =  34 MHz to 68.75 MHz
    
  //calculate Phase Frequency Detector frequency (PFDFreq) - the actual "lock" frequency in the phase detector
  double PFDFreq = (RefFreq / R2_RCounter) * ((1 + R2_RefDoubler) / (1 + R2_RefDivBy2));
  
  //calculate theoretical fractional NCounter value needed (somewhere between N and N+1 in a FRACTIONAL-N PLL)
  //(Note - TargetFreq * VCODivider is the actual frequency at which the VCO runs under "lock" conditions)
  double NCounter = (TargetFreq * VCODivider) / PFDFreq;

  //set INT value equal to the integer part of fractional NCounter (which is a floating point value)
  R0_INT = NCounter;

  //set MOD value to integer required to achieve desired channel spacing
  R1_MOD = PFDFreq / ChanSpacing; //MOD is the minimum increase/decrease in output frequency under phase locked condition
  
  //set FRAC value to integer required to achieve fractional part of theoretical NCounter
  R0_FRAC = round((NCounter - R0_INT) * R1_MOD);  //(Note - FRAC/MOD is the fractional part of NCounter between N and N+1)

  //adjust any change in RF power or enabled RF output
  R4_OutputPower = RFOutputPower;
  R4_RFEnable = RFOutputEnable;

  //build all 6 register values from component parts
  Register[0] = R0_Control | R0_FRAC << 3 | R0_INT << 15 | R0_Reserved << 31;
  Register[1] = R1_Control | R1_MOD << 3 | R1_Phase << 15 | R1_Prescaler << 27 | R1_PhaseAdj << 28 | R1_Reserved << 29;
  Register[2] = R2_Control | R2_CounterReset << 3 | R2_CP3State << 4 | R2_PowerDown << 5 | R2_PDPolarity << 6 | R2_LPD << 7 | R2_LPF << 8 | R2_ChgPump << 9 |
                        R2_DoublBuf << 13 | R2_RCounter << 14 | R2_RefDivBy2 << 24 | R2_RefDoubler << 25 | R2_MuxOut << 26 | R2_LowNoiseSpur << 29 | R2_Reserved << 31;  
  Register[3] = R3_Control | R3_ClockDiv << 3 | R3_ClockMode << 15 | R3_Reserved1 << 17 | R3_CSR << 18 | R3_Reserved2 << 19 | R3_ChargeCancel << 21 |
                        R3_ADB << 22 | R3_BandSelCMode << 23 | R3_Reserved3 << 24;
  Register[4] = R4_Control | R4_OutputPower << 3 | R4_RFEnable << 5 | R4_AuxOutPower << 6 | R4_AuxOutEnable << 8 | R4_AuxOutSelect << 9 | R4_MTLD << 10 | R4_VCOPowerDown << 11 |
                        R4_BdSelClock << 12 | R4_RFDivSel << 20 | R4_FeedBack << 23 | R4_Reserved << 24;
  Register[5] = R5_Control | R5_Reserved1 << 3 | R5_Reserved2 << 19 | R5_Reserved3 << 21 | R5_LDPinMode << 22 | R5_Reserved4 << 24;
}

//KeyInput Routine
void KeyInput() {
  //blink the LED
  if (Serial.available() > 0) {
    //read the incoming byte
    Byte1 = Serial.read();
    if (Byte1>0x20) {
      switch (Byte1) {
      case 'q':  //freq up 100 KHz
        //task goes here...
        TargetFreq = TargetFreq + 10;             //set target frequency increase = 100 Hz
        if (TargetFreq > 440000000) {TargetFreq = 440000000;} //set upper limit
        UpdateADF4351();                          //change frequency of ADF4351
        PrintFreq();
        Blink();
        break;
      case 'z':  //freq down 100 KHz
        //task goes here...
        TargetFreq = TargetFreq - 10;             //set target frequency decrease = 100 Hz
        if (TargetFreq < 3400000) {TargetFreq = 3400000;}     //set lower limit
        UpdateADF4351();                          //change frequency of ADF4351
        PrintFreq();
        Blink();
        break;
      case 'w':  //freq up 1 MHz
        //task goes here...
        TargetFreq = TargetFreq + 100000;         //set target frequency increase = 1 MHz
        if (TargetFreq > 440000000) {TargetFreq = 440000000;} //set upper limit
        UpdateADF4351();                          //change frequency of ADF4351
        PrintFreq();
        Blink();
        break;
      case 'x':  //freq down 1 MHz
        //task goes here...
        TargetFreq = TargetFreq - 100000;         //set target frequency decrease = 1 MHz
        if (TargetFreq < 3400000) {TargetFreq = 3400000;}     //set lower limit
        UpdateADF4351();                          //change frequency of ADF4351
        PrintFreq();
        Blink();
        break;
      case 'c':  //c625 channel spacing = 6.25 KHz
        //task goes here...
        if (Serial.available() == 5) {
          Byte2 = Serial.read();
          Byte3 = Serial.read();
          Byte4 = Serial.read();
          ChanSpacing = ((Byte2-0x30) * 100) + ((Byte3-0x30) * 10) + (Byte4-0x30);
          Serial.print("Channel Spacing = "); Serial.println(ChanSpacing);
        }
        else {
          Serial.println("c command requires 3 digits");
        }
        Blink();
        break;
      case 'm':  //modulation control
        //task goes here...
        if (ModulationOn) {
          ModulationOn = false;                   //turn FM modulation off
          RFOutputEnable = true;                  //ensure output is enabled when turning modulation off
          UpdateADF4351();                        //change frequency of ADF4351
          Serial.println("AM Modulation is OFF");
        }
        else {
          ModulationOn = true;                    //turn FM modulation on
          Serial.println("AM Modulation is ON");
        }
        Blink();
        break;
      case 's':  //s0100 = set 100 MHz
        //task goes here...
        if (Serial.available() == 2) {
          PrintFreq();
          break;          
        }
        if (Serial.available() == 6) {
          Byte2 = Serial.read();
          Byte3 = Serial.read();
          Byte4 = Serial.read();
          Byte5 = Serial.read();
          TargetFreq = ((Byte2-0x30) * 100000000) + ((Byte3-0x30) * 10000000) + ((Byte4-0x30)* 1000000) + ((Byte5-0x30)* 100000);
          UpdateADF4351();                              //change frequency of ADF4351
          PrintFreq();
        }
        else {
          Serial.println("s command requires 4 digits");
        }
        Blink();
        break;
      case 'f':  //f1234567 = set 1234.567 MHz
        //task goes here...
        if (Serial.available() == 2) {
          PrintFreq();
          break;          
        }
        if (Serial.available() == 9) {
          Byte2 = Serial.read();
          Byte3 = Serial.read();
          Byte4 = Serial.read();
          Byte5 = Serial.read();
          Byte6 = Serial.read();
          Byte7 = Serial.read();
          Byte8 = Serial.read();
          TargetFreq = ((Byte2-0x30) * 100000000) + ((Byte3-0x30) * 10000000) + ((Byte4-0x30)* 1000000) + ((Byte5-0x30)* 100000) + ((Byte6-0x30) * 10000) + ((Byte7-0x30) * 1000) + ((Byte8-0x30)* 100);
          UpdateADF4351();                              //change frequency of ADF4351
          PrintFreq();
        }
        else {
          Serial.println("f command requires 7 digits");
        }
        Blink();
        break;
      case 'p':  //p3 = set power out to 3 (range 0 - 3)
        //task goes here...
        if (Serial.available() == 2) {
          Serial.print("RF Power = "); Serial.println(RFOutputPower);
          break;          
        }
        if (Serial.available() == 3) {
          Byte2 = Serial.read();
          RFOutputPower = (Byte2-0x30);
          Serial.print("RF Power = "); Serial.println(RFOutputPower);
          UpdateADF4351();                              //change power level of ADF4351
        }
        else {
          Serial.println("p command requires 1 digit");
        }
        Blink();
        break;
      case 'r':  //toggle RF enable
        //task goes here...
        if (RFOutputEnable == 1) {
          RFOutputEnable = 0;
          Serial.println("RF Enable is OFF");
        }
        else {
          RFOutputEnable = 1;
          Serial.println("RF Enable is ON");
        }
        UpdateADF4351();            //change RF Enable status
        Blink();
        break;
      case 'v':  //print version number
        //task goes here...
        Serial.println(ProgramVersion);
        Blink();
        break;
      } //end of switch statement
     } //end of Byte1 > 0x60
  } //end of if Serial Available
}
 
Experiment (2) – Measure 1 GHz wavelength [Analogue method]

Haven’t got an amplitude modulation experiment ready yet, but here is one that can measure the wavelength of the ADF4351 1 GHz output using an analogue technique.

It employs two parallel conductors forming a transmission line known as Lecher Lines. Here I am using two aluminium tubes of outside diameter 10mm and 1 metre in length. The tubes are spaced 12 cm apart, but all dimensions are not very critical.

In the picture on the left below you see the Lecher Lines, suspended above a table surface by three books. This is to avoid energy losses from direct table contact – at 1 GHz frequencies and above dielectric losses quickly mount up. The conductors are connected to the ADF4351 board via two short croc clip leads. The leads form a “v” shape as they diverge from the short coax. The shape is important because it forms a gradual change in the characteristic impedance of the transmission line as “waves” from the signal generator progress down into the tube conductors.

Sine wave signals now travel along the tube length to the far end. They cannot go further so are then reflected backwards towards the generator. There is little change in energy as they travel up and down the Lecher Lines, so the backward wave is similar in magnitude to the initial forward wave. Whenever two waves of identical frequency move in opposite directions to each other, they create a “standing wave” – this is a wave that appears to remain static in position, but it has “nodes” along the length where the signal amplitude may either be small (the two signals are cancelling each other as they pass by), or it may be large (the two signals are aiding each other).

Using an amplitude detector that can quickly slide back and forth, it is possible to observe these nodal points directly. I could use the AD8317 but that is not so mobile, so the picture shows a schematic for another simple LED detector, and beneath it are two snapshots of positions when the detector is at a “maximum node” (LED bright) and at a “minimum node” (LED dark). By moving the detector up and down, I managed to place coins at the location of the minimum nodes along the tube length.

Lecher Lines 01.jpg Lecher Lines 05.jpg

The task of measuring the wavelength is then very simple. The distance between two coins is a half of a wavelength – so one full wavelength is twice that distance. Using a tape measure, I measured the coins to be 14.5 cm apart, which means that the full wavelength for an ADF4351 signal of 1 GHz is 29 cm.

The speed of travel for these signals is simply the wavelength times the frequency – 0.29 metres * 1 billion = 290 million metres/second. This is slightly slower than the generally acknowledged speed of light/radio at 300 million metres/second. The ratio of the signal speed divided by the speed of light is called the “velocity factor” for the transmission line. So my Lecher Lines have a velocity factor of 290/300 = 0.97.

Knowing these facts, it would be possible now to measure an unknown frequency injected into the Lecher Line just by measuring its wavelength.

It is very satisfying to experience the effects of a 1 GHz frequency directly on the bench top. You get a strong feeling of “closer” contact with mother nature !

The detector can employ any type of GHz transistor, providing that the “transition frequency (ft)” for it is well above that frequency whose wavelength you are trying to measure. Also remember to switch the power level of the ADF4351 to its highest setting (command p3 in my code) to achieve best results.
 
Experiment (3) – Making a 1 GHz Frequency Counter

In the last experiment, I measured the wavelength of a 1 GHz signal. Now it is time to actually count every individual cycle – all 1 billion per second of them.

My Rigol scope has its own built-in frequency counter which is good up to 100 MHz. So by putting the 1 GHz signal into a “pre-scaler” chip, I can divide the signal down and then display this directly on the scope and its counter.

One suitable chip, still available on eBay for about $1.40, is the MB506. This is a classic 8 pin DIL device, so no need for fancy delicate soldering.

The picture below shows my lash-up on breadboard construction. This is not ideal, because the chip input row of pins has a capacitance to the next adjacent row of 2.8 pF, and this has a very low impedance of 57 ohms at 1 GHz, which is the same magnitude as the 51 ohm termination resistor (required to terminate the coax line). But it does work even up to 1.1 GHz, providing you put the scope probe on X10 and use the “p3” command for maximum power from the ADF4351. I soldered the cable directly to one leg of the two 100 pF capacitors (so in free air) with their other legs then inserted into the breadboard.

MB506 Prescaler 01.jpg MB506 Prescaler Output 02.jpg

As you see on the scope display, the counter is reading “7.81252 MHz”. The pre-scale division ratio I’m using is 128:1 so the input frequency must be 7.81252 * 128 = 1000.00256 MHz. Actually, the counter reads high by about 3 in the least significant digit so the true reading ought to be 7.81249 * 128 = 999.99872 MHz or thereabouts.

The chip ought to also be capable of 256:1 division, but I have never managed to get this to work. So much for chips via eBay :).

To my surprise, I also have a Velleman DVM13MFC2 2.4 GHz frequency counter (found in Europe, looks very similar to Victor VC2000) and when I studied the schematic – lo and behold, it also used the MB506 chip. So with a decent form of construction on ‘manhattan style’ pcb, then you could probably make your own 2 GHz counter at very low cost. My own breadboard refused to work any higher than 1.1 GHz. It began losing cycles at 1.2 GHz. But that is not surprising as 2.8 pF at 1.2 GHz has an impedance of only 47 ohms – lower than the terminating resistor.

I did test the Velleman counter at higher frequencies, and it worked well up to 2.7 GHz (only spec’d at 2.4) so this is another very useful test result from the ADF4351.
 
Experiment (4) – Test with two 1 GHz Dipole Antennas (Transmit and Receive)

In this fourth experiment, I illustrate radio signals transmitted from the ADF4351 via 50 ohm RG316 coax fed into a simple half wave dipole antenna. Another receiver dipole (same design) is located 75 cm away on the bench top and this feeds again via coax into the input of the AD8317 power meter. The d.c. output signal from the AD8317 is connected to Ch1 of my scope. This voltage follows that graph given in post #1 – namely, the lower the voltage, the stronger is the received signal.

Each dipole is made from two separate strips of adhesive “copper foil tape”. The copper tape is 10 mm wide and 45 micron copper thickness. It is self adhesive and has a protective plastic backing (removed before use). The tape is first carefully stuck down onto a thin wooden support (wood dimensions – 180mm x 25mm x 6 mm) to form the rigid dipole. Each separate strip of tape (for top and bottom) is 72.5 mm long, and a 5mm gap separates them at the centre of the support. The overall measurement, therefore, of the copper dipole elements is 145 + 5 = 150 mm end to end.

The coax is terminated via an SMA male at one end (for the electronics) and at the other end its inner and outer conductors are stripped and soldered directly to the copper foil of the dipole. Both dipoles are held vertical by two plywood bases. Each base has a small rectangular slot cut to take the upright wooden supports with a simple “push fit”. The picture below shows the complete test setup on the bench top.

Dipoles 1 GHz 001.jpg

The first test conducted with this configuration was to examine the “resonant” effect of the dipole being cut to a “half wavelength” at 1 GHz. You would expect the maximum power to be transmitted and received at this frequency, with a slight drop in power for frequencies to either side of resonance.

I used the 14.5 cm (145 mm) result of Experiment (2) in post #3 previously as calculation of the half wavelength required. This fixed the combined length for the copper foil strips. I wasn’t quite sure what effect having a 5 mm gap in the centre would be. The answer is given in the next picture. Here you can see that the maximum signal (lowest d.c. voltage from the AD8317 power meter output) occurs at 960 MHz.

This suggests that my dipoles ought to have been slightly shorter – the gap has effectively extended the “end to end length” of copper to 150 mm. That appears to be too long, giving resonance now slightly below 1 GHz. However, because I’m using self adhesive copper foil, I have the option now to trim the ends back a bit to put resonance exactly on 1 GHz. I may try this later.

Dipole Resonance 02.jpg

The second test on this rig aims to discover how effective the transmitting dipole is at radiating energy. On a small scale such as this, it is a possibility that the ADF4351 board itself might be responsible for radiating some of the received power (rather than the dipole). Or it may be that the coax is radiating some too? Who knows?

To test where the received radio power is actually coming from, a comparison is needed – (a) With a transmitter dipole in place as normal, and (b) With no Tx dipole in place, but using a dummy 50 ohm load resistor instead on the end of the coax to absorb the transmitter power.

The picture (A) below shows the output from the receiver dipole when the transmitter dipole is in place. In addition - to highlight the power phase of the signal – I have turned on “amplitude modulation” (command “m” in Teensy code). Clearly you can see what happens when the RF power is turned off – the voltage rises, and some extraneous radio noise is present in the receiver. An instant later, when the RF power is switched on, you see that the voltage falls, and this is more powerful than the noise so a relatively steady d.c. signal is briefly shown on the scope trace. This on/off modulation is happening at 100 mSec intervals. Teensy is controlling the switching automatically.

In picture (B) below it, you see the effect of replacing the transmitter dipole with a 50 ohm “dummy load” resistor. The resistor is fully metal encased inside a standard SMA male terminator, which in turn is screwed on the end of a similar length of RG316 coax. Now the receiver dipole is showing only the high voltage, with the extraneous radio noise being continuous. This indicates no transmitter signal is being picked up whatsoever – even though full RF power is still being applied, and it demonstrates that neither the pcb board nor the coax is responsible for the receiver radio signal. The noise seen is coming from other sources – probably WiFi signals somewhere close by.

Dipoles 1 GHz 003.jpg

One last interesting result of this experimental setup… during testing, out of the blue, I could suddenly see a very curious strong signal interfering with the experiments.

At first I had no clue where this strong signal was coming from. It certainly did not look quite like my ADF4351 signals (see picture below). All of a sudden it disappeared. Then my wife called me to say “dinner” was ready to be served. Yes, you may have guessed it… she had just used the microwave in the kitchen next door! And not on full power either – because it too has “amplitude modulation” !!

Kitchen Microwave Signal 01.jpg
 
Status
Not open for further replies.
Back
Top