This library is an improvement of the standard Arduino function analogWrite(). The analogRead() is also made much faster, see this article: Fast analogRead / 10-bit ADC for the Arduino Uno and Zero.
Download
Download the library from GitHub, you will find here program examples too.
These libraries should be installed also:
The library is easy to use; the following code creates a 10bit DAC on pin 5 of the Arduino Zero and sets output to 1.65V:
#include <avdweb_SAMDpwmDAC.h>
SAMDpwmDAC myDAC = SAMDpwmDAC(3, 10, 5);
myDAC.write(512); // 512/1024 * 3.3V = 1.65V
Due to the higher PWM frequency, the RC low-pass filter has a shorter settling time. The PWM frequency depends on the resolution. We can calculate the PWM frequency as follows:
PWM frequency = 48MHz / 2^resoluton
For example, for a resolution of 10bit, the PWM frequency is 47kHz. Note that with analogWrite, at the same resolution, the frequency is just 732Hz.
Suppose that the RC low-pass filter has an allowed ripple of 0.1% at 1.65V output voltage. The PWM-DAC resolution is 10bit, so the frequency is 47kHz. With this online tool we can calculate the low-pass filter:
This RC filter is obtained by using the online tool:
There is only needed a small RC filter at the high-speed DAC:
Fast PWM-DAC library for the SAMD21
For analogWrite(), the settling time is much longer:
The library is straightforward since the resolution is set during initialisation. We can set any resolution from 1 ... 16bit, although a resolution of 1 ... 7bit is of little use.
With analogWrite(), the resolution has to be set first with analogWriteResolution(), so this requires two steps. This resolution than will remain the same for the rest of the program. In program technical point of view, this is an undesirable situation. How do we know the resolution at any moment?
The SAMD21 has 6 timers, so we can use maximal 6 different PWM DACs at the same time. To organise this, it is useful that the timer number can be set, so there is no doubt about it. This table can be used to determine which pins are available for each timer:
SAM15x15 and Arduino Zero Timer/Counter pins
As you can see, the distribution of pins is rather messy.
The disadvantage of analogWrite() is that we don't know the timer number at initialisation:
analogWrite(pin, value);
That makes it harder to find out how many PWM DACs are left and which pins are free.
The timers 0, 1 and 2 are not implemented yet. I hope that other people want to do this on GitHub.