AD9833 Signal Generator - signal flickering (time issue?)

Hi everyone,
Im currently working on a AD9833 based signal generator.
Here I have an issue, the signal flickers which I believe is caused by the fact that the state of generator is continously updated in void loop().

Here I provide my code:

#include <SPI.h>
#include <Wire.h>
//#include <LiquidCrystal_I2C.h>


//Map pins
const int FSYNC = 10; 
const int PUSH = 2;
const int testButt = 3;

//Define contants for AD9833
const int SINE = 0x2000; //0010 0000 0000 0000                    
const int SQUARE = 0x2028; //0010 0000 0010 1000                  
const int TRIANGLE = 0x2002; //0010 0000 0000 0010

//set some default values
int waveform = SINE; //default waveform is sine.
long freq = 10000; //default frequency is 1 kHz.
int x = 0b0001; //cyclic for shape change
int step = 1; //default is 10 Hz step.

enum Mode {FREQ,SHAPE,STEP,AMPL};
Mode mode = FREQ;

void write_frequency(long frequency){
    int MSB,LSB;
    int phase = 0;
    long calculated_freq_word;
    float AD9833Val = 0.00000000;
    AD9833Val = (((float)(frequency)) / 25000000); // zegar DDS 25 MHz
    calculated_freq_word = AD9833Val * 0x10000000;
    MSB = (int)((calculated_freq_word & 0xFFFC000) >> 14);
    LSB = (int)(calculated_freq_word & 0x3FFF);
    LSB |= 0x4000;
    MSB |= 0x4000;
    phase &= 0xC000;
    write_register(0x2100);
    write_register(LSB);
    write_register(MSB);
    write_register(phase);
    write_register(waveform);
}
 
void write_register(uint16_t data){
    SPI.setDataMode(SPI_MODE2); //IMPORTANT: This is the right SPI mode for AD9833.

    digitalWrite(FSYNC, LOW); //Set FSYNC low
    delayMicroseconds(10); //prepare for transfer

    SPI.transfer(highByte(data));
    SPI.transfer(lowByte(data));

    digitalWrite(FSYNC, HIGH); //Bring FSYNC back to high
}

void reset(){
  write_register(0x100);
  delay(10);
}

void display(){

}

void check_button(){
  if(!digitalRead(PUSH)){ //button pushed, connected to ground (LOW)
    if (mode == Mode::FREQ)
      mode = SHAPE;
    else if (mode == Mode::SHAPE)
      mode = STEP;
    else if (mode == Mode::STEP)
      mode = AMPL;
    else if (mode == Mode::AMPL)
      mode = FREQ;
    delay(50); //some delay for bouncing
  }
  printMode(); //debug function
}

void printMode(){ //debug function
  if (mode == Mode::FREQ) {
      Serial.println("Mode: FREQ");
    }
    else if (mode == Mode::SHAPE){
      Serial.println("Mode: SHAPE");
    }
    else if (mode == Mode::STEP){
      Serial.println("Mode: STEP");
    }
    else if (mode == Mode::AMPL){
      Serial.println("Mode: AMPL");
    }
}

void adjust(){
  if (mode == Mode::FREQ){
      if (true){ //right
          freq+=step;
      }
      else if (false){ //left
          freq-=step;
      } 
  }
  else if (mode == Mode::SHAPE){
    int dir = 0;
    if(!digitalRead(testButt)){ //check encoder rotation //1 = SINE, 2 = SQUARE, 4 = TRIANGLE
      x <<= 1;
      if (x > 4)
        x = 0b0001;
      if (x == 1)
        waveform = SINE;
      else if (x == 2)
        waveform = SQUARE;
      else if (x == 4)
        waveform = TRIANGLE;
    }
    else if(false){
      if (x == 1){
        x = 0b0100;
        waveform = TRIANGLE;
      }
      else{
        x >>= 1;
        if(x == 1)
          waveform = SINE;
        else if (x == 2){
          waveform = SQUARE;
        }
      }
    }
  }
  else if (mode == Mode::STEP){
    if (true){ //right
      if (step < 1000000)
        step*=10; 
      delay(100);
    }
    else if (false){ //left
      if(step != 1){
        step/=10;
      }
      delay(100);
    }
  }
  else if (mode == Mode::AMPL){
   //nop
  }
}

void setup(){ 
  Serial.begin(9600);
  pinMode(PUSH,INPUT_PULLUP);
  pinMode(testButt,INPUT_PULLUP);

  SPI.begin(); //start the SPI communication
  reset(); //reset the AD9833 module

  write_frequency(freq); //write default: Sine 1 kHz
}

void loop(){
  //check_button(); //switch mode if button was pressed
  //adjust(); //adjust values with encoder
  write_frequency(freq); //set parameters

  //delay(200); //some delay is desired
  delay(100);
}

This flicker seems to go away when we set relatively high frequency like 200 kHz or so.
I tried to play with delay() but no luck yet.
Does anyone know a suitable soltution to this problem?

Thanks in advance.

Kind regrads

So why not just change it when a change is needed?
What exactly are you trying to do?

Can you provide a schematic?

1 Like

Yeah, actually thats true, perhaps I can add some boolean variable to check if we have changed anything, I will try on that. (Or maybe some has better idea?)

As for schematic, I do not have a proper one yet, I just have this setup:

(Arduino Nano) --> (AD9833)
Vcc ---> Vcc
GND ---> GND
D11 ---> DATA
D13 ---> CLK
D10 ---> FNC

  • some inputs for buttons and encoder that are currently not used

What does this command do? (Inside the write_frequency function )

Don't write the frequency in every time through loop() (ie, thousands of times a second). Only write the frequency when you need a change.

I wrote a library for this device that works well if you are interested (GitHub - MajicDesigns/MD_AD9833: Library for using a AD9833 Programmable Waveform Generator hardware by Analog Devices. or used the library manager).

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.