Deciding the frequency of DAC signal (and smoothening)

Hi there!

I am doing a project where I need a triangle signal with 500 Hz as the frequency. I am using the MCP4725 for this. So far I have been looking at the example code from the MCP4725 library.

#include <Wire.h>
#include <Adafruit_MCP4725.h>

Adafruit_MCP4725 dac;

void setup(void) {
  Serial.begin(9600);
  Serial.println("Hello!");

  dac.begin(0x60);
    
  Serial.println("Generating a triangle wave");
}

void loop(void) {
    uint32_t counter;
    // Run through the full 12-bit scale for a triangle wave
    for (counter = 0; counter < 4095; counter++)
    {
      dac.setVoltage(counter, false);
    }
    for (counter = 4095; counter > 0; counter--)
    {
      dac.setVoltage(counter, false);
    }
}

By increasing the counter steps in the for-loops I manage to get the frequency I want by trial and error. Sadly, this is making the signal very low resolution. To compensate for this I could make a filter, but what kind of filter would be the best fitting? I guess just want to remove the “stair case” steps, and not smooth out the top and bottom of the triangle signal.

Is there any other and better way to set the frequency of the signal?

For best signal stability you need a timer. For 500Hz and 2*4096 steps the timer frequency should be 4.096MHz, a bit too high for proper generation and handling from a 16MHz clock. The steps can be reduced to 2*4000, resulting in 4 clock ticks per step. Reducing the steps to 2*1000 or 2*500 may be better to handle, otherwise a controller with a higher clock frequency is recommended.

The output signal can be smoothed by a RC low pass filter.

Much better results can be achieved with an analog circuit: two constant current sources loading and unloading a capacitor, with some clock or controller switching both current sources on and off. This will yield a perfect triangle, without staircases and of the requested frequency.