AD9850 + Arduino R3 UNO

EB3CXQ RF GENERATOR

Cosetes que tenia per casa i tenia una mica de temps.

Volia tenir un generador de RF per veure si els equips de ràdio estàn correctament ajustats. Això a mode de fer proves i test inicials per tenir referències alhora de saber possibles desviaments.

Comparteixo l’sketch de Arduino per si algú ho vol fer la pràctica.

El codi és un mix d’altres sketch de persones que han fet desenvolupament de les diferents parts. Jo només he adaptat el codi a les meves necessitats.

Jo no sóc programador i vagi per davant el meu agraïment a aquestes persones.

També deixo un video amb unes proves de funcionament.

/*
 ///////////// RF GENERATOR //////////////////////
 Low power CW beacon using an Arduino and AD9850 board
 
 Mix code from many. Thanks to all people that have brain :)

 https://www.instructables.com/id/Arduino-30MHZ-DDS-Signal-Generator-In-12/
 https://www.instructables.com/id/Arduino-Uno-Menu-Template/
 http://gm1sxx.blogspot.com/2015/06/a-practical-implementation-of-el-cheapo.html

 Materials:

 Gravity: 1602 LCD Keypad Shield For Arduino: https://www.dfrobot.com/product-51.html
 Arduino R3 UNO:https://store.arduino.cc/arduino-uno-rev3
 AD9850:https://www.analog.com/en/products/ad9850.html
 
 
*/

#include <LiquidCrystal.h>
#include <EEPROM.h>

///////////////////////////////////////////////////

char callsign[8];
char alpha[] = {'A', 'B', 'C', 'D', 'E','F','G','H','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8','9','0','-','/'};

///////////////////////////////////////////////////

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int backLight = 10;

#define W_CLK 3        // Pin 3 - connect to AD9850 module word load clock pin (CLK)
#define FQ_UD 11       // Pin 11 - connect to freq update pin (FQ)
#define DATA 12        // Pin 12 - connect to serial data load pin (DATA)
#define RESET 13       // Pin 13 - connect to reset pin (RST).
#define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); }
#define FREQUENCY2 0              //Leave this at 0
#define N_MORSE  (sizeof(morsetab)/sizeof(morsetab[0]))
#define SPEED  (12)
#define DOTLEN  (1200/SPEED)
#define DASHLEN  (3*(1200/SPEED))

int_fast32_t rx=10000000; // Base (starting) frequency of VFO.  This only loads once.  To force load again see ForceFreq variable below.
int_fast32_t rx2=1; // variable to hold the updated frequency
int_fast32_t increment = 10; // starting VFO update increment in HZ.
int_fast32_t iffreq = 0; // Intermedite Frequency - Amount to subtract (-) from base frequency. ***********140 Hz ICOM 706MK2G- 0 Hz Yaesu FT817ND ****************

String hertz = "10 Hz";
int  hertzPosition = 5;
byte ones,tens,hundreds,thousands,tenthousands,hundredthousands,millions ;  //Placeholders
String freq; // string to hold the frequency
int_fast32_t timepassed = millis(); // int to hold the arduino miilis since startup
int memstatus = 1;  // value to notify if memory is current or old. 0=old, 1=current.


int ForceFreq = 0;  // Change this to 0 after you upload and run a working sketch to activate the EEPROM memory.  YOU MUST PUT THIS BACK TO 0 AND UPLOAD THE SKETCH AGAIN AFTER STARTING FREQUENCY IS SET!

///////////////////////

String menuItems[] = {"Show Config", "Set Frequency", "Set Callsign", "RF Generator", "Beacon Mode", "About"};

// Navigation button variables
int readKey;
int savedDistance = 0;

// Menu control variables
int menuPage = 0;
int maxMenuPages = round(((sizeof(menuItems) / sizeof(String)) / 2) + .5);
int cursorPosition = 0;

// Creates 3 custom characters for the menu display
byte downArrow[8] = {
  0b00100, //   *
  0b00100, //   *
  0b00100, //   *
  0b00100, //   *
  0b00100, //   *
  0b10101, // * * *
  0b01110, //  ***
  0b00100  //   *
};

byte upArrow[8] = {
  0b00100, //   *
  0b01110, //  ***
  0b10101, // * * *
  0b00100, //   *
  0b00100, //   *
  0b00100, //   *
  0b00100, //   *
  0b00100  //   *
};

byte menuCursor[8] = {
  B01000, //  *
  B00100, //   *
  B00010, //    *
  B00001, //     *
  B00010, //    *
  B00100, //   *
  B01000, //  *
  B00000  //
};


void(* resetFunc) (void) = 0; //declare reset function @ address 0

// This function will generate the 2 menu items that can fit on the screen. They will change as you scroll through your menu. Up and down arrows will indicate your current menu position.
void mainMenuDraw() {
  Serial.print(menuPage);
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print(menuItems[menuPage]);
  lcd.setCursor(1, 1);
  lcd.print(menuItems[menuPage + 1]);
  if (menuPage == 0) {
    lcd.setCursor(15, 1);
    lcd.write(byte(2));
  } else if (menuPage > 0 and menuPage < maxMenuPages) {
    lcd.setCursor(15, 1);
    lcd.write(byte(2));
    lcd.setCursor(15, 0);
    lcd.write(byte(1));
  } else if (menuPage == maxMenuPages) {
    lcd.setCursor(15, 0);
    lcd.write(byte(1));
  }
}

// When called, this function will erase the current cursor and redraw it based on the cursorPosition and menuPage variables.
void drawCursor() {
  for (int x = 0; x < 2; x++) {     // Erases current cursor
    lcd.setCursor(0, x);
    lcd.print(" ");
  }

  // The menu is set up to be progressive (menuPage 0 = Item 1 & Item 2, menuPage 1 = Item 2 & Item 3, menuPage 2 = Item 3 & Item 4), so
  // in order to determine where the cursor should be you need to see if you are at an odd or even menu page and an odd or even cursor position.
  if (menuPage % 2 == 0) {
    if (cursorPosition % 2 == 0) {  // If the menu page is even and the cursor position is even that means the cursor should be on line 1
      lcd.setCursor(0, 0);
      lcd.write(byte(0));
    }
    if (cursorPosition % 2 != 0) {  // If the menu page is even and the cursor position is odd that means the cursor should be on line 2
      lcd.setCursor(0, 1);
      lcd.write(byte(0));
    }
  }
  if (menuPage % 2 != 0) {
    if (cursorPosition % 2 == 0) {  // If the menu page is odd and the cursor position is even that means the cursor should be on line 2
      lcd.setCursor(0, 1);
      lcd.write(byte(0));
    }
    if (cursorPosition % 2 != 0) {  // If the menu page is odd and the cursor position is odd that means the cursor should be on line 1
      lcd.setCursor(0, 0);
      lcd.write(byte(0));
    }
  }
}

void operateMainMenu() {
  int activeButton = 0;
  while (activeButton == 0) {
    int button;
    readKey = analogRead(0);
    if (readKey < 790) {
      delay(100);
      readKey = analogRead(0);
    }
    button = evaluateButton(readKey);
    switch (button) {
      case 0: // When button returns as 0 there is no action taken
        break;
      case 1:  // This case will execute if the "forward" button is pressed
        button = 0;
        switch (cursorPosition) { // The case that is selected here is dependent on which menu page you are on and where the cursor is.
          case 0:
            menuItem1();
            break;
          case 1:
            menuItem2();
            break;
          case 2:
            menuItem3();
            break;
          case 3:
            menuItem4();
            break;
          case 4:
            menuItem5();
            break;
          case 5:
            menuItem6();
            break;
         }
        activeButton = 1;
        mainMenuDraw();
        drawCursor();
        break;
      case 2:
        button = 0;
        if (menuPage == 0) {
          cursorPosition = cursorPosition - 1;
          cursorPosition = constrain(cursorPosition, 0, ((sizeof(menuItems) / sizeof(String)) - 1));
        }
        if (menuPage % 2 == 0 and cursorPosition % 2 == 0) {
          menuPage = menuPage - 1;
          menuPage = constrain(menuPage, 0, maxMenuPages);
        }

        if (menuPage % 2 != 0 and cursorPosition % 2 != 0) {
          menuPage = menuPage - 1;
          menuPage = constrain(menuPage, 0, maxMenuPages);
        }

        cursorPosition = cursorPosition - 1;
        cursorPosition = constrain(cursorPosition, 0, ((sizeof(menuItems) / sizeof(String)) - 1));

        mainMenuDraw();
        drawCursor();
        activeButton = 1;
        break;
      case 3:
        button = 0;
        if (menuPage % 2 == 0 and cursorPosition % 2 != 0) {
          menuPage = menuPage + 1;
          menuPage = constrain(menuPage, 0, maxMenuPages);
        }

        if (menuPage % 2 != 0 and cursorPosition % 2 == 0) {
          menuPage = menuPage + 1;
          menuPage = constrain(menuPage, 0, maxMenuPages);
        }

        cursorPosition = cursorPosition + 1;
        cursorPosition = constrain(cursorPosition, 0, ((sizeof(menuItems) / sizeof(String)) - 1));
        mainMenuDraw();
        drawCursor();
        activeButton = 1;
        break;
    }
  }
}

