Hi I'm new to the Teensy and hardware in general. I'm trying synthesize simple waveforms from the Teensy 3.1 DAC pin. My constraints are pretty simple: audio range output with standard/common sample rates(44.1kHz)
For the moment, I'm only interested in sinewaves. I can create them without a problem, but I can't get the Teensy to output at the expected frequency. I think the problem is that the Teensy has trouble with the 44100 Hz sample rate. In my code below, I'm trying to output a 2000Hz sinewave, but when analyzed through an oscope, the frequency is measured at something around 909Hz; less than half the frequency.
Please see my code below:
each iteration of loop() outputs a sample. And my sample rate is determined by the value of an elaspedMicros object, the code waits until enough time has time has passed(22 microseconds for a 44.1kHz sample rate)
I experimented by replacing the sinewave output code with simple alternating high voltage, and low voltage values(a square wave), and when analyzed, I successfully measured a consistent and expected sample rate (each sample lasted about 22 microseconds). Yet when outputting the sinewave, it seems as though each sample last about twice that length(about 50 microseconds per sample), and some samples last longer than others as well.
My questions:
Does anybody know if the use of an elaspedMicros object is the right way to manage a sample rate (I got this technique from an example on the pjrc.com Teensy 3.1 page)?
Is it possible that a software/memory buffer would help?
High frequencies also produce a a lot of stepping(the voltage gaps between samples) in the output. Does anybody know the right way to smooth this out?
Thanks!
For the moment, I'm only interested in sinewaves. I can create them without a problem, but I can't get the Teensy to output at the expected frequency. I think the problem is that the Teensy has trouble with the 44100 Hz sample rate. In my code below, I'm trying to output a 2000Hz sinewave, but when analyzed through an oscope, the frequency is measured at something around 909Hz; less than half the frequency.
Please see my code below:
each iteration of loop() outputs a sample. And my sample rate is determined by the value of an elaspedMicros object, the code waits until enough time has time has passed(22 microseconds for a 44.1kHz sample rate)
Code:
float phase = 0.0;
float twopi = 3.14159 * 2;
float freq = 2000; // output frequency, in Hz
float sr = 44100; // sample rate
float increment; // To be added to phase during each iteration of loop
int srDelay; // time delay(in microseconds) between samples. Determines sample rate
elapsedMicros usec = 0; // type auto increases as time elapses.
// Calcuate increment for a given output frequency, and sample rate
float updateIncrement(float frequency, float sampleRate) {
return twopi/(sampleRate/frequency);
}
// Calculate time delay between samples
float updateSRDelay(int sampleRate) { return (1.0/sr)*1000000.0; }
void setup() {
analogWriteResolution(12);
increment = updateIncrement(freq, sr);
srDelay = updateSRDelay(sr);
}
void loop() {
float val = sin(phase) * 2000.0 + 2047.0; // maps sin() output range[-1,1] to unsigned 12bit range [0,4095]
analogWrite(A14, (int)val); // output sample
phase += increment;
if (phase >= twopi) // full cycle completed
phase = 0; // reset
while (usec < srDelay); // wait inbetween samples
usec = usec - srDelay;
}
I experimented by replacing the sinewave output code with simple alternating high voltage, and low voltage values(a square wave), and when analyzed, I successfully measured a consistent and expected sample rate (each sample lasted about 22 microseconds). Yet when outputting the sinewave, it seems as though each sample last about twice that length(about 50 microseconds per sample), and some samples last longer than others as well.
My questions:
Does anybody know if the use of an elaspedMicros object is the right way to manage a sample rate (I got this technique from an example on the pjrc.com Teensy 3.1 page)?
Is it possible that a software/memory buffer would help?
High frequencies also produce a a lot of stepping(the voltage gaps between samples) in the output. Does anybody know the right way to smooth this out?
Thanks!
Last edited: