8 bit digital-to-analog converter


Well, yes, I know: you get an integrated digital-to-analog converter for less than one Euro (Microchip MCP4706).
But isn't it more fun do build one of your own?

Version 1

For a good DAC you need a lot of resistors with very high precision. That used to be a problem long time ago when standard resistors came with a tolerance of some 20 per cent. Nowadays you get large quantities of very precise resistors for a low price. But still you need "R" and "2R" types. No problem: for "2R" take two of them in series. This even will increase the precision as errors might compensate each other.

Locate the yellow and the blue box in the schematic above. We used two mini boards to solder the resistors to that boards in order to ease the construction. If you count them you will get 25 resistors of the same value. Which value? Whatever you can get between 10 kΩ an 100 kΩ. (Make sure the input resistance of your Opamp is much higher.)

As you can see (or guess?) the pins d2 to d9 are used to control the DAC.

If you don't use a rail-to-rail opamp (as I did) you have to reduce its input signal accordingly. You see the 4.7 kΩ and 10 kΩ resistors in the picture.

Version 2

Instead of getting the high-value resistors by a series you can obtain the low-value resistors by parallel. As said above, the values don't matter much, but they all must be the same. Actually, in this case you only need 23 resistors. In this example we used an Arduino NANO. To take the picture we removed the wires from the Arduino to the resistors all well as the SD card which was connected to d10-d13.

For those who want to see the schematic here it is:

Test the quality of the DAC

You can test the quality of what you just created by using the analog input of the Arduino itself, feeding back the DAC signal to "A0".

void setup() {
  //
  Serial.begin(9600);
  Serial.println("DAC-ADC-test");
  Serial.println("x\ty");
  DDRD = B11111100;
  DDRB = B00000011;
  for (int i = 0; i <=255; i++) {
    PORTD = i << 2;
    PORTB = i >> 6;
    delay(100);
    Serial.print(i);
    Serial.print("\t");
    Serial.println(analogRead(A0));
  }
  
}

void loop() {
}

Export the contents of the Serial terminal to your favourite spreadsheet software and you get

let it be displayed as a diagram

and the formula

gives you the breathtaking result of 0,9999992476. Can you expect any more?




contact: nji(at)gmx.de