nmaitland / AD9833

Arduino library for AD9833 function generator.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Arduino CI Arduino-lint JSON check GitHub issues

License: MIT GitHub release PlatformIO Registry

AD9833

Arduino library for AD9833 function generator.

Description

Experimental library for the AD9833 function (waveform) generator. The library supports both hardware SPI and software SPI.

TODO: test with hardware.

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 give 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 0.004 Hz. can be made. This is not tested yet.

Compatibles ??

List of (partially) compatibles in the series, that might work (partially) with this library.

TODO: Investigations needed, verify table below.

type freq max freq step wave forms Notes
AD9832 12.5 MHz SI
AD9833 12.5 MHz 0.1 Hz SI TR SQ for reference
AD9834 37.5 MHz 0.28 Hz SI TR has extra HW lines.
AD9835 50.0 MHz 0.01 Hz ?? looks not compatible
AD9837 16.0 MHz 0.06 Hz SI TR SQ
AD9837 8.0 MHz 0.06 Hz SI TR

If you have experience with one of the above "compatibles" and this library, please let me know by opening an issue. Probably they need a dedicated library based on this one.

Related

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 datasheet for detailed description of the pins.

Interface

#include "AD9833.h"

Constructor

  • AD9833() 12.5 MHz signal generator
  • void begin(uint8_t selectPin, uint8_t dataPin = 0, uint8_t clockPin = 0) For hardware SPI only use the first two parameters, for SW SPI you need to define the data and clock pin too.
    • selectPin = chip select. If the selectPin is set to 255, external FSYNC is used. See section below
  • void begin(uint8_t selectPin, SPIClass * spi) For hardware SPI only, to select a specific hardware SPI port e.g. SPI2. If the selectPin is set to 255, external FSYNC is used. See section below
  • void reset() does a hardwareReset(), and sets the control register to B28 for the setFrequency()
  • void hardwareReset() resets all registers to 0.
  • 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.
powerMode meaning
0 no power saving
1 powers down the on-chip DAC
2 disable internal MCLK clock
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

Frequency

Default channel is 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 selectFreqChannel(uint8_t channel) select the active frequency 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 is limited to 0° - 360°. Returns the phase set.
  • float getPhase(uint8_t channel = 0) returns the phase set.
  • float getMaxPhase() returns the maximum phase to set (convenience).
  • void selectPhaseChannel(uint8_t channel) select the active phase channel (0 or 1).

Hardware SPI

To be used only if one needs a specific speed.

  • void setSPIspeed(uint32_t speed) set SPI transfer rate.
  • uint32_t getSPIspeed() returns SPI transfer rate.
  • bool usesHWSPI() returns true if HW SPI is used.

ESP32 specific

  • void selectHSPI() in case hardware SPI, the ESP32 has two options HSPI and VSPI.
  • void selectVSPI() see above.
  • bool usesHSPI() returns true if HSPI is used.
  • bool usesVSPI() returns true if VSPI is used.

The selectVSPI() or the selectHSPI() needs to be called BEFORE the begin() function.

  • void setGPIOpins(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t select) to overrule ESP32 default hardware pins (to be tested). Needs to be called AFTER the begin() function.

In code, something like this (TODO write example)

void setup()
{
  freqGen.selectVSPI();
  freqGen.begin(15);
  freqGen.setGPIOpins(CLK, MISO, MOSI, SELECT);  // SELECT should match the parameter of begin()
  ...
}

Low level API

Use at your own risk, please read the datasheet carefully.

Since version 0.1.1 writing to the registers is made public. By using the low level API to access the registers directly, one has maximum control over the AD9833 device. Especially frequency setting is improved as the float setFrequency() does not have the 28 bits precision of the register.

  • void writeControlRegister(uint16_t value) see datasheet
  • void writeFreqRegister(uint8_t reg, uint32_t freq) reg = 0 or 1, freq = 0 .. 134217728
  • void writePhaseRegister(uint8_t reg, uint16_t value) reg = 0 or 1, freq = 0 .. 4095

External FSYNC

Experimental => use with care!

If in the begin() function the selectPin is set to 255 external FSYNC is used. This allows to control e.g many AD9833 devices in parallel, with multi-IO chips. Think of the SPI based MCP23S08/17, or the I2C based PCF8574/75.

The advantage is that one can control many (e.g. 16 devices) with a minimum of IO lines.

The disadvantage is that you need to add extra code lines to set / clear the FSYNC line(s). Furthermore one should know that using this "external FSYNC" is slower than direct control with MCU pins from within the library.

Pin count wise this concept is only interesting for 3 or more AD9833 devices.

Code wise you need to "manual" control the FSYNC.

  setFsyncLow(5);        //  select device 5
  AD.setFrequency(440);  //  set a new frequency
  setFsyncHigh(5);       //  update the setting.

As this implementation is experimental, the interface might change in the future.

Future

Must

  • update documentation

Should

  • investigate HLB mode versus B28 mode
  • investigate external clock
  • investigate timing (response time)
    • change freq
    • change channels etc
  • test on ESP32 (3V3)

Could

  • extend unit tests
  • add examples
    • for ESP32 HWSPI interface
    • use of channels (freq & phase)
    • multi device example (array?)
  • move code to .cpp
  • solve MAGIC numbers (defaults)
  • setting half freq register for performance mode.
    • HLB mode
  • extend performance measurements
  • investigate compatibility AD9834 a.o.

Wont

Support

If you appreciate my libraries, you can support the development and maintenance. Improve the quality of the libraries by providing issues and Pull Requests, or donate through PayPal or GitHub sponsors.

Thank you,

About

Arduino library for AD9833 function generator.

License:MIT License


Languages

Language:C++ 100.0%