frequency response plotting using AD9850 DDS module

Hi,
I am trying to plot the frequency response of amplifier automatically using DDS AD9850 as a function generator and interface it with Arduino UNO. I downloaded the code and library for the same from Arduino tehNiq: Signal generator with AD9850 and Arduino
Now the problem I m facing is, I am able to see the changes in frequency on LCD when i rotate the rotary encoder but the same changes are not visible on CRO. I get a constant Frequency irrespective of the changes i make in the rotary encoder. Also, this is manual updation, how can I go for automation in this system?? I don't know much about coding :frowning: please can anybody help me in generating frequency pulses to program DDS AD9850?? I will attach the code I used for programming DDS.
Please help!!
Thanks in advance,
Arpita

http://www.hamstack.com/hs_projects/k6bez_antenna_analyzer.pdf

http://dc2wk.schwab-intra.net/?page_id=1072

http://rheslip.blogspot.com/2015/08/the-simple-scalar-network-analyser.html

Arduino AD9850 network analyzer
Arduino AD9850 antenna analyzer

arpita_aw:
I will attach the code I used for programming DDS.

And the circuit you are using please - something is failing in the communication to the chip
by the sound of it, that could hardware or software...

Hi,

I am building AD9850 based signal generator module, I have used the code and schematic for frequency generation from this link Arduino tehNiq: Signal generator with AD9850 and Arduino .

Problem which I am facing now is with LCD. i.e when i try to change frequency by rotating the rotary encoder only one frequency is shown on LCD. I am able to see the frequency change on Oscilloscope but I am not able to verify the same on LCD

also with reference of above

is it possible to update the frequency on DDS automatically? Like between 20Hz to 20kHz (in user defined steps) and feed it to arduino UNO and acquire and dsiplay the same on windows PC through bode Plot on MATLAB ??

I am using simulink block in Matlab R2015a for analog read from arduino. So far very little success is being achieved. I will be grateful for your help in coding for the above problem statement.

Please help ASAP.

Can you post your exact code please? In code tags?

hi,
I am using the below code. there is no change of frequency visible on oscilloscope.
/*
Main code by Richard Visokey AD7C - http://www.ad7c.com
Revision 2.0 - November 6th, 2013
adapted sketch 1.2 - january 1st, 2015 - by Nicu Florica - http://www.tehnic.go.ro
http://nicuflorica.blogspot.ro/
http://arduinotehniq.blogsopt.com/
*/

// Include the library code
#include <LiquidCrystal.h>
#include <Rotary.h>
#include <EEPROM.h>

//Setup some items
#define W_CLK 8 // Pin 8 - connect to AD9850 module word load clock pin (CLK)
#define FQ_UD 9 // Pin 9 - connect to freq update pin (FQ)
#define DATA 10 // Pin 10 - connect to serial data load pin (DATA)
#define RESET 11 // Pin 11 - connect to reset pin (RST)
#define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); }
Rotary r = Rotary(2,3); // sets the pins the rotary encoder uses. Must be interrupt pins.
LiquidCrystal lcd(13, 12, 7, 6, 5, 4); // I used an odd pin combination because I need pin 2 and 3 for the interrupts.
int_fast32_t rx=7200000; // Starting frequency of VFO
int_fast32_t rx2=1; // variable to hold the updated frequency
int_fast32_t increment = 1; // starting VFO update increment in HZ.
int buttonstate = 0;
String hertz = "1 Hz";
int hertzPosition = 6;
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!

void setup() {
pinMode(A0,INPUT); // Connect to a button that goes to GND on push
digitalWrite(A0,HIGH);
lcd.begin(16, 2);
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
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 on the AD9850 - Datasheet page 12.
lcd.setCursor(hertzPosition,1);
lcd.print(hertz);
// Load the stored frequency
if (ForceFreq == 0) {
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();
}
}

void loop() {
if (rx != rx2){
showFreq();
sendFrequency(rx);
rx2 = rx;
}

buttonstate = digitalRead(A0);
if(buttonstate == LOW) {
setincrement();
};

// Write the frequency to memory if not stored and 2 seconds have passed since the last frequency change.
if(memstatus == 0){
if(timepassed+20 < millis()){
storeMEM();
}
}
}

ISR(PCINT2_vect) {
unsigned char result = r.process();
if (result) {
if (result == DIR_CW){rx=rx+increment;}
else {rx=rx-increment;};
if (rx >=3000000){rx=rx2;}; // UPPER VFO LIMIT
if (rx <=1){rx=rx2;}; // LOWER VFO LIMIT
}
}

// frequency calc from datasheet page 8 = * /2^32
void sendFrequency(double frequency) {
int32_t freq = frequency * 4294967295/125000000; // note 125 MHz clock on 9850. You can make 'slight' tuning variations here by adjusting the clock frequency.
for (int b=0; b<4; b++, freq>>=8) {
tfr_byte(freq & 0xFF);
}
tfr_byte(0x000); // Final control byte, all 0 for 9850 chip
pulseHigh(FQ_UD); // Done! Should see output
}
// 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
}
}

void setincrement(){
if(increment == 1){increment = 10; hertz = "10 Hz"; hertzPosition=5;}
else 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 = 1; hertz = "1 Hz"; hertzPosition=6;};
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();
memstatus = 0; // Trigger memory write
};

void storeMEM(){
//Write each frequency section to a EPROM slot. Yes, it's cheating but it works!
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);
memstatus = 1; // Let program know memory has been written
lcd.setCursor(1,15);
lcd.print("*");
delay(500);
lcd.setCursor(1,15);
lcd.print(" ");

};

hi
I am sending the circuit schematic, i used Arduino UNO and removed the frequency shift connection.

Thanks
Arpita

You have variables that need to be volatile because they are used in an ISR. Any multi-byte
variable changed in an ISR should only be read in a critical section in the main program.
That means disabling interrupts, then reading it (each byte is read separately in an 8-bit
microcontroller), then re-enabling interrupts:

  noInterrupts (); 
  long my_rx = rx ;
  interrupts () ;
  if (my_rx != rx2){   
        showFreq(my_rx);  // modify this function to take rx as a parameter
        sendFrequency(my_rx);
        rx2 = my_rx;
  }