AD9833 Poly Signal Generator

Something I wanted to do right from first getting hold of some AD9833 Signal Generators was to set several of them up on a single shield.  This project shows how to drive four of them from an Arduino Uno.

Warning! I strongly recommend using an old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments or amplification!

These are the key Arduino tutorials for the main concepts used in this project:

If you are new to Arduino, see the Getting Started pages.

Parts list

  • Arduino Uno
  • 6x AD9833 signal generator modules
  • Uno Proto Shield
  • 3.5mm Jack Socket
  • 2x 10uF non-polar capacitors (optional, but advised)
  • 3x miniature PCB mounted switches (optional)
  • 2x 10kΩ “thumb trim” potentiometers (optional)
  • 6x 7-way female headers
  • Range of male headers
  • Amplification/speaker for output

The Circuit

AD9833 Multi MIDI Signal Generator_bb

There are two main parts to this circuit.  The top part is a set of female headers to vertically house six of the AD9833 breakout boards and the bottom half and top-right are the optional parts supporting a MIDI connection (D0/RX), two potentiometers (on A0 and A1) and two switches (D2 and D3).

The six AD9833 modules are connected in “parallel” to the Arduino’s 5V, GND, D13 and D11 pins.  Then each has its own “FSYNC” pin linked to one of the Arduino’s IO pins (D5 to D10).

I soldered “right angle” pin headers to the boards to allow them to be mounted vertically – although I already had one soldered with normal headers, hence you’ll see one lying down in the photos!  I removed the plastic housing for the header pins so that they were angled more closely to the PCB.  Without doing this there probably wouldn’t be enough clearance between the boards when mounted.  You can see the pinouts for my modules below.

The audio GNDs are linked together and the audio outputs are linked in a “passive mixer” style connection to the output jack.  I’ve included two non-polar 10uF capacitors to remove the DC bias from the signal, but in theory these are optional (but I’d advise not leaving them out as they create a much more “line output” friendly signal).  I’ve also grouped the audio outputs into two groups of three and connected them up to the left and right channels of the jack socket, via an optional “convert to mono” jumper.  I’ve also included an audio test header output (mono only) to make it easy to hook up a scope for testing.

In theory there ought to be a resistor on the audio outputs to form a proper passive mixing arrangement, but I read in the AD9833 chip data sheet:

Voltage Output. The analog and digital output from the AD9833 is available at this pin. An external load resistor is not required because the device has a 200 Ω resistor on-board.

So I took that to mean that I wouldn’t need one – but I am not an electronics person, so do your own reading and decide for yourself!  If in doubt add a resistor…

The two pots are linked to A0 and A1 via jumpers too, so they can be disabled if required.  As this board is unlikely to be stacked under another shield, I didn’t bother with my usual arrangement of bringing out A0-A6 to headers and using stacking headers for the Arduino connection.  Instead, I’ve just soldered male headers directly onto the proto board as you can see in the photos.

In theory you could build all this on solderless breadboard, extending the ideas in AD9833 MIDI Signal Generator – Part 2 but for me, I decided that way madness lies, hence soldering some sockets to a proto board.  Here are some photos of the build stages.

At this stage the pots are just pushed in position for reference, but you can see the parallel solder links for the 7-pin female headers and the “mono” jumper, non-polar caps and the output jack.

Now the (optional) MIDI RX switch and header is in place along with links between the 5V and GND from the header sockets to the MIDI headers.  You can also see the audio output link in two sets of three linking to the L and R pins of the jack socket via the “mono” jumper.

Here the switches are also now just pushed in for reference but I’ve wired up D13 and D11 via links on the top of the board (purple), and D5 to D10 via links on the bottom (green).

2021-02-23 22.12.36

Finally the connections are made for 5V and GND from the MIDI jumper to the Arduino’s pin headers to the potentiometers, and GND is routed to the two switches.  A0 and A1 are connected, via jumpers, to the potentiometers (pink wires); and D2 and D3 are connected to the switches (yellow).

In the following you can see the six boards plugged in.

2021-02-24 18.13.56

In the final build, I added the audio test output header pins too.

The Code

Once again I’m using the library from MajicDesigns which can be installed in the usual way. Note that the bug I found and reported that I mentioned in the earlier projects has been fixed in more recent versions of the library so it can now simply be used “as is”.

This is just some simple test code to make sure each signal generator can be independently accessed and controlled.  I’ve not done anything with the switches or pots yet.

I create an array of objects via the AD9833 library to control each instance of the AD9833 using some C++ trickery as follows.

#define NUM_ADS 6
int fsync[NUM_ADS] = {5, 6, 7, 8, 9, 10};
MD_AD9833* ad[NUM_ADS];

void setup () {
   // initialise each instance of the AD9833
   for (int i=0; i<NUM_ADS; i++) {
      ad[i] = new MD_AD9833(fsync[i]);
      ad[i]->begin();
   }
}

Each time through, the loop creates a new instance of the MD_AD9833 object with a different FSYNC pin defined.  A pointer to each instance is then stored in the ad[] array which means each can be referenced when required later.  Note that this means we need to use “->” nomenclature rather than the more usual dot (“.”) way of referring to member functions.

Here is the test code that turns on each signal generator in turn with a slightly increased frequency each time.  You can hear in the video (and see the effect on the oscilloscope) that each second the sound is slightly more dissonant than before until all six signal generators are on, at which point they are all turned off and the frequency is doubled (so goes up an octave) and turns on the generators again.  After doing this a few times the frequency drops back down and starts all over again.

void loop () {
   for (int i=0; i<NUM_ADS; i++) {
      ad[i]->setMode(MD_AD9833::MODE_SINE);
      ad[i]->setFrequency (MD_AD9833::CHAN_0, freq+8*i);
      delay(1000);
   }

   for (int i=0; i<NUM_ADS; i++) {
      ad[i]->setMode(MD_AD9833::MODE_OFF);
   }

   freq = freq*2;
   if (freq > 1760) freq=220;
}

You can find it on GitHub here.

Closing Thoughts

I have deliberately left lots of potential here – the use of two potentiometers for analog control, two switches to select waveforms, a MIDI link, as well as the possibility of driving the generators in two groups of three, one for the left channel and one for the right.

Now that this basic test is complete, it’s time to have a play and see what is possible.

Kevin

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s