Java Based DDS Controller
A few years ago I purchased a couple of printed circuit boards for an ARRL QEX article called “Building A Direct Digital Synthesis VFO “. One board found its way into a DDS based signal generator with a few modifications. The other wound up as a general purpose PC controlled synthesizer for digital radio experiments and the like.
The original control software was written in Visual Basic and controlled the DDS via the parallel port. Since the parallel port has gone the way of disco and Betamax, I decided to convert the control interface to USB, and since I’ve been learning Java, I decided to re-work the GUI as well.
The result is a USB controlled DDS synthesizer with the simple GUI shown below.
1. The USB Buffer Board
The schematic for a USB buffer board is shown below: The USB module is a DLP-USB245M parallel module from FTDI. The 74AC244 buffer is probably overkill, but they’re easier to replace than the USB module. The DB25 connector which connects to the DDS board was left over from the parallel port version.
2. The DDS Circuit
The actual circuit remains the same, but the microcontroller, rotary switch and LCD components have been omitted. I used an AD9851 DDS instead of the original AD9850. The AD9851 has a wider frequency range, so the low pass output filter was scaled to allow higher frequencies. The original board used a 78L05 regulator which is not shown on the original schematic, but this was replaced with a higher current 7805 to allow for the higher current draw of the AD9851. The AD9851 has an internal 6X REFCLK multiplier option which allows lower frequency oscillators to be used. In this case the 30MHz clock oscillator is internally multiplied up to 180MHz. The DDS board is connected to the USB buffer board by the DB25 connector left over from the printer port version.
3. The Software GUI
I’ve been using Eclipse to in my Java projects. When I started to look at GUIs however Eclipse started to seem very primitive compared to the Microsoft Visual IDE (C++, C# etc.). It seemed that you actually had to place controls and components by manually writing the code with the co-ordinates. Fortunately I came across WindowBuilder which is a plug-in for Eclipse. Its free and as shown below lets you design your GUI graphically.
The actual software isn’t that complicated. The main class, USBTuner.java, is a JFrame extension which generates the GUI, and communicates with the USB buffer, and the DDS board.
The USBUtils.java class puts the USB buffer into BIT-BANG mode with dedicated outputs for clock, data, and control pins. Under control of the USB buffer, the DDSUtils.java class, resets and configures the DDS, and sets the DDS frequency. The DDS is programmed in the serial mode with one bit each for the serial data, clock, and control bit.
Operation is fairly straightforward. The default frequency is 100KHz. Frequency can be set in the text window at the top of the GUI. The resolution (MHz/KHz) is set by the button to the right of the text field. You can also scroll through the frequency range using the Coarse and Fine scroll. The resolution of the scroll bars is controlled by the Resolution radio buttons. The frequency is displayed in the top text field.
5.1 Java USB Interface
FTDI provides Windows drivers for the DLP_USB245M module, and these must be installed for the USB to work on a windows system. To work under Java, I use j2dxx, which is a Java interface port to FTDI’s drivers. During development with Eclipse, the j2dxx.jar file has to be in the java build path, so I’ve made a j2dxx library and placed it in C:\Program Files\java\j2dxx. j2dxx.jar calls a native library, J2DXX.dll, which I’ve paced in the root directory of the project folder (lib\\native\\windows).
5.2 Java Library Path
java.library.path is a system property used by Java to search for native libraries. In this application, the only native library is the USB interface J2DXX.dll. To set the java.library.path property under program control, the following code must be run in the main() routine before the application is started:
System.setProperty("java.library.path", "lib\\native\\windows"); Field fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" ); fieldSysPath.setAccessible( true ); fieldSysPath.set( null, null );
This will allow the program to be run from the program jar file as long as the native library is in a lib\native\windows sub-folder.
6. Source Code
The source code and native library can be downloaded here: USBTuner_source.zip
The executable jar file and native library can be downloaded here:USBTuner_Jar.zip.
Keep in mind that the FTDI drivers must be installed and that the native library folder must be in the same folder as the jar file.
It seems that every time I learn a new programming language, I wind up writing a USB DDS controller, so, bowing to the inevitable, I wrote one in Python. This actually might come in handy if I ever get around to experimenting with Raspberry Pi’s, or possibly a Python based SDR.
I’ve been able to control my DDS board with an Arduino controlled by the PC serial port under a Python GUI http://dbc-projects.net/arduino-dds-controller/. I was able to use most of the Python GUI for the USB version. The GUI screenshot is shown below:
1. Python and USB
Initially I’d hoped to be able to use the Virtual Comm Port (VCP) driver provided by FTDI to control the DLP-USB245M via the serial port. Unfortunately, after writing a few test scripts, I found that while I was able to write and read to the module, I was unable to configure it or write to the actual output pins. Additionally, after scouring the Internet, I found very little information on using VCP to control the DLP-USB245M, which is very suspicious.
The other option was to use the FTD2XX.dll library. This is the library that FTDI provides to implement VCP and provide more direct control over their devices. It was written in C so a wrapper for Python was required similar to the Java version (J2DXX.dll).
Back to the Internet.
It turns out that there are several versions of wrappers available. Some geared toward Linux, some toward Python 2.7. Some even require changes to the operating system. I finally settled on a Python 2.7 version found here: https://github.com/GeezerGeek/open_sld/blob/master/ftdi.py.
Its similar to a number of others out there, but I only had to make one small change to make it compatible with Python 3 (I changed “xrange” to “range”). The module is included in the zip file below.
2. Source Code
The source code, including the wrapper can be found here: pyDDS_USB_Source.zip
For convenience I keep the wrapper module in the same directory as the application. As with the Java version, the FT2XX.dll library must be installed in the Windows System32 directory.
The USB/DDS source code is very similar to the Arduino version in that it consists largely of a GUI to get and send the frequency data to the DDS. In the USB version however, a function to detect and initialize the DLP-USB245BM module has been added, along with a new class to configure and control the DDS.
The module initialization function looks for the DLP-USB245BM module among a list of FTDI devices and, if found gets a handle to the device.
The DDS control class (DDS_Utils()) is similar to the Java version and includes the following functions:
reset() – Sets the serial mode of the DDS, and clears residual data from the device
setFreq(freqVal) – Generates DDS the 40 bit frequency control word based on the device parameters, and writes the data to the DDS
writeDDSReg(freqWord) – Serially writes the 40 bit frequency control word to the DDS, along with the clock and control signals.