DDS is wrong

@WBahn: recent Projects article on this site, here.

@jjlarkin: yes, code is basic demo, but is there.

  • Frequency is a fixed constant. They are using a constant 60.0Hz in a float variable.

  • Phase is actually done in both a loop-counter variable and an accumulator that drives a delay timer. The time advances by a fixed 1/256 of a cycle or (360/256) degrees. Then, it emits the corresponding voltage. Then it waits for a 1/256 of a period.
The author derives the phase from that lookup table index. That 1/256 period wait is not particularly accurate (is low by about 1/624 cycle). Not how I would do it (or even accept from someone else), but phase accumulation technically is there.​

There was a recent thread on the software part of this topic. The later posts were getting pretty thorough, with some good looking code. Incorporating that work into the article would have been nice.

Below is the code that I downloaded from the article, presented for your convenience.
C:
const float freq = 60.0f;
const int   N    = 256;     // 256 samples/cycle
const uint32_t Ts_us = (uint32_t)llroundf(1e6f / (freq * N));

uint16_t lut[N]; // store the sine wave here

void setup() {
  analogWriteResolution(12);

  for (int i = 0; i < N; ++i){
      lut[i] = 2048 + (1000.0 * sin(2 * PI * i / N));
  }

}

void loop() {
  static uint32_t t_next = micros();
  for (int i = 0; i < N; ++i) {
    analogWrite(DAC0, lut[i]);  // output the sine wave values
    t_next += Ts_us;
    while ((int32_t)(micros() - t_next) < 0) { /* spin */ }
  }
}
 
Last edited:
Top