Direct Digital Synthesizer (DDS) (Part 5)
Part 1, 2, 3, 4, 5, 6, 7, 8, 9
This is an update in the status of PlainDDS library. After revising the code and trying some suggestions made by Arduinoos visitors, I performed some intensive tests from which I have been able to draw some conclusions:
– The bits setting must be executed as quickly as possible in order to keep the interrupt execution as short as possible and consequently avoid signal disturbances. It sounds trivial,but the goal is not so easy to achieve.
– The best to achieve this is to use a dedicated port: preferably PORTB, PORTC is alright too, and PORTD if you do not use the Rx Tx functions (In other words, the Serial library functions)
– Under these conditions, the start bit setting does not make sense and has been removed.
Signal stability can be optionally improved (DDS Start function argument) by disabling Timer0 and Timer2. Care must be taken after using this option, because the timing functions such as delay or millis() will no longer work. Timer0 and Timer2 are enabled again with their original settings on completion of the DDS Stop function. The frequency ranges from 1 Hz to 16 kHz
but you can push it at higher values after some fine tuning of the final stage capacitor, to the cost of some signal attenuation.
In any way, the accuracy is quite remarkable, or say, far enough satisfactory for an prototype application.
The code is now serialized (date code) and it comes with a user manual which actual content is as follows.
Copyright (C) 2012 Didier Longueville This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. PlainDDS library contains a set of functions which are dedicated to signal generation. Principle of use: - Initialize generator - Run generator - Change parameters on line - Release generator Waves can be: - predefined - user defined Hardware: - the R2R ladder must be connected to pins 0 to n from any port. Check compatibility (e.g. PORTD) --------------------------------------------------------------------------------------------------- CustomData(index) --------------------------------------------------------------------------------------------------- with: - index: custom data index returns: - custom data value from the specified index comments: - Data is stored in EEPROM --------------------------------------------------------------------------------------------------- CustomData(index, value) --------------------------------------------------------------------------------------------------- with: - index: custom data index - value: custom data value returns: - custom data value from the specified index comments: - none --------------------------------------------------------------------------------------------------- CustomData(index, value, maxValue) --------------------------------------------------------------------------------------------------- with: - index: custom data index - value: custom data value - maxValue: maximum custom data value; the recorded data shall be normalized to maxValue returns: - normalized custom data value from the specified index comments: - none --------------------------------------------------------------------------------------------------- Frequency(_frequency) --------------------------------------------------------------------------------------------------- with: - _frequency from 1 to 16kHz (in integer format) returns: - nothing comments: - none --------------------------------------------------------------------------------------------------- InitializeDDS(bits, port) --------------------------------------------------------------------------------------------------- Initialize DDS generator with: - bits: Number of data bits - port: any port (typically B, C or D) returns: - nothing comments: - none --------------------------------------------------------------------------------------------------- ReleaseDDS --------------------------------------------------------------------------------------------------- Release generator with: - nothing returns: - nothing comments: - Stop generator, free memory, release timer2 --------------------------------------------------------------------------------------------------- Start --------------------------------------------------------------------------------------------------- Starts the generator with: - nothing returns: - nothing comments: - Runs until Stop function is run --------------------------------------------------------------------------------------------------- Start(highStabMode) --------------------------------------------------------------------------------------------------- Starts the generator with: - highStabMode: boolean, 1 disables timer 0 and timer 1. These timers are restored on completion of the stop function. returns: - nothing comments: - Runs until Stop function is run - Timer0 is used in Arduino.h base functions for timing functions (e.g. delay, millis). Disabling timer0 will cancel these functions --------------------------------------------------------------------------------------------------- StandByValue(_standbyValue) --------------------------------------------------------------------------------------------------- Sets the stand by value with: - _standbyValue: any digital value ranging fro 0 to 255 returns: - nothing comments: - Applies when the generator is stopped --------------------------------------------------------------------------------------------------- Stop --------------------------------------------------------------------------------------------------- Stops the generator with: - nothing returns: - nothing comments: - Restart generator with the Start function - Output is set according to StandByValue --------------------------------------------------------------------------------------------------- WaveType(_waveStyle) --------------------------------------------------------------------------------------------------- Set the output wave type with: - _waveStyle as per constants (DDS_WAV_TYP_x) returns: - nothing comments: - The custom data are read from the EEPROM. Fill in the EEPROM prior to using this mode --------------------------------------------------------------------------------------------------- Constants --------------------------------------------------------------------------------------------------- Wave types: DDS_WAV_TYP_FLAT DDS_WAV_TYP_SINE DDS_WAV_TYP_SQUARE DDS_WAV_TYP_TRIANGLE DDS_WAV_TYP_SAW_TOO_POS_SLP DDS_WAV_TYP_SAW_TOO_NEG_SLP DDS_WAV_TYP_RANDOM DDS_WAV_TYP_CUSTOM
As you can read, PlainDDS contains some functions which will help the user to set custom values directly in the appropriate vector.
The code below is extracted from the eample sketch and shows how easy it is to program PlainDDS
/* InitializeDDS DDS engine : Start pin, bits, port */ DDS.InitializeDDS(bits, port); DDS.StandByValue((1 << bits) >> 1); for (uint8_t j = 1; j < 6; j++) { /* Generate various types of waves */ DDS.WaveType(j); DDS.Start(1); /* Sweep frequencies */ for (uint16_t i = 1; i <= 16000; i++) { DDS.Frequency(i); } DDS.Stop(); /* Stop generator and stand by output value */ } DDS.ReleaseDDS();
The libray, its user manual and a example skecth are available on request.