#148 AD9833 Basic Demo Cycle
Run a basic waveform demo with an AD9833 module
Notes
I bought an AD9833 module from a seller on aliexpress with the intention of using it to build a function generator to add to my collection of test gear.
This project is a first test to explore:
- the SPI protocol it supports
- different waveforms it can produce
- controlling the frequency
Conclusion:
- once you get the SPI configuration correct, it works extremely well, and is very easy to control.
- accuracy at frequencies under 1MHz or so is very good
- accuracy over 1MHz inconclusive .. I need to do some more testing
Module Interface
Here’s the module, with pins attached (with my imperfect soldering, so don’t blame the manufacturer!):
The labeling of the pins is a bit unusual. Here’s the pin definition, and how they connect to an Arduino Uno for hardware SPI:
Pin | Usage | Arduino SPI Pin |
---|---|---|
VCC | 2.3V to 5.5V | |
DGND | digital ground | |
SDATA | SPI data (MOSI) | 11 MOSI |
SCLK | SPI clock | 13 SCK |
FSYNC | SPI slave select (SS) | 10 SS |
AGND | analog ground | |
OUT | output signal |
NB: the “analog ground” is internally linked to “digital ground” according to the circuit diagram for the module.
SPI Specifics
The module operates in SPI_MODE2 with MSBFIRST:
- data shifted on falling edge
- FSYNC pin is active low,
- accepts the most significant bit (MSB) of each transfer first.
- The SCLK pin is also specified to be kept high when not in use
Waveform demo
The BasicDemoCycle.ino script is a simple non-interactive demo that runs through the different waveforms.
It uses the new SPI.beginTransaction/SPI.endTransaction syntax, although since the script only works with one SPI device, it is redundant to wrap each command sequence in a transaction. But it is a good test of the “right way to do it”. NB: many other scripts found on the net pre-date this syntax.
It is running at very low frequencies in order to produce a visual demo. It sends the measure waveform to the serial port. LEAP#090 PlotNValues (a simple Processing sketch) reads the data from the serial port and plots the output value over time, with some coloration effects thrown in for good measure.
Here’s a sample trace. It shows a few cycles of each waveform. From the left:
- sine wave
- square wave (normal cycle time)
- triangle wave
- square wave (halved cycle time i.e. twice as fast)
- output off
Note that square waves are rail-to-rail, since they bypass the DAC. Other waveforms peak at 0.65V per the datasheet.
Frequency Accuracy?
A few quick measurements with a frequency counter gave very good results under a few MHz. But when I started pushing into the 6-12.5MHz realm, accuracy appeared to drop off markedly.
This may simply be the influence of running the module on a breadboard. I should try it on a PCB.
For now, here are some results (AC-coupled scope traces) with a sinusoid waveform in the breadboard layout.
At 1MHz, still a decent output:
By 8MHz, the waveform is quite distorted and unstable but still on frequency:
By 12MHz, it has devolved to a heavily-modulated mess:
Construction
NB: I created a custom Fritzing Part available here for these diagrams.
Running at 300kHz, pretty accurate!
Credits and References
- Thanks to Michaël via email for the idea of an “off” step in the demo cycle
- Module from a seller on aliexpress
- AD9833 datasheet
- Arduino SPI Reference
- Sending out the right signals - informative round-up of various signal generator modules
- Julian’s Postbag: #41 - AD9833 Waveform Generator - my inspiration to try the unit!
- AD9833 Waveform Generator - good project write-up
- Waveform Generation with AD9833, and SPI - some more good details