Ever wondered how to create a simple and low cost function generator using an Arduino? Such a circuit would be very useful for many electronic experiments. It can be done by using an AD9833 function generator IC connected to an Arduino
The function generator described in this project also has a digitally controlled gain, allowing the Arduino to control the amplitude of the output waveforms
Here are the major components
- Arduino Uno
- AD9833 DDS Programmable Function Generator Module
- MCP601 Operational Amplifier
- MCP4131 SPI Digital POT
- 1 kOhm resistor
- Breadboard and wires
Let's make some waves.
AD9833 DDS Function Generator ModuleThe AD9833 is a low power, micro controller programmable function generator capable of producing sine, triangular, and square wave outputs.
The output frequency and phase are software programmable, allowing for easy tuning.
The specific board used in this project can be purchased on eBay, AliExpress, Amazon and other sites. Prices range from $5 to $10 excluding shipping.
The pictures shows the board used in this project. It comes with a header which is not attached to the board. As a first step in this project, solder the header into the board to achieve the completed result as shown
A few more items to note regarding the AD9833:
- The max amplitude output when generating a Sine or Triangle wave is 650 mV with a minimum of 38 mV. More on this limitation later. The square wave output is rail to rail
- The max Vdd is 5 V. This suits the 5V power supply available from the Arduino
- The AD9833 uses a SPI communication protocol to write to the data register that controls the output. Later in this project, the Arduino sketch will demonstrate how this works
For full details of how the AD9833 works, see the AD datasheet
https://www.analog.com/en/products/ad9833.html
MCP4131 Digitally Controlled PotentiometerThe MCP41XX family of integrated circuits are manufactured by Microchip and represent a range of digitally controlled potentiometers. The family of devices support 7-bit and 8-bit resistor networks using an SPI interface to control resistance.
A block diagram from the MCP data sheet:
The device can be used as two terminal variable resistor or a three terminal potentiomenter.
Control of the wiper position and hence the resistance is determined by the three digital inputs:
- Device is selected by taking CSlow.
- Using a SPI serial interface (10 MHz, modes 0, 0 & 1, 1), high-speed Read/Writes are written to potentiometer registers. SCK synchronizes the clock between devices
- The wiper moves to the position determined by the value written to the register.
- The wiper has 128 (in the case of MCP4131) possible positions (0 – 127), allowing for incremental steps of about 0.8% of the total resistance.
- The current wiper position can be read from the MCP4131 via the SPI interface
Complete specifications for the MCP4131can be found at the Microchip website.
https://www.microchip.com/en-us/product/MCP4131
https://ww1.microchip.com/downloads/en/DeviceDoc/22060b.pdf
Non - Inverting AmplifierAs explained earlier, the AD9833 produces a max output of 650 mV, which cannot be varied.
This limitation could be restrictive for applications or experiments, so it would be useful to amplify this voltage to larger values. This project uses an non-inverting op amp circuit to achieve this. A standard non-inverting op amp configuration as shown
The gain of this configuration is G = 1 + Rf/Rin. There are numerous articles explaining how the configuration works and derivations of the gain function for those who need more background.
https://www.electronics-tutorials.ws/opamp/opamp_3.html
If Rf is made variable, then the gain can be varied to produce a output voltage with a required value that suits the application or experiment. This project inserts the MCP4131 103 as the feedback resistor (Rf) in a two terminal variable resistor configuration. It is controlled by the Arduino to give the required variable output.
For the specific configuration used in this project, max Rf = 6 kOhm, Rin = 1 kOhm to give a gain of 7.
This gain gives an output voltage of 7 x 650 mV = 4.55 V. This will not saturate the output of op amp.
The CircuitSee the schematic of the circuit used in this project:
Here are some features of the circuit:
- A MCP601 single rail power supply operational amplifier is used in the circuit. This can be substituted with other similar IC’s
- The op amp is set up as a non inverting amplifier; input signal from the AD9833 is connected to the non inverting input (pin 3). It also acts as a buffer between the AD9833 and whatever load is attached, providing a low impedance output.
- Rin is a fixed 1 kOhm resistor connected between inverting input and ground
- Rf is the MCP4131 configured as a two terminal variable resistor. The resistance can be digitally varied by the Arduino to give resistances between 1 kOhm and 6 kOhm. This corresponds to a gain of 2 to 7
- SPI communication with the MCP4131 uses Arduino pin 13(SCK), pin 11 (SDI), and pin 10 (CS). This is configured in the Arduino sketch that contols the circuit
- SPI communication with the AD9833 uses Arduino pin 4 (DATA), pin 5 (CLK) and pin 6 (FSYNC). This is also configured in the Arduino sketch
- The circuit can be powered from the Arduino 5V supply
Using a breadboard and connectors, build the circuit as shown in the picture
Before compiling the sketch, you need to install the AD9833 library. In the Arduino IDE, click on the library manager icon and search for AD9833. The library required is MD_AD9833 by majicDesigns (this is for IDE version 2.0.3. Screenshot will be different for previous IDE versions).
The library provides access to the AD9833 chip features. More info on the library along with documentation can be found at:
https://github.com/MajicDesigns/MD_AD9833
The sketch used in this project is based on anexample included with the library
Compile and upload the sketch to the Arduino. Once the sketch is loaded and the program initializes, the following menu is displayed on the serial monitor
Commands are entered in the format :XXXXX; for example, to set the frequency of channel 0 to 2000 Hz, use the following command - :f12000;
To set the gain to 4 enter following command - :ga4;
It is important to include the : and ; with all commands.
ResultsBelow are two screenshots captured from the output.
Frequency = 2 kHz and gain = 5
Frequency = 2000 Hz and Gain = 2
All op amps have a reduced open loop gain as frequency increases. This is captured in a parameter called “Gain Bandwidth Product” which is quoted on all op amp spec sheets.
Refer to the following Wikipedia article for a full explanation
https://en.wikipedia.org/wiki/Gain%E2%80%93bandwidth_product
Because of this limitation, the MCP601 op amp used in this circuit will have a reduced gain as the frequency gets higher and it will be impossible to output a waveform at 4.55 V with the max gain of 7.
The gain bandwidth product of the MCP601 is quoted as 2.4 MHz. This means that a gain of 7 is possible up to 2400/7 = 342 kHz. At frequencies above this gain will decrease until no more output is possible.
All things considered, for a total cost of approx $20, a very good result and useful function generator.
Comments