The ADALM1000 has 4 general purpose digital input/output pins which we can use as a serial port, as we saw in this last blog entry. We can use these pins to interface to direct digital synthesis (DDS) waveform generators such as the AD9837, AD9833 and AD5932. All three of these DDS generators are capable of producing sine, triangular, and square wave outputs.
SparkFun have a breakout board based around the AD9837 DDS called the MiniGen ($29.95).
In figure 1 we see that it is a relatively simple matter to connect the MiniGen board to the digital connector on the ALM1000. If a 6 pin right angle male header is installed as shown, the FSYNC, SDATA, and SCLK pins connect to PIO 0, PIO 1, and PIO 3 respectively. The other three header pins are open connections on the MiniGen board and the ground and power GND, VIN pins can be wired to 3.3V and GND with jumper wires. The solder bridge jumper, which shorts out the on board LDO, for powering the board directly from 3.3V will also need to be soldered in as shown. I installed a two pin female right angle connector to the analog output connection points as well.
Figure 1 Adapting AD9837 MiniGen to ALM1000
Demo Python program
A version of the ALICE oscilloscope program has been made which includes a sub-window to control the MiniGen functions. In figure 2 we see a screen shot of the program. The MiniGen control window allows the four possible waveform shapes to be selected. The master clock frequency can be set, the board comes populated with a 16 MHz crystal oscillator. And of course the output frequency can be set. All the necessary Python program files are included in the zip archive attached at the end of this blog.
The board produces approximately 1 V p-p amplitude signals centered on the supply / 2 which is about 1.65 V in this case. The generator is setup to generate a sine wave at 170 Hz. Scope channel A is displaying the generator output and channel B is displaying the signal after going through a simple RC low pass filter. Note that the internal ALM1000 AWG generators are turned off and not being used.
Figure 2 ALICE with MiniGen plug-in
The AD9833 is another waveform generator similar to the AD9837. Looking at the datasheet for the AD9833 it looks like the serial interface waveforms are the same as for the AD9837 and the configuration of the control, frequency and phase registers are the same as well so the demo Python program should work for both devices by adjusting which I/O pins map to FSYNC, SDATA and SCLK as needed.
An AD9833 based module has also been designed. A rendering of the PCB is shown in figure 3 and Eagle design files are included in the zip archive attached at the end of this blog. The AD9833 comes in a leaded SMD package and is perhaps easier to mount by hand rather than the LFCSP package the AD9837 comes in. A socketed through hole half can crystal oscillator was used in this case to make it easy to swap in and out different frequency oscillators. Also there is no op-amp on the board so just the raw output of the AD9833 is provided. For this board SCLK and SDATA are connected to PIO 0 and PIO 1 respectively. Solder jumper SJ1 connects FSYNC to either PIO 2 or PIO 3. The 6 pins of the connector pass through to the DIGITAL2 header to allow stacking a second copy of this board or some other serial interface board to the ALM1000. Jumper JP2 provides an option to power the circuit from the 3.3 Volts or an external +5 V supply.
Figure 3 AD9833 generator board layout
The PCB costs $7.80 at OSH Park for three copies. The AD9833 in single quantities costs $ 9.23 at Mouser. Half size can crystal oscillators at various frequencies cost $1.00 or less from multiple sources. Male and female single row headers as well as the passives are commonly available items. Total BOM for one board should be less than $25.
The third possibility is the AD5932 DDS waveform generator. The schematic for an AD5932 based function generator board is shown in figure 4. Unlike the AD9833 and AD9837, the AD5932 has a CTRL input that starts the output waveform on the falling edge after a rising edge. This can be used to synchronize the starting point of the generated waveform with another signal such as one or the other of the ALM1000 analog outputs.
One side of an AD8542 dual rail-to-rail CMOS op-amp is used to amplify the output of the AD5932. The amplifier is configured as an inverting I to V stage. The current output of the DAC is connected to the summing junction in the current to voltage configuration. Adjustable resistor R1 allows the amplitude of the output to be varied. A DC offset to keep the output within the 0 to 5 V power supply is provided by R2, R3 from the 2.5 V reference of the ALM1000.
Figure 4 AD5932 generator board schematic
The second side of the dual op-amp is used as a voltage comparator to produce a trigger signal to the CTRL input of the AD5932. Jumper JP5 allows either analog output channel A or B or an external signal to be used as the trigger source. Adjustable resistor R6 is used to set the trigger level on the input signal.
The control register of the AD5932 must be written to before each trigger input pulse on the CTRL input. This requires that the program do a write cycle to the AD5932 before each scope sweep. Unfortunately this requires changes deep inside the ALICE program and is left for the more advanced users.
A rendering of the 1.2” by 2.5” PCB is shown in figure 5.
Figure 5 AD5932 DDS generator board layout
With the proliferation of possible external “PMOD” type boards that can be controlled through the ALM1000 digital connector, a version of the ALICE oscilloscope program has been written which allows the user to optionally select a “plugin” software module upon start-up. Customized plugin modules to control any of these external boards can then be written without messing with the main program. The zip archive contains a draft version of the main program and “plugin” modules for the PMOD-DA1, the AD9837 MiniGen, the AD9833 DDS board and the AD5932 DDS board. Simple modules to replace the static controls of the 4 digital pins which were removed from the main program are included as well.
One thing to remember about writing these plugin modules is that the variable spaces for the main program and plugin are separate and passing info between the two is difficult. Also common functions used by both parts of the program such as the pysmu.py functions need to be in a separate file that is imported into each part. The zip file contains a copy of pysmu.py as well.
In conclusion we can drive the AD9837, AD9833 or AD5932 serial port from the digital port on the ADALM1000 and use Python to control the output waveform. In future blogs we will see how to use the ALM1000 digital pins to control even more devices that have serial inputs and outputs.
As always I welcome comments and suggestions from the user community out there.