// This function is called whenever a button press is evaluated. The LCD shield works by observing a voltage drop across the buttons all hooked up to A0.
int evaluateButton(int x) {
  int result = 0;
  if (x < 50) {
    result = 1; // right
  } else if (x < 195) {
    result = 2; // up
  } else if (x < 380) {
    result = 3; // down
  } else if (x < 555) {
    result = 4; // left
  } else if (x < 790) {
    result = 5; // select
  }
  return result;
}

// If there are common usage instructions on more than 1 of your menu items you can call this function from the sub
// menus to make things a little more simplified. If you don't have common instructions or verbage on multiple menus
// I would just delete this void. You must also delete the drawInstructions()function calls from your sub menu functions.

void drawInstructions() {
  lcd.setCursor(0, 1); // Set cursor to the bottom line
  lcd.print("Use ");
  lcd.write(byte(1)); // Up arrow
  lcd.print("/");
  lcd.write(byte(2)); // Down arrow
  lcd.print(" buttons");
}

void menuItem1() { // Function executes when you select the 2nd item from main menu
  int activeButton = 0;

  lcd.clear();
  showFreq();
  lcd.setCursor(1, 1);
  lcd.print(callsign);
  while (activeButton == 0) {
    int button;
    readKey = analogRead(0);
    if (readKey < 790) {
      delay(100);
      readKey = analogRead(0);
    }
    button = evaluateButton(readKey);
    switch (button) {
      case 4:  // This case will execute if the "back" button is pressed
        button = 0;
        activeButton = 1;
        break;
    }
  }
}

void menuItem2() { // Function executes when you select the 2nd item from main menu
  int activeButton = 0;
  lcd.clear();
  lcd.setCursor(0, 0);
  showFreq();
  lcd.setCursor(1, 1);
  lcd.print("Select to Step");
  while (activeButton == 0) {
    int button;
    readKey = analogRead(0);
    if (readKey < 790) {
      delay(100);
      readKey = analogRead(0);
    }
    button = evaluateButton(readKey);
    switch (button) {
      case 1:
        button = 0;
        lcd.clear();
        showFreq();
        lcd.setCursor(0, 1);
        lcd.print("Saving QRG...");
        storeMEM();
        delay(1000);
        activeButton = 1;
        break;
      case 2:
        button = 0;
        rx=rx+increment;
        if (rx >=30000000) { rx=rx-increment; } ; // VFO LIMIT
        lcd.setCursor(0, 0);
        showFreq();
        break;
      case 3:
        button = 0;
        rx=rx-increment;
        if ( rx < 10 ) { rx=rx+increment; }; // VFO LIMIT
        lcd.setCursor(0, 0);        
        showFreq();
        break;
      case 4:  // This case will execute if the "back" button is pressed
        button = 0;
        activeButton = 1;
        break;
      case 5:
        button = 0;
        setincrement();
        break;
      }  
   }
}

void menuItem3() { // Function executes when you select the 3rd item from main menu
  int activeButton = 0;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Set Callsign...");
  lcd.setCursor(0, 1);
  lcd.print(callsign);
  while (activeButton == 0) {
    int button;
    readKey = analogRead(0);
    if (readKey < 790) {
      delay(100);
      readKey = analogRead(0);
    }
    button = evaluateButton(readKey);
    switch (button) {
      case 1:
        button = 0;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Saving CALL...");
        lcd.setCursor(0, 1);
        lcd.print(callsign);
        storeCALL();
        delay(1000);
        activeButton = 1;
        break;
      case 2:
        button = 0;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Reset Config...");
        lcd.setCursor(0, 1);
        lcd.print(callsign);
        storeRESET();
        delay(1000);
        activeButton = 1;
        break;        
      case 4:  // This case will execute if the "back" button is pressed
        button = 0;
        activeButton = 1;
        break;
      case 5:
        button = 0;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Enter your call:");
        lcd.setCursor(0, 1);
        lcd.print(callsign);
        lcd.setCursor(0, 1);
        lcd.cursor();
        lcd.blink();
        int subactiveButton = 0;
        int pos = 0;
        int letter = 0;
        
        while (subactiveButton == 0) {
        int subbutton;
          readKey = analogRead(0);
          if (readKey < 790) {
            delay(100);
            readKey = analogRead(0);
          }
          subbutton = evaluateButton(readKey);
          switch (subbutton) {
            case 1:
               subbutton = 0;
               if ( pos < 8 ) {
                   pos=pos+1;
               }
               lcd.setCursor(pos, 1);
               break;
            case 2:
               subbutton = 0;
               if ( letter < 36 ) {
                   letter=letter+1;
               }
               callsign[pos]=alpha[letter];
               lcd.print(callsign[pos]);
               lcd.setCursor(pos, 1);
               break; 
            case 3:
               subbutton = 0;
               if ( letter > 0 ) {
                   letter=letter-1;
               }
               callsign[pos]=alpha[letter];
               lcd.print(callsign[pos]);
               lcd.setCursor(pos, 1);
               break;   
            case 4:
               subbutton = 0;
               if ( pos > 0 ) {
                   pos=pos-1;
               }
               lcd.setCursor(pos, 1);
               break;   
            case 5:
               subbutton = 0;
               lcd.setCursor(0, 0);
               lcd.print("Save pending... ");
               lcd.setCursor(0, 1);
               lcd.print("                ");
               lcd.setCursor(0, 1);
               lcd.print(callsign);
               subactiveButton = 1;
               break;
          }
        }
        lcd.noCursor();
        lcd.noBlink();
        break;
     }
     
   }
}

void menuItem4() { // Function executes when you select the 4th item from main menu
  int activeButton = 0;

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("RF TRANSMIT MODE");
  lcd.setCursor(0, 1);
  lcd.print("Press button... ");  
  
  pinMode(FQ_UD, OUTPUT);
  pinMode(W_CLK, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(RESET, OUTPUT);

  pulseHigh(RESET);
  pulseHigh(W_CLK);
  pulseHigh(FQ_UD);  // this pulse enables serial mode - Datasheet page 12 figure 10

  while (activeButton == 0) {
    int button;
    readKey = analogRead(0);
    if (readKey < 790) {
      delay(100);
      readKey = analogRead(0);
    }
    button = evaluateButton(readKey);
    switch (button) {
       case 1:
        button = 0;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("TX: CQ CQ CQ de ");
        lcd.setCursor(0, 1);
        lcd.print(callsign);
        sendmsg("CQ CQ CQ DE");
        sendmsg(callsign);
        sendmsg("K");
        delay(1000);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("RF TRANSMIT MODE");
        lcd.setCursor(0, 1);
        lcd.print("Press button... ");
        break;
      case 2:
        button = 0;
        lcd.setCursor(0, 1);
        lcd.print("TX: E E E E E E");
        sendmsg("E E E E E E E E E T");
        lcd.setCursor(0, 1);
        lcd.print("Press button...   ");
        break;
      case 3:
        button = 0;
        lcd.setCursor(0, 0);        
        showFreq();
        lcd.setCursor(0, 1);
        lcd.print("TX:FIXED CARRIER");
        delay(3000);
        lcd.setCursor(0, 0);
        lcd.print("TX:FIXED CARRIER");
        lcd.setCursor(0, 1);
        lcd.print("Back to stop... ");
        sendFrequency(rx);
        break;
      case 4:  // This case will execute if the "back" button is pressed
        button = 0;
        pulseHigh(RESET);
        lcd.display();
        activeButton = 1;
        break;
      case 5:
        button = 0;
        lcd.setCursor(0, 1);
        lcd.print("TX: AD9850 TEST");
        sendmsg("E E E AD9850 TEST E E E AD9850 TEST E E E AD9850 TEST E E E T");
        lcd.setCursor(0, 1);
        lcd.print("Press button...   ");
        break;
    }
  }
}

void menuItem5() { // Function executes when you select the 5th item from main menu
  int activeButton = 0;

  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print(" CW BEACON MODE");
  pinMode(FQ_UD, OUTPUT);
  pinMode(W_CLK, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(RESET, OUTPUT);

  pulseHigh(RESET);
  pulseHigh(W_CLK);
  pulseHigh(FQ_UD);  // this pulse enables serial mode - Datasheet page 12 figure 10

  while (activeButton == 0) {
    int button;
    readKey = analogRead(0);
    if (readKey < 790) {
      delay(100);
      readKey = analogRead(0);
    }
    button = evaluateButton(readKey);
    switch (button) {
      case 4:  // This case will execute if the "back" button is pressed
        button = 0;
        activeButton = 1;
        break;
    }
     
     showFreq();
     delay(5000);
     lcd.setCursor(0, 1);
     lcd.print("                ");
     lcd.setCursor(0, 1);
     lcd.print("TX: VVV VVV VVV ");
     sendmsg("VVV VVV VVV");
     lcd.setCursor(0, 1);
     lcd.print("                ");
     lcd.setCursor(0, 1);
     lcd.print(callsign);
     sendmsg(callsign);
     lcd.setCursor(0, 1);
     lcd.print("QRPP BEACON EEE ");
     sendmsg("/B QRPP BEACON E E E E E E E E E T");
     lcd.setCursor(0, 1);
     lcd.print("Sleep 60 seconds   ");
     delay(5000);
     lcd.setCursor(0, 1);
     lcd.print("Shutdown screen    ");
     delay(5000);
     lcd.setCursor(0, 0);
     lcd.print("Reset to Stop      ");
     delay(5000);
     digitalWrite(10, LOW); //Set LED Backlight to OFF
     delay(45000);
  }
}

void menuItem6() { // Function executes when you select the 7th item from main menu
  int activeButton = 0;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("  RF GENERATOR  "); // print a simple message
  lcd.setCursor(0,1);
  lcd.print("     AD9850    "); // print a simple message
  delay(5000);
  lcd.setCursor(0,1);
  lcd.print("     v0.1a       "); // print a simple message
  delay(5000);
  lcd.setCursor(0,1);
  lcd.print(" www.eb3cxq.com"); // print a simple message
  delay(5000);
  while (activeButton == 0) {
    int button;
    readKey = analogRead(0);
    if (readKey < 790) {
      delay(100);
      readKey = analogRead(0);
    }
    button = evaluateButton(readKey);
    switch (button) {
      case 4:  // This case will execute if the "back" button is pressed
        button = 0;
        activeButton = 1;
        break;
    }
  }
}

struct t_mtab {
  char c, pat;
} ;

struct t_mtab morsetab[] = {
  {'+', 42},
  {'-', 97},
  {'=', 49},
  {'.', 106},
  {',', 115},
  {'?', 76},
  {'/', 41},
  {'A', 6},
  {'B', 17},
  {'C', 21},
  {'D', 9},
  {'E', 2},
  {'F', 20},
  {'G', 11},
  {'H', 16},
  {'I', 4},
  {'J', 30},
  {'K', 13},
  {'L', 18},
  {'M', 7},
  {'N', 5},
  {'O', 15},
  {'P', 22},
  {'Q', 27},
  {'R', 10},
  {'S', 8},
  {'T', 3},
  {'U', 12},
  {'V', 24},
  {'W', 14},
  {'X', 25},
  {'Y', 29},
  {'Z', 19},
  {'1', 62},
  {'2', 60},
  {'3', 56},
  {'4', 48},
  {'5', 32},
  {'6', 33},
  {'7', 35},
  {'8', 39},
  {'9', 47},
  {'0', 63}
} ;


void dash()
{
  sendFrequency(rx);
  delay(DASHLEN);
  sendFrequency(FREQUENCY2);
  delay(DOTLEN);
}

void dit()
{
  sendFrequency(rx);
  delay(DOTLEN);
  sendFrequency(FREQUENCY2);
  delay(DOTLEN);
}


void send(char c)
{
  int i ;
  if (c == ' ') {
    delay(7 * DOTLEN) ;
    return ;
  }
  for (i = 0; i < N_MORSE; i++) {
    if (morsetab[i].c == c) {
      unsigned char p = morsetab[i].pat ;

      while (p != 1) {
        if (p & 1)
          dash() ;
        else
          dit() ;
        p = p / 2 ;
      }
      delay(2 * DOTLEN) ;
      return ;
    }
  }
  /* if we drop off the end, then we send a space */
  Serial.print("?") ;
}

void sendmsg(char *str)
{
  while (*str)
    send(*str++) ;
}
// transfers a byte, a bit at a time, LSB first to the 9850 via serial DATA line
void tfr_byte(byte data)
{
  for (int i = 0; i < 8; i++, data >>= 1) {
    digitalWrite(DATA, data & 0x01);
    pulseHigh(W_CLK);   //after each bit sent, CLK is pulsed high
  }
}

// frequency calc from datasheet page 8 = <sys clock> * <frequency tuning word>/2^32
void sendFrequency(double frequency) {
  int32_t freq = (frequency - iffreq )* 4294967295 / 125000000; // note 125 MHz clock on 9850
  for (int b = 0; b < 4; b++, freq >>= 8) {
    tfr_byte(freq & 0xFF);
  }
  tfr_byte(0x000);
  pulseHigh(FQ_UD);
}


void setincrement(){
  if(increment == 10){increment = 50; hertz = "50 Hz"; hertzPosition=5;}
  else if (increment == 50){increment = 100;  hertz = "100 Hz"; hertzPosition=4;}
  else if (increment == 100){increment = 500; hertz="500 Hz"; hertzPosition=4;}
  else if (increment == 500){increment = 1000; hertz="1 Khz"; hertzPosition=6;}
  else if (increment == 1000){increment = 2500; hertz="2.5 Khz"; hertzPosition=4;}
  else if (increment == 2500){increment = 5000; hertz="5 Khz"; hertzPosition=6;}
  else if (increment == 5000){increment = 10000; hertz="10 Khz"; hertzPosition=5;}
  else if (increment == 10000){increment = 100000; hertz="100 Khz"; hertzPosition=4;}
  else if (increment == 100000){increment = 1000000; hertz="1 Mhz"; hertzPosition=6;}  
  else{increment = 10; hertz = "10 Hz"; hertzPosition=5;};  
   lcd.setCursor(0,1);
   lcd.print("                ");
   lcd.setCursor(hertzPosition,1); 
   lcd.print(hertz); 
   delay(250); // Adjust this delay to speed up/slow down the button menu scroll speed.
};

void showFreq(){
    millions = int(rx/1000000);
    hundredthousands = ((rx/100000)%10);
    tenthousands = ((rx/10000)%10);
    thousands = ((rx/1000)%10);
    hundreds = ((rx/100)%10);
    tens = ((rx/10)%10);
    ones = ((rx/1)%10);
    lcd.setCursor(0,0);
    lcd.print("                ");
   if (millions > 9){lcd.setCursor(1,0);}
   else{lcd.setCursor(2,0);}
    lcd.print(millions);
    lcd.print(".");
    lcd.print(hundredthousands);
    lcd.print(tenthousands);
    lcd.print(thousands);
    lcd.print(".");
    lcd.print(hundreds);
    lcd.print(tens);
    lcd.print(ones);
    lcd.print(" Mhz  ");
    timepassed = millis();
    };

void storeMEM(){
   EEPROM.write(0,millions);
   EEPROM.write(1,hundredthousands);
   EEPROM.write(2,tenthousands);
   EEPROM.write(3,thousands);
   EEPROM.write(4,hundreds);       
   EEPROM.write(5,tens);
   EEPROM.write(6,ones);   
   };

void storeCALL(){
   EEPROM.write(7,callsign[0]);
   EEPROM.write(8,callsign[1]);
   EEPROM.write(9,callsign[2]);
   EEPROM.write(10,callsign[3]);
   EEPROM.write(11,callsign[4]);       
   EEPROM.write(12,callsign[5]);
   EEPROM.write(13,callsign[6]);
   EEPROM.write(14,callsign[7]);   
   };

void storeRESET(){
   EEPROM.write(0,14);
   EEPROM.write(1,0);
   EEPROM.write(2,6);
   EEPROM.write(3,0);
   EEPROM.write(4,0);       
   EEPROM.write(5,0);
   EEPROM.write(6,0);   
   EEPROM.write(7,'E');
   EEPROM.write(8,'B');
   EEPROM.write(9,'3');
   EEPROM.write(10,'C');
   EEPROM.write(11,'X');       
   EEPROM.write(12,'Q');
   EEPROM.write(13,0);
   EEPROM.write(14,0);  
   lcd.setCursor(0,0);
   lcd.print("** RESETTING  **"); // print a simple message
   lcd.setCursor(0,1);
   lcd.print("FACTORY  DEFAULT"); // print a simple message 
   delay(3000);
   resetFunc();
   
};

///////////////////////////////////////////////////

void setup()
{
 lcd.begin(16, 2);       // start the library 
 pinMode(10, OUTPUT);    //Control LED Backlight @ D10
 delay(500);
 digitalWrite(10, HIGH); //Set LED Backlight to ON/OFF
 lcd.display();
 lcd.clear(); 
 lcd.setCursor(0,0);
 lcd.print("  RF GENERATOR  ");
 lcd.setCursor(0,1);
 lcd.print("     AD9850    ");
 delay(2000);
 // Load the stored frequency  
 freq = String(EEPROM.read(0))+String(EEPROM.read(1))+String(EEPROM.read(2))+String(EEPROM.read(3))+String(EEPROM.read(4))+String(EEPROM.read(5))+String(EEPROM.read(6));
 rx = freq.toInt();  
 // Load the stored callsign 
 callsign[0] = char(EEPROM.read(7));
 callsign[1] = char(EEPROM.read(8));
 callsign[2] = char(EEPROM.read(9));
 callsign[3] = char(EEPROM.read(10));
 callsign[4] = char(EEPROM.read(11));
 callsign[5] = char(EEPROM.read(12));
 callsign[6] = char(EEPROM.read(13));
 callsign[7] = char(EEPROM.read(14));
 lcd.createChar(0, menuCursor);
 lcd.createChar(1, upArrow);
 lcd.createChar(2, downArrow);
}
 
void loop()
{

  lcd.setCursor(9,1);            // move cursor to second line "1" and 9 spaces over
  lcd.print(millis()/1000);      // display seconds elapsed since power-up
  mainMenuDraw();
  drawCursor();
  operateMainMenu();
}


Video demostració del funcionament del programa

2 thoughts on “AD9850 + Arduino R3 UNO

  1. Bona nit!
    Està molt be, ja he vist també el video, però, tinc un dubte la senyal de rf surt per proximitat del xip o tens un petit cable com antena?

  2. Tinc un petit cable d’antenna a la sortida sinewave 1 del AD9850. Lo seu seria posar un connector d’antenna. Hi ha gent que fa coses molt xules amb això. Posa filtres etc… a mi ja se m’escapa al meu coneixement. A Aliexpress també hi ha plaques amb el connector d’antenna filtres etc…

    Dona molt per fer aquest bitxet.

Comments are closed.