Saturday, January 30, 2021

ADF4351 Signal Generator

 Not much here, just a simple signal generator based on ADF4351 module from "fleebay". PS: there is an improvement over this code at this new post.


 I just needed to generate one single frequency that can go up or down in 100Khz steps via two push buttons. Added an optional LCD to display the main frequency and the third harmonic since I'm using it to verify some equipment on 10Ghz.

Test board:



On the frequency counter:



Schematic based on an Arduino Nano controler:

Spectrum output on lower frequencies (414Mhz) and output level at "0" (add 20db attenuation at the spectrum input):

and the third harmonic:

Power at "3" (second harmonic now visible)


 3rd harmonic as seen on a 10Ghz adapter for a 1.5Ghz spectrum analyzer:
(not calibrated):

Code:

 /// code start
/*!
   ADF4351 signal generator
  
   CT2GQV 2020
   v1.3

   Based on code from: ADF4351 example program https://github.com/dfannin/adf4351

   VFO with 100Khz steps starting from a predifined frquency (UL frequencia) using 2 buttons for up and down.
   Display on 16x2 I2C LCD of the frequency set and the third harmonic value
   Also serial output of the main frequency set.
*/

#include <Arduino.h>
#include "adf4351.h"
#include <LiquidCrystal_I2C.h>

#define SWVERSION "1.3"
#define PIN_SS 9  ///< SPI slave select pin, default value
ADF4351  vfo(PIN_SS, SPI_MODE0, 1000000UL , MSBFIRST) ;
                      
unsigned long frequencia = 3333320000UL ; // 3.333.334 (10 Ghz n=3)
// unsigned long frequencia = 2000000000UL ; // 2.000.000 (10 Ghz n=5)
// unsigned long frequencia =    414000000UL ; //    414.000 (10.368 Ghz n=25)
// for 442Mhz use the bellow and comment the above
//   unsigned long frequencia =  442000000UL ; // 442Mhz or 1.326 Ghz , tird harmonic

// I2C LCD virtual pinout
#define I2C_ADDR    0x27  // I2C Address for my LCD, found with I2C scanner
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7
LiquidCrystal_I2C       lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);

// buttons for up/down in frequency, puleed up from 5v with a 10K resistor, analog pin will be short to ground for button press
int button1 = 1;
int button2 = 2;


void setup()
{
  Serial.begin(9600) ;
  Serial.print("adf4351 VFO CT2GQV "); Serial.println(SWVERSION) ;

  pinMode(button1, INPUT);
  pinMode(button2, INPUT);

  lcd.begin (16, 2, LCD_5x8DOTS); lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE); lcd.setBacklight(HIGH); // 20x4 lines display LCD
  lcd.home();
  lcd.setCursor(0, 0);  lcd.print("Signal Generator  ");
  lcd.setCursor(0, 1);  lcd.print("Ver: "); lcd.print(SWVERSION);

  Wire.begin() ;
  /*!
     setup the chip (for a 10 mhz ref freq)
     most of these are defaults
  */
  vfo.pwrlevel = 3 ; // measured at 3.3Ghz after 1m cable >> "0" = -8 dBm / "1" =  -5.8dbm / "2" = -3.3dbm / "3" = -0.4dbm
  vfo.RD2refdouble = 0 ; ///< ref doubler off
  vfo.RD1Rdiv2 = 0 ;   ///< ref divider off
  vfo.ClkDiv = 150 ;
  vfo.BandSelClock = 80 ;
  vfo.RCounter = 1 ;  ///< R counter to 1 (no division)
  vfo.ChanStep = steps[2] ;  ///< set to 10 kHz steps

  /*!
     sets the reference frequency to 10 Mhz
  */
  if ( vfo.setrf(10000000UL) ==  0 )
    Serial.println("REF.SET: 10 Mhz") ;
  else
    Serial.println("ERROR: reference freq set error") ;
  /*!
     initialize the chip
  */
  vfo.init() ;

  /*!
     enable frequency output
  */
  vfo.enable() ;

  delay(1000);
  lcd.clear();

  if ( vfo.setf(frequencia) == 0 ) {
    Serial.print("VFO.SET:") ; Serial.println(vfo.cfreq) ;
    lcd.setCursor(0, 0);  lcd.print("F   :"); lcd.print(frequencia/1000);
    lcd.setCursor(0, 1);  lcd.print("F(3):"); lcd.print((frequencia/1000)*3);
  } else {
    Serial.println("ERROR: Set init Frequency") ;
  }

vfo.ChanStep = steps[4] ; ///< change to 100 kHz
}

void loop()
{
  int buttonState1 = analogRead(button1);
  int buttonState2 = analogRead(button2);
  // serial debug for the button for +/- frequency
  // Serial.print("B1,B2:"); Serial.print(buttonState1); Serial.print(",");  Serial.println(buttonState2);

// up frequency
  // button pin is puled down to ground...or close to it (100) as long as lower than 2049
  if (buttonState1 <= 100) {
    frequencia += vfo.ChanStep;
    if ( vfo.setf(frequencia) == 0 )
    {
      Serial.print ("VFO.SET: "); Serial.println(vfo.cfreq) ;
      lcd.setCursor(0, 0);  lcd.print("F   :"); lcd.print(frequencia/1000);
      lcd.setCursor(0, 1);  lcd.print("F(3):"); lcd.print((frequencia/1000)*3);
    }
  }
// end up frequency 

// down frequency
  if (buttonState2 <= 100) {
    frequencia -= vfo.ChanStep;
    if ( vfo.setf(frequencia) == 0 )
    {
      Serial.print ("VFO.SET: "); Serial.println(vfo.cfreq) ;
      lcd.setCursor(0, 0);  lcd.print("F   :"); lcd.print(frequencia/1000);
      lcd.setCursor(0, 1);  lcd.print("F(3):"); lcd.print((frequencia/1000)*3);
    }
  }
// end down frequency 

 
// button software debounce
  delay(150);
}
/// code end

Some other signal generators based on similar modules and also the ADF4355:
http://f6kbf.free.fr/html/ADF4351%20and%20Arduino_Fr_Gb.htm
https://pa0rwe.nl/?page_id=1345 (for the ADF4355)

 

Have a nice day!

No comments: