Wednesday, May 15, 2013

Teensy Basics 6: R2R DAC Primer

This article assumes that you have read Teensy Basics 1 and Teensy Basics 2 and Teensy Basics 3 and Teensy Basics 4 and Teensy Basics 5.

It is easy to build a simple DAC that can be used with the Teensy. Using port manipulation, it is also possible to program data for the DAC.

We can use port manipulation to help with creating and controlling a DAC. A DAC is an digital to analog converter. It is a circuit or device that can take a digital control (i.e. discrete data or number in some form) as an input. The output is an analog voltage the corresponds to the value received.

A DAC can be used to generate audio and control waveforms. An example of a very simple, easy to build DAC is called an R2R ladder DAC. R2R = “resistance, 2 x resistance” because only two different values of resistors are needed.

Hardware Setup
The following is a diagram of an 8bit R2R ladder DAC. Every horizontal resistor should be “2R” e.g. 20K. Every vertical resistor should be “R” e.g. 10k. Each bit (0 – 7) is a digital connection, and is either HIGH or LOW.

Consider the Teensy input / output pins in terms of ports in conjunction with the above diagram:

We can then connect the DAC to the Teensy to the DAC in the following way:

Here is an example of a breadboard setup. The output (which is the blue line without a connection) should be connected to the signal of an audio input of a speaker system. The ground of the Teensy should be connected to the ground of an audio input of a speaker system.

Writing code for the DAC
The concept of how to program is straightforward. A value is written to the port. That value is converted to an analog voltage by the R2R ladder DAC. Each value is an instantaneous sample. Therefore, we need to be constantly writing new values to the DAC in order to generate a changing waveform. 

A value of 0 that is written to the DAC will result in an output of 0V. The maximum value allowed by the bit depth (15 if it is a 4-bit DAC, 255 if it is an 8-bit DAC) will result in an output of approximately 5V. Intermediate values are scaled accordingly. The bit depth will determine what voltage output is of a corresponding data input.


The DAC is 8bit (i.e. 0 – 255): 
A value of 0 = 0 / 255 = 0V
A value of 15 = 15 / 255 = 0.059 V

The DAC is 4 bit (i.e. 0 – 15):
A value of 0 = 0 / 15 = 0V
A value of 15 = 15 / 15 = 5V

The DAC can be programmed very easily. First, we need to set the direction of the pins to output in the setup() function: 

Then, it is simply a matter of looping code and telling the DAC what to do. For example, the following generates a square wave.

The following generates a sawtooth wave. 

The following generates a noise wave. 
The following generates a sine wave. 

The aim of this article is to provide a foundation for a DAC upon which can be built. Be aware that more complex code is needed to more complex sound, and that an output buffer is useful for many audio applications.