AD9833
Arduino library for AD9833 function generator.
Install / Use
/learn @RobTillaart/AD9833README
AD9833
Arduino library for AD9833 function generator.
Description
Experimental
Arduino library for the AD9833 function (waveform) generator (12.5 MHz) The library supports both hardware SPI and software SPI.
The AD9833 is a signal generator that has two channels for frequency and two channels for the phase. These channels can be set separately to have maximum flexibility.
The AD9833 can generate three waveforms: sine, square (2x) and triangle. The frequency of the waves cover a range from 0 to 12.5 MHz. The step size for frequency is ~0.1 Hz (using 25 MHz reference clock).
The library also can set the phase of each wave from 0° to 360°. The step size for phase is ~0.1°.
| type | freq max | freq step | phase | phase step | Notes | |:--------:|:----------:|:-----------:|:--------:|:-----------:|:--------| | AD9833 | 12.5 MHz | 0.1 Hz | 0..360 | 0.1° |
Note: With an external 1 MHz clock smaller frequency steps down to 0.004 Hz. can be made. This is not tested yet.
Feedback as always is welcome.
Volume control
The AD9833 does not have volume (amplitude) control of the waveform generated. Switching off the output of the selected waveform by setting its frequency to zero can / does generate a popping sound / artefact.
In issue #23 this popping sound is investigated (thanks to 0x3B29 for testing). The solution found so far is to use a digital potentiometer, in this case a SPI based MCP 4151-104E/P, which is 10 kΩ in 256 steps (0..255). This digital potentiometer is used to lower the volume in multiple steps to zero, or in multiple steps to the maximum volume.
One problem is that the fade down of the potentiometer affected the ability of the AD9833 library to set the frequency immediately after. It looks like an interference between the settings of the SPI bus, as the two devices uses a different SPI-mode. The root cause is not found at the moment of writing. However a workaround exists by setting the frequency twice with a millisecond delay. That allowed to control the volume without a noticeable popping sound.
Further investigation is needed (although not part of this library sec).
Detailed discussion see - https://github.com/RobTillaart/AD9833/issues/23
Note: Ω = Alt-234 (UTF-8)
Compatibles ?
List of (partially) compatibles in the series, that might work (partially) with this library.
| type | freq max | freq step | wave forms | Notes | |:--------:|:----------:|:-----------:|:--------------------:|:--------| | AD9832 | 12.5 MHz | ? | SINE | | AD9833 | 12.5 MHz | 0.1 Hz | SINE TRANGLE SQUARE | for reference | AD9834 | 37.5 MHz | 0.28 Hz | SINE TRANGLE | has extra HW lines. | AD9835 | 50.0 MHz | 0.01 Hz | ?? | looks not compatible | AD9837 | 16.0 MHz | 0.06 Hz | SINE TRANGLE SQUARE | | AD9837 | 8.0 MHz | 0.06 Hz | SINE TRANGLE |
TODO: Investigations needed, verify table above (hardware and time needed).
If you have experience with one of the above "compatibles" and this library, please let me know by opening an issue. Probably these devices need dedicated libraries, possibly based on this one.
0.4.0 Breaking change
Version 0.4.0 introduced a breaking change to improve handling the SPI dependency. The user has to call SPI.begin() or equivalent before calling AD.begin(). Optionally the user can provide parameters to the SPI.begin(...)
0.2.0 breaking change
The version 0.2.0 has breaking changes in the interface. The essence is removal of ESP32 specific code from the library. This makes it possible to support the ESP32-S3 and other processors in the future. Also it makes the library a bit simpler to maintain.
Note: the parameters for pins have moved to the constructor.
Note: the order of the parameters of the software SPI constructor has changed in 0.2.0.
Related
- https://github.com/RobTillaart/AD985X
- https://github.com/RobTillaart/functionGenerator software waveform generator
- https://pages.mtu.edu/~suits/notefreqs.html frequency table for notes.
STM32 specific library
- https://github.com/gianni-carbone/STM32ad9833
Connection
Schema AD9833 chip, breakout will have different pins.
TOP VIEW
+-----------+
COMP | 1 10 | VOUT
VDD | 2 9 | A-GND
CAP / 2.5 V | 3 8 | FSYNC (select)
D-GND | 4 7 | SCLK
MCLK | 5 6 | SDATA
+-----------+
| PIN | Description | |:--------------|:---------------------| | COMP | DAC Bias Pin | | VDD | Power supply | | CAP / 2.5 V | (datasheet) | | D-GND | Digital Ground | | MCLK | Digital Clock Input | | SDATA | Serial Data In | | SCLK | Serial Clock In | | FSYNC | Select | | A-GND | Analog Ground | | VOUT | Analog Out |
Read the datasheet for detailed description of the pins.
Interface
#include "AD9833.h"
Constructor
If the selectPin is set to 255, external FSYNC is used. See section below.
- AD9833(uint8_t selectPin, SPIClassRP2040 * mySPI = &SPI) Constructor HW SPI.
- AD9833(uint8_t selectPin,SPIClass * mySPI = &SPI ) Constructor HW SPI
- AD9833(uint8_t selectPin, uint8_t dataPin, uint8_t clockPin) Constructor SW SPI.
- void begin() initializes SPI + internals.
- void reset() does a hardwareReset(), and sets the control register to B28 for the setFrequency()
- void hardwareReset() resets all registers to 0.
PowerMode
- bool setPowerMode(uint8_t mode = 0) set the powerMode.
Default is 0, wake up. So use
setPowerMode(0)to wake up the device. Returns false if mode is out of range. Details see datasheet. - uint8_t getPowerMode() returns current powerMode bits.
(table 14 datasheet)
| define name | powerMode | meaning | |:--------------------------:|:-----------:|:------------------------------| | AD9833_PWR_ON | 0 | no power saving | | AD9833_PWR_DISABLE_DAC | 1 | disable the on-chip DAC | | AD9833_PWR_DISABLE_CLOCK | 2 | disable internal MCLK clock | | AD9833_PWR_DISABLE_ALL | 3 | combination of mode 1 & 2 |
Waveform
- void setWave(uint8_t waveform)
- uint8_t getWave()
| waveform | define name | value | notes | |:-----------:|:-----------------:|:-------:|:--------| | No output | AD9833_OFF | 0 | | Sine | AD9833_SINE | 1 | | Square | AD9833_SQUARE1 | 2 | | Square2 | AD9833_SQUARE2 | 3 | half frequency | Triangle | AD9833_TRIANGLE | 4 |
UseRounding
Experimental => use with care!
The setFrequency() and setPhase() use rounding to maximize the accuracy of these functions. This is however not always what one needs e.g. if one wants to create harmonics without drift (see #19).
Therefor since 0.4.3 one can replace the rounding of the internal math with truncating which may do a better job. This is not tested thoroughly so use it with care.
- void setUseRounding(bool flag = true) Set the internal flag to use rounding The default value is true to be backwards compatible.
- bool getUseRounding() get the current status of the flag.
Note: reset() does not affect this flag.
Frequency
The default channel is set to 0, which makes the function calls simpler when only using one channel.
- float setFrequency(float freq, uint8_t channel = 0) SetFrequency sets the frequency and is limited by the MaxFrequency of 12.5 MHz. Returns the frequency set.
- float getFrequency(uint8_t channel = 0) returns the frequency set.
- float getMaxFrequency() returns the maximum frequency to set (convenience).
- void setFrequencyChannel(uint8_t channel) select the active frequency of channel (0 or 1).
Note: the frequency depends on the internal reference clock which is default 25 MHz. The library does not support other reference clocks yet.
Phase
Default channel is 0, which makes the function calls simpler when only using one channel.
- float setPhase(float phase, uint8_t channel = 0) setPhase sets the phase and normalizes the phase to 0° - 360°. So for example 405° becomes 45° and -23° becomes 337°. Returns the phase set in degrees.
- float getPhase(uint8_t channel = 0) returns the phase set in degrees.
- float getMaxPhase() returns the maximum phase to set (convenience).
- void setPhaseChannel(uint8_t channel) select the active phase channel (0 or 1).
Since 0.4.2 the library supports get and set the phase in radians.
- **float setP
Related Skills
node-connect
347.9kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
108.7kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
347.9kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
347.9kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
