I notice there are 2 DAC pins on my Wio Terminal 40 pin header, DAC0 and DAC1, on pins 11 and 26, respectively. I presume these can be coded for audio playout but I can’t find any howTwos or tutorials? According to stuff I’ve seen about the SAMD 51, these can also function as ADCs, as well. (??)
Has anybody got any example code or successfully got audio out of their Wio using these pins? Anybody know of an ArduinoIDE-friendly way of programming this or of any tutorials?
OK, gotta laugh, in my impatience to wait for an answer, I solved the riddle
The following code puts a 1kHz square wave tone on DAC0, and in inverted phase on DAC1.
uint32_t sqrWave = 0; // Create a 32 bit unsigned integer
void setup() {
dacConfigure(); // Zero the DACs to prevent noise
}
void loop() { // main loop
if(sqrWave == 0){
sqrWave = 65535; // take the square wave to maximum
} else {
sqrWave = 0; // take the square wave to minimum
}
dacWrite(sqrWave, 65535 - sqrWave); // Reverse phase between left and right channels
delay(1); // 1 millisecond delay makes the tone approx. 1kHz
}
void dacConfigure(){ // Zero the DAC
analogWriteResolution(16); // Set the resolution to 16 bits (CD quality)
analogWrite(DAC0, 0); // Zero the left channel
analogWrite(DAC1, 0); // Zero the right channel
}
void dacWrite(uint32_t lSample, uint32_t rSample){ // Write samples to DACs
analogWrite(DAC0, lSample); // Write left sample to left channel
analogWrite(DAC1, rSample); // Write right sample to right channel
}
And I thought it was going to be hard!
Posted before I got a speaker on it. Might be the impedance, but I suspect I have more reading to do.
Any help still appreciated. The DAC library for the Maker and Zero doesn’t work, either BTW. “Unable to build for board Wio Terminal” from memory.
Doing all my own work on this, here, but others might find it useful…
If we analogWrite to the DAC at greater than its bitrate (at least I think that’s what was causing silence, despite having a clear set of numbers being fed to it, as reported by the serial monitor), I didn’t get any output until I bitcrushed the 16 bit numbers down to 12 bit using…
#include <Chrono.h> // uses the Chrono library, just cheating to get tighter timing
#include <math.h> // math library for sinf (floating point sin)
Chrono sampleTimer(Chrono::MICROS); // instantiate class of Chrono to time sample output
float smplRate = 44100.0; // deault playback sample rate (44.1kHz)
float smplWvLn = 1000000 / smplRate; // sample rate wavelength in uS
float otPtFreq = 824.1; // sets output frequency in Hz
float otPtWvLn = 1000000 / otPtFreq; // output wavelength in uS
float inc = 2 * PI * smplWvLn / otPtWvLn; // radians increment per sample
float i = 0.0; // increment counter
void setup() {
analogWriteResolution(12); // set output bitrate for inbuilt DACs
sampleTimer.start(); // start sampleTimer
}
void loop(){
if(sampleTimer.hasPassed(smplWvLn)){ // the sampleTimer returns true
sampleTimer.restart(); // restart the timer
unsigned long out = sinusoid(); // call for next sample from the wavetable
analogWrite(DAC0,out >> 4); // write sample to DAC0
analogWrite(DAC1,out >> 4); // write sample to DAC1
}
}
float sinusoid(){
if(i < 2 * PI){
float r = 2046.5 + 2048.0 * sinf(i); scales sample to 12 bit amplitude (0 to 4095)
i += inc;
return r;
} else if (i >= 2 * PI){
i = 0;
}
}
I’ve actually managed to give it ultra-low frequencies and I’ve had some awesome sinewaves on my 'scope!