Fast PWM-DAC library
Create a faster DAC with the FastPWMdac library
The library is essentially a wrapper around the TimerOne library by Paul Stoffregen.
For the fast ADC see HERE.
For the SAMD21 see this article: Fast PWM-DAC library for the SAMD21 and Arduino Zero.
The Arduino has no integrated DAC; to create analog output values, we have to use the standard Arduino function analogWrite(). This creates a so called PWM DAC, a PWM signal which has to be filtered with a low-pass filter. However, the standard analogWrite() function is very slow, don't use it anymore. The FastPWMdac library is much faster; these are the advantages:
- The PWM frequency is 31250Hz for 8-bit instead of 490Hz for the standard analogWrite().
- The resolution is 8-bit or 10-bit.
- The low pass filter uses a much smaller capacitor; no elco required anymore.
- The settling time is reduced which has great benefits when the DAC is used in a control loop.
Library downloads
The FastPWMdac is just an interface on the TimerOne library from Paul Stoffregen.
The library TimerOne.h has to be installed too. Paul Stoffregen has further improved the TimerOne library: it support many Arduino boards and is faster.
Download the TimerOne library HERE.
Download the FastPWMdac library at GitHub.
Using the PWM DAC
Output voltage
For a 5V supply voltage, the output voltage is:
Resolution 8bit: U = value * 5 / 255
Resolution 10bit: U = value * 5 / 1023
Resolution
The resolution can be set to 8bit or 10bit.
void init(byte _timer1PWMpin, byte resolution);
- For 8bit the PWM period is 32us / 31.25KHz.
- For 10bit the PWM period is 130us / 7.8Khz.
Output pins
For the Arduino Uno / ATmega328p, only the pins 9 or 10 can be used. For other Arduino boards see: TimerOne & TimerThree Libraries at www.pjrc.com.
Characteristics
With a resolution of 8 bit and a 10k / 100nF low pass filter, these are the characteristics:
- PWM frequency 31250Hz
- Max ripple voltage 40mV
- Cut-off frequency 160Hz
- Settling time 0% ... 90% 2.3ms
Fast PWM DAC example program
The example program creates a sawtooth at pin 9:
#include <FastPWMdac.h> const byte dacPin = 9; FastPWMdac fastPWMdac; void setup() { //analogWrite(dacPin1, 127); // analogWrite is SLOW with period 490Hz } void loop() { fastPWMdac.init(dacPin, 8); // initialization for 8 bit resolution for(int i=0; i<256; i++) // use byte because of 8 bit resolution { fastPWMdac.analogWrite8bit(i); // sawtooth output, period = 31.25Khz delay(1); } fastPWMdac.init(dacPin, 10); // initialization for 10 bit resolution for(int i=1023; i>=0; i--) { fastPWMdac.analogWrite10bit(i); // sawtooth output, period = 7.8Khz delay(1); } }