DAC analogWrite Limitation

Jake

Well-known member
I wanted a function generator to test some code and used the DAC and analogWrite function of the teensy 3.1. It is listed at https://forum.pjrc.com/threads/2507...Using-Teensy-3-1?highlight=function+generator. Note that this code can generate up to 6 harmonics. Also note that it normalized the output for a total amplitude of one. And as configured the second harmonic dominates.

While testing the output I found the sine wave was clipped. The link gives the details of the voltage and the analog value where this happens. With a 12 bit DAC, which should be able to output to 4096, the output gets clipped at 2733 and the maximum voltage is 2.151 volts. The variable analogBits is actually half the analog bits used and is an easy way to test this.

Is there something I am missing or is this a limitation of some sort?
 
So in your sketch, I collected the max value that is being passed to analogWrite() in loop(), and i get 2668.
So me thinks there is nothing wrong with the DAC, but your code is doing the clipping.
 
I wrote the code with analogBits as a variable to have the values being passed to the function analogWrite go between 0 and 2 * analogBits. When I change the value of analogBits to above 1352, then the sine wave as viewed on an oscilloscope connected to pin 14 starts being clipped. Since the DAC is 12 bit, I would expect analogBits should go up to 2047 so that the value passed to the DAC is between 0 and 4095 inclusive.

Since the maximum voltage I see is 2.151 volts then 2.151 V * 4095/2733 = 3.223 V, indicating that the delta voltage per DAC step is correct, but the output voltage is limited.
 
I can't reproduce your problem. I printed out micros() and the A14 values, and plotted ... nice sine curve, going 49 to 4046 with analogBits =2048. Then I hooked A14 to my cheap USB scope and i get an unclipped sine wave from 0 to 3.3v at 200Hz.

works for me.

You could check your DAC output with a meter, write 4095 to A14.
Or a simple square wave or sawtooth, or hook A14 to A0 and run 0 to 4095 and print out analogRead(A0);
 
Last edited:
Thank you very much for the response, if I learn anything more on my end I will let you know.
 
I'm way late on this, but I just ran into the same situation as Jake.

Jake, were you using AGND, or DGND? Works perfectly for me with DGND, but for AGND, full output will be 0 to ~2.19V.

To test, I ran the example script from https://www.pjrc.com/teensy/teensy31.html under '12 Bit Analog Output', and switched between AGND and GND:

Code:
// Simple DAC sine wave test on Teensy 3.1

float phase = 0.0;
float twopi = 3.14159 * 2;
elapsedMicros usec = 0;

void setup() {
  analogWriteResolution(12);
}

void loop() {
  float val = sin(phase) * 2000.0 + 2050.0;
  analogWrite(A14, (int)val);
  phase = phase + 0.02;
  if (phase >= twopi) phase = 0;
  while (usec < 500) ; // wait
  usec = usec - 500;
}
 
I just tested again with both GND and AGND and my peak voltage is 3.24 V. I cannot seem to duplicate the problem, and am using the same Teensy 3.1.

A second Teensy that did not have this problem continues to work well.
 
Back
Top