Program multiple AD9833 with Arduino Uno or Due and no SPI

This is how I programmed multiple AD9833 with Arduino Uno (same for Arduino Due). This method doesn't use SPI port. Connect FSYNC, SDATA AND CLK of the AD9833 to pin 12, 19 and 18 of Arduino. All other AD9833 boards are connected together on the SDATA and CLK while FSYNC pins are connected to pins 0-13 of Arduino board to be programmed sequentially . The code is pretty simple. It works with Arduino Due too.

#include "Wire.h"
int FSYNC = 12; //in my example OR ANY PIN 0-13
int SDATA = 19;
int SCLK = 18;
int i;
int k ;
unsigned long freq;     
//byte wave=1;
void setup() {
  freq=1; // start with frequency 1HZ as an example
//Application Note AN-1070 from Analog Devices
 UpdateRegister(0x2100);  UpdateRegister(0x50C7); UpdateRegister(0x4000); 
 UpdateRegister(0xC000); UpdateRegister(0x2000);
for(k=0;k<14;k++)  pinMode(k, OUTPUT);

  for (i=0;i<14;i++)  digitalWrite(i,HIGH); // put pins 0-13 (FSYNC's) as output HIGH
  
 // pinMode(FSYNC, OUTPUT);  pinMode(SDATA, OUTPUT); pinMode(SCLK, OUTPUT);
 //digitalWrite(FSYNC, HIGH);digitalWrite(SDATA, LOW);digitalWrite(SCLK, HIGH);
  }

void loop() {
for(k=0;k<14;k++) 
{
 UpdateFreq(freq, 0x2000);  // for every FSYNC pins 0-13 we update a desired frequency
 FSYNC++;                                //0x2000 is for sine wave, 0x2020 is for square etc
 delay(1);      
          }
freq++; //increase programmed frequency by 1Hz after each AD9833 was programmed (e.q.)
FSYNC=0; //start FSYNC (AD9833 chip select ) from the beginning 
delay(500); // a delay to measure your desired programmed frequencies with a scope
}

void UpdateFreq(long freq, int form){
// function to program the frequency into registers - no touch
long FreqReg;
unsigned int MSB, LSB;
  FreqReg = (freq * pow(2, 28)) / 25000000; // 25MHz Quarz
  if (form == 0x2020) FreqReg = FreqReg << 1;  
  MSB = (int)((FreqReg & 0xFFFC000) >> 14);
  LSB = (int)(FreqReg & 0x3FFF);
  LSB |= 0x4000;
  MSB |= 0x4000;
  UpdateRegister(0x2100); // Control Register, Reset Bit DB8 
  UpdateRegister(LSB);    // Frequency Register 0 LSB
  UpdateRegister(MSB);    // Frequency Register 0 MSB
  UpdateRegister(0xC000); // Phase Register
  UpdateRegister(form);   // Exit Reset 
}
void UpdateRegister(unsigned int data)
{ // function to program registers - no touch
  unsigned int pointer = 0x8000;
  digitalWrite(FSYNC, LOW);
  for (int i=0; i<16; i++){
    if ((data & pointer) > 0) { 
      digitalWrite(SDATA, HIGH); 
    }
    else { 
      digitalWrite(SDATA, LOW); 
    }
    digitalWrite(SCLK, LOW);
    digitalWrite(SCLK, HIGH);
    pointer = pointer >> 1 ;
  }
  digitalWrite(FSYNC, HIGH);
}

Did you have a question?

Please edit your post…

First, use Auto Format in the IDE.

Then, use Copy for Forum in the IDE

Then, paste it instead of the code you have there now, so we can see you work in all its glory, like:

void loop() {

// so it looks like code 
// in a grey box area
// with... 

  if ()
 // all the formatting intact

TIA

a7

oh , holly mamma , it worked :slight_smile: , thanks for the suggestion

OK, tell the truth - did you

Auto Format

that code using the tool in the IDE?

a7

So

#include "Wire.h"

int FSYNC = 12; //in my example OR ANY PIN 0-13
int SDATA = 19;
int SCLK = 18;
int i;
int k ;
unsigned long freq;
//byte wave=1;

void setup() {
  freq = 1; // start with frequency 1HZ as an example
  //Application Note AN-1070 from Analog Devices
  UpdateRegister(0x2100);  UpdateRegister(0x50C7); UpdateRegister(0x4000);
  UpdateRegister(0xC000); UpdateRegister(0x2000);
  for (k = 0; k < 14; k++)  pinMode(k, OUTPUT);

  for (i = 0; i < 14; i++)  digitalWrite(i, HIGH); // put pins 0-13 (FSYNC's) as output HIGH

  // pinMode(FSYNC, OUTPUT);  pinMode(SDATA, OUTPUT); pinMode(SCLK, OUTPUT);
  //digitalWrite(FSYNC, HIGH);digitalWrite(SDATA, LOW);digitalWrite(SCLK, HIGH);
}

void loop() {
  for (k = 0; k < 14; k++)
  {
    UpdateFreq(freq, 0x2000);  // for every FSYNC pins 0-13 we update a desired frequency
    FSYNC++;                                //0x2000 is for sine wave, 0x2020 is for square etc
    delay(1);
  }
  freq++; //increase programmed frequency by 1Hz after each AD9833 was programmed (e.q.)
  FSYNC = 0; //start FSYNC (AD9833 chip select ) from the beginning
  delay(500); // a delay to measure your desired programmed frequencies with a scope
}

void UpdateFreq(long freq, int form) {
  // function to program the frequency into registers - no touch
  long FreqReg;
  unsigned int MSB, LSB;
  FreqReg = (freq * pow(2, 28)) / 25000000; // 25MHz Quarz
  if (form == 0x2020) FreqReg = FreqReg << 1;
  MSB = (int)((FreqReg & 0xFFFC000) >> 14);
  LSB = (int)(FreqReg & 0x3FFF);
  LSB |= 0x4000;
  MSB |= 0x4000;
  UpdateRegister(0x2100); // Control Register, Reset Bit DB8
  UpdateRegister(LSB);    // Frequency Register 0 LSB
  UpdateRegister(MSB);    // Frequency Register 0 MSB
  UpdateRegister(0xC000); // Phase Register
  UpdateRegister(form);   // Exit Reset
}

void UpdateRegister(unsigned int data)
{ // function to program registers - no touch
  unsigned int pointer = 0x8000;
  digitalWrite(FSYNC, LOW);
  for (int i = 0; i < 16; i++) {
    if ((data & pointer) > 0) {
      digitalWrite(SDATA, HIGH);
    }
    else {
      digitalWrite(SDATA, LOW);
    }
    digitalWrite(SCLK, LOW);
    digitalWrite(SCLK, HIGH);
    pointer = pointer >> 1 ;
  }
  digitalWrite(FSYNC, HIGH);
}

Anyway, nice work.

a7

It remains to check the work on the RP2040 Pico! Compiles without errors!

if you load the correct values on the registers and the output pins to connect to anything you want to control sequentially , then bcse this version dosnt use SPI, there is no reason to fail