Introduction: MIDI-controlled Stepper Motor With a Direct Digital Synthesis (DDS) Chip

Ever have a bad idea that you JUST had to turn into a mini project? Well, I was playing around with a sketch I had made for the Arduino Due aimed at making music with an AD9833 Direct Digital Synthesis (DDS) module... and at some point I thought "hey, maybe I should rig a stepper motor/driver to this". And that idea is exactly what sparked this little breadboard-based project.

Included in this project will be some code for using MIDI-over-USB to control an Arduino Due and sending square waves between an AD9833 module and the stepper driver. There will also be a diagram and basic instructions for connecting this up to an Arduino Due.


What you'll need for this project:

- Arduino Due

NOTE: The code is written for the Due, but it should also work and/or be adapted for the Zero. It utilizes Arduino's MIDIUSB library, which requires a native USB port.

- Solderless Breadboard + Jumpers

- AD9833 Breakout Module

- A4988 Stepper Driver (or similar)

- NEMA 17 Stepper Motor (or similar)

- 24V Power Supply (note, I chose this value of 24 Volts because it was greater than the nominal stepper motor voltage. Your implementation may be different if you use a bigger motor)

Step 1: Breadboarding

The basic idea behind this is that the Direct Digital Synthesis IC will generate a square wave to drive the stepper motor driver's "step" pin. This stepper driver will then move the motor at the specified audible frequency. The direction of the motor is somewhat arbitrary so long as it steps at the correct frequency.

The approach I prefer to take with breadboarding is to run the power pins and grounds first and then start to run all of the other, non-power connections.


- Connect the AGND and DGND Pins of the AD9833 Module to the GND Rail on the breadboard.

- Conect the two GND Pins on the Stepper Driver to the GND Rail

- Bring this over to one of the Arduino Due's GND Pins

3.3V Power:

- Connect the VDD Pin of the Stepper Driver to the breadboard's V+ Rail

- Connect the VCC Pin of the AD9833 Module to the breadboard's V+ Rail

- Bring this over to the Arduino Due's 3.3V Pin

24V Power:

- Connect the VMOT pin to the 24V DC Power supply (depending on your choice of motor, you may want to run a higher or lower supply rail)

Module-to-Module Connection:

- Connect the OUT pin from the AD9833 module to the STEP pin of the motor driver

Stepper Driver Connections:

- Connect the Stepper Motor connections to the 2B/2A/1A/1B Pins. Polarity is not that important, so long as the Driver phases match up with those of the Stepper Motor.

- Connect the RESET and SLEEP Pins together, and bring those over to the Arduino Due Pin 8.

- Connect the DIR Pin to the 3.3V Rail

AD9833 Module Connections:

- Connect SCLK to the Arduino Due's SCK pin. Note that this pin is on the 6-pin male ICSP header near the microcontroller, not on the normal external female headers.

- Connect the SDATA Pin to the Due's MOSI pin. Note that this pin is on the 6-pin male ICSP header near the microcontroller, not on the normal external female headers.

- Connect the FSYNC to the Arduino Due Pin 6 (this is the Chip Select pin for this project)

Now that the breadboard is fully assembled, it's time to take a look at the code!

Step 2: Programming and MIDI Setup

The attached .ino sketch will take USB-MIDI inputs through the Arduino Due's Native USB port, and will use them to drive the AD9833. This chip has a DAC that runs at 25MHz w/ 28 bits of frequency resolution (total overkill for what's needed here), and much of the code here is configuring that to run and output a square wave.

Note: there are two USB Ports. One is used for programming the board, and the other is going to be used for MIDI-over-USB comm.

Note that this sketch will not work as-is on the Arduino Uno - this project is specific in its need for the Native USB in the Arduino Due or similar devices.

Customization Options:

- There are 2 modes, which can be set by a preprocessor macro definition. If "#define STOPNOTES" is left intact, the stepper will stop in between notes. This isn't always desired (for example, playing fast arpeggios), so to change this behavior, simply delete or comment out that #define statement and the stepper will run continuously once played.

- I use a cheap 2-octave MIDI keyboard with this that has an octave up/down button, but in case you don't have that option, you can octave-shift the below frequency translation by multiplying or dividing by powers of 2.

The MIDI-to-frequency translation is done with this line in the playNote function:
int f_out = (int)(27.5*pow(2,((float)midiNote-33)/12));

- I tend to use my PC for interfacing over USB MIDI - you can do this from your favorite Digital Audio Workstation (DAW) software. If you don't have one, it's pretty easy to set this system up using LMMS - a free, open source platform. Once it's installed and running, simply set the Arduino Due as the MIDI Output Device, and if you're using a USB MIDI keyboard, set that as an input.

Step 3: Testing and Experimenting

Time to play your stepper motor!

As stated, the whole idea behind this was kind of an off-the-cuff experiment, so by all means, do some experimenting of your own!