Go Down

Topic: Which DAC should I use? (Read 4269 times) previous topic - next topic

capicoso

Hello. I'm designing a MIDI to CV converter with Arduino. Arduino receives 0-127 values of notes, and along with the DAC and opamps it generates a DC voltage according to each note, in a 1v/oct scale, this is 83,333mV each note. Right now the MIDI part doesn't matter.
I'm using a DAC0808 which is 8bit. I have it connected like this but using 15v ref instead of 10v http://ecee.colorado.edu/~ecen4618/dac0808d.gif but I used  4.7k instead of 5k. I'm just starting with DACs so there are things I don't understand.
 Well, i'm just using 7bit of the converter, then the Vo goes to an opamp to scale it to 1v/oct.
 I write the DAC like this:
Code: [Select]
for(byte nBit = 0; nBit < 8; nBit++){
    bitNota = bitRead(nota, nBit);
    digitalWrite(nBit, bitNota);

  }

I just read each bit of a byte, and write it to the DAC. Every 12 notes(octave) I should have 1V. At the output of the DAC i scale it to 1v/oct like this http://musicfromouterspace.com/analogsynth_new/THE_CAVE/MIDI%20to%20CV%20Old%20Design%20I/midi2cv_files/D2Aconvert.gif but without the offset adjustment.

If I look at my DVM, it looks like it's ok, first octave is 0,996V, second octave 1,99V, third 3V and so on. But when I look at the smaller steps between each semitone they're not scaled at 83,33mV. They're close, pretty close but just not there. And a very small diference is noticeable when I connect it to a VCO.

I read here http://obsoletetechnology.wordpress.com/projects/midi-cvgate-converter/ that he had the same problem, but he shifted all the bits one to the left, this is, leaving the LSB at 0, this however would double the scale, so I changed the op amp gain to atenuate to 1v/oct scale. It was better I think.
 Now the questions
is it just that the DAC isn't precise enough? Why would a 12bit DAC be better?(i read that by shifting all the bits to the left and leaving the 4 lsb would make it more precise)

maybe the scale goes off at my op amp scaling? How can I generate 83,33mV steps directly with the arduino and the DAC?

I can get some AD7541AKN 12bit, would it be better? Or I also can get a MCP4922 which is a 12bit dual DAC, and i've seen it used a lot in MIDI-CV devices

is it smart to use a 12bit DAC when I only need 7bit?

What is a good Vref to use? Apart from being stable, supposing I only need a range from 0-5v, should I use a ref of 5v or 10v?

lot of questions... i'm just starting with DACs and reading a lot, but i'm still confused.

thanks

raschemmel

I assume you are not in the USA so just for clarification,
this

Quote
this is 83,333mV each note. 
means 83.333 mV /note, correct ?
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

raschemmel

#2
Nov 27, 2014, 10:49 pm Last Edit: Nov 28, 2014, 08:04 pm by raschemmel
Quote
Why would a 12bit DAC be better?  
Because a DAC outputs a STAIR-STEP waveform with discrete voltages for each level and the higher the
resolution, the closer you can get to matching the MIDI standard you are imposing on yourself because
the voltage difference (increments) are smaller. What you have now is a DAC that is generating voltages that are IN BETWEEN the ones you need.  You need better resolution.


I had basically the same resolution problem when I was building my Junior Class project at DeVry's BSEET
course in Pomona, Ca in '94.

The project objective was build and program a uC based clock that has a speaker, and amplifier and some
form of display (7-segment LED or VFD or LCD).

The minimum requirement for a passing grade was a clock that makes a 'Tick' sound every second and
plays a 'musical' tune consisting of a minimum of 6 or 8 notes , lasting a minimum of 10 seconds.

One of my classmates was also a technician with many years of hands-on electronic experience (everyone
else was just out of HS and had never seen a resistor before, let alone touched one) and we hung out
together and tried to compete with each other. i made up my mind i was going to one-up him on this
project so I told him I was going to make my clock play the entire theme from STAR TREK DEEP SPACE 9

STAR TREK DEEP SPACE 9 THEME

ALL 1 minute , 35 seconds of it , IN KEY !

Quote
"IN KEY ! "
This was an important detail because my classmate and I both knew (we doubt anyone else in the class
knew) , the MUSIC consists of NOTES, not SOUNDS. It IS possible to create a combination of sounds
and call it music, but to be defined as MUSIC, it must consist of notes from the 88 note equally tempered
scale and must be either FLAT, SHARP or WHOLE.

88-NOTE EQUALLY TEMPERED MUSIC SCALE


If you look at the frequencies you see that at the bottom of the scale the difference in frequency is minimal but as you go up higher in the scale the difference (in Hz) between the notes increases.

In retrospect, if I had known what I was getting myself into when I added "IN KEY", I probably would
not have said it. Bottom line is that the crystal frequency of the HEATHKIT ET-3400  uProcessor Trainer
was too low (4 Mhz) to get the resolution I needed to make the music sound like the theme music.
I had to use 16-bit registers for the delay loops because some of those notes are held pretty long. When
I first tried it the notes sounded "sour" because they were OFF-frequency. I finally had to hack the
trainer and swap out the 4 Mhz crystal with a 6 Mhz crystal , a trick many know by the term "over-clocking". This gave me enough resolution to make the notes sound correct to anyone but a professional
musician with a trained ear. Someone who can walk in a room and say immediately "that piano is out of tune".  

What you are doing is analogous because you are too are trying to translate S/W into a some kind of
signal representing notes but instead of generating frequencies like I did, you are generating voltages
and they are not correct because the resolution is way too low. You need at least a 12-bit DAC

MCP4725

If you programmed your circuit to play the same DS-9 THEME it too would sound sour the first time.
You need to take it up a few notches to at least 12-bits.

EPILOG
On Presentation Day , my classmates who had heard my circuit working (I used a 5W amplifier and a
6" speaker instead of a 1/2W amplifier and 1" speaker like everyone else used, and a scrolling VFD
instead of a 7-segment display. It played the entire 1 minute 35 seconds) asked the Professor to
grade my project first so everyone could watch. The entire lab class gathered around while the Professor
listened to the music. He was a serious Chinese gentleman and gave no indication he was impressed.
He simply listened and watched the time scrolling and after 20 seconds wrote down A+ and said "NEXT !"
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

ChilliTronix

@raschemmel, It's a shame the Karma thing isn't working, after reading that, I would have added one.

Interesting story.

Of course, people don't know that the ear is a sort of partly digital spectrum analyser.

raschemmel

#4
Nov 28, 2014, 12:09 am Last Edit: Nov 28, 2014, 12:49 am by raschemmel
Thank you. You should have been there.  :smiley-mr-green:

Actually, the Karma thing IS working. I clicked you avatar and it showed your profile with a Karma of 12. I then clicked where is says "Add Karma" under you avatar and nothing appeared to happen but when I
clicked your avatar again it showed your profile with a karma of 13.

(13-12)=1 =>conclusion, the karma thing is working.
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

ChilliTronix

Ah so it is... :) Your karma is now 108.

raschemmel

What goes around comes around... :smiley-wink:
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

avr_fred

#7
Nov 28, 2014, 04:01 am Last Edit: Nov 28, 2014, 04:04 am by avr_fred
We now return you to our regular programming... :-[

It all boils down to the accuracy of the dac. While changing devices to a higher resolution dac intuitively appears to help, it may not if the overall accuracy is less since you are not increasing your input resolution. So, you've got to research the data sheets and understand what they're telling you.

The overall accuracy of the dac0808 is +/- 0.19%.

The overall accuracy of the ad7541akn is +/- 0.012% which is almost a 16:1 improvement. This is with using the same 7 bits of input resolution since that is all you have and that isn't going to change, only the accuracy of the part we apply those 7 bits to...

Do the individual steps of your dac0808 meet the  +/- 0.19% spec? If so, then then changing to a dac with better specs will help the output voltage accuracy. If it does not, there are cases where a dac can be missing bits and will have larger than expected output voltage swings. These are defective units of course but they can sometimes be difficult to find, unless you can create an output ramp and either watch the output on a scope or measure each and every step in its output, a rather mind numbing task.

capicoso

Thanks for the complete answers, and interesting stories  :)

First of all, I meant 83.33mV yes, 1V/12

Now I think I underestand a a bit more. Also, depending on the range output I want the resolution will be enough or not. I want a 0-5v range, so with 12 bit I would have 12mV steps?

I'm now wondering if I should use ad7541akn or MCP4922. It seems ad7541 is more precise? But it's only one DAC, and the MCP4922 is double and also SPI...

avr_fred

The formula for the output voltage resolution:  1 / (number of bits)^2 * dac ref voltage.

For example, a 12 bit dac with a 5 volt ref would have a minimum voltage step (1 bit) would be: 1/4096*5 = 0.0012 volts (1.2 millivolts)

It is important to understand that a 12 bit dac that has a 1% full scale error is worse than an 8 bit dac with 0.1% fs error. If you have only 7 bits of input resolution, the 8 bit part is a better choice. If you have more, you'll have do the math to see if the 12 bit part is a better choice in terms of total system error.

Some dac's are rated in "lsb" error terms which is "least significant bit" and in those cases, you have to look at the bit count to arrive at an error in terms of full scale error.

Most importantly, output resolution will never be greater than resolution of the input bit count and DAC accuracy is important and should not be ignored.


raschemmel

#10
Nov 28, 2014, 07:11 am Last Edit: Nov 28, 2014, 04:58 pm by raschemmel
Have you considered trying a different s/w approach. If you want EXACTLY 83.33 mV per note then maybe what you need to do is scrap your current approach and use an array of 128 values , each one containing the count to send to a 12 bit DAC , to get MIDI_count * 83.33 mV +/- 1.2 mV. The MIDI count becomes the index to access the array. A count of 35 will give you (35*0.083333= 2.916655 V /0.0012=2431, the value you send to the DAC which , while not exact, is within 550 uV (approximately half a millivolt) of the target value. Alternately, you can do the conversion on the fly.


Note: In case everyone else isn't aware, the OP said he receives a value of 0 -127 and that each count
should represent 83.33 mV. (0.083333 V)
Let count = 127
                 127 * 0.083333 = 10.583291 V

                 which as everyone knows is beyond the 0 -5 V output range of the DAC connected to the
                 arduino . I believe the OP did mention an amplifier.


Quote
Every 12 notes(octave) I should have 1V
Quote
then the Vo goes to an opamp to scale it to 1v/oct.  
For this example it is assumed the
                 "amplifier" is an op amp gain of 2 non-inverting amplifier to convert the values to the
                 voltage the OP needs. (0 to 10.583 V for a count of 0 to 127)


START
step-1: receive 0 - 127 count from MIDI
step-2: Multiply count by 0.083333 to convert to voltage
step-3: Divide value by mV/ per count value of the 12-bit DAC you are going to use.
         
       MIDI_count   = 0; // initialize variable
         float  note_increment_val = 0.083333;

      MIDI_count = 100; // assign 100 to MIDI_count.

                         
       MIDI_count *  note_increment_val = 100*  float target_val =8.3333.


                           float target_val = 8.3333;

                           int amplifier_gain = 2;

                         Calculated value for mV/step for 12-DAC:

                               Step-4: calculate max count for 12-bits
                                         212=4096.

                            Step-5: Divide 5V by the maximum count to get the per count voltage:
                                         5V/4096=0.00122070
                                         float per_count_voltage =0.00122070;

                            Step-6: Calculate number of counts for 12 bit DAC to output target value
                                         calculated at beginning of step-3 (8.3333 V)
                                        float dac_target_count = 0;  //dac_target_count is the count to send to
                                         generate the value before amplification by Gain of 2 op amp
                                         non-inverting instrumentation  amplifier:
                                 
            target_val /amplifier_ gain/per_count_voltage=3413.3284181
           
            int dac_target_count = 3413.3284181;

            int dac_target_count now contains integer 3413. // converted by assigning a float to an int.
             this truncates the float instead of rounding it. I don't know how to round it. You'll have to
                 research that topic.
                float target_val = dac_target_count * per_count_voltage= 3413*0.00122070 =4.1666499.
             float dac_target_val =  4.1666499 V.
               

             dac_target_val * amplifier_gain = 4.1666499 * 2 =  8.3333 V (target_val)

              which, if you still recall after the above is the initial  target_val  (8.3333 V)

             The 12-bit DAC outputs the  dac_target_val 4.1666499.
             The op amp gain of 2 non-inverting amplifier amplifies to 8.3333 V (the target value)

           
                                     
                                         
                                   
                                                               
                           
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

capicoso

Wow, amazing, I'll have to re-read that a few times though

Yes, I have a quad op-amp at the output, like you said, and use a third one for portamento. But maybe I won't use the full 0-127 range, more like 36-92 or 36-104. Then I have a multiturn trimpot at the opamp gain to fine tune.

I'm still thinking which DAC to choose, from my ignorance, it looks like the MCP4922 is still more precise than my DAC0808. MCP4922 at 12bit has a +- 2LSB INL, 10bit version +-0.5LSB, 8bit version +-0.125LSB. And the DNL of the MCP4922 is +-0.2LSB.

Can I use the 5V from arduino as a stable reference? Or I need something better? I have some LM336.5 which is a 5v ref

I'll read again your answer with more attention when I can try with the 12bit DAC, raschemmel. Thank you, I think I  got the idea.

thanks again

raschemmel

#12
Nov 28, 2014, 08:08 pm Last Edit: Nov 28, 2014, 08:19 pm by raschemmel
Check the accuracy of the MCP4725 (it's only $5)

LINK:

MCP4725 datasheet


MCP4725

Explanation of INL and DNL DAC accuracy specs

Note: There may be more than one way to correct INL and DNL error. In order to do this you need to run
some tests to find out if it is consistent and linear , such that it can be compensated by adjusting the gain
of your amplifier, or even the offset voltage of the amplifier (if you have an offset circuit added)
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

capicoso

#13
Nov 28, 2014, 08:41 pm Last Edit: Nov 28, 2014, 08:45 pm by capicoso
I'll check it.
The problem about the MCP4725 is that i'm in Argentina, I can't get it here, only MCP4922. And also, I can't buy from ebay... I have some friends that can bring me things from ebay though, but a few times in a year.

I also have to check what % accuracy is enough for the pitch tracking. Like you said, in the lower notes it doesn't matter too much, the scale is the same. And also, even if the lower notes are a bit out of tune, they don't sound bad. Higher notes out of tunes are horrible and unusable

edit: I found some MCP4725 in a website from my country... they're expensive though, double than the MCP4922. Can I connect two MCP4725 to the arduino?
thanks

raschemmel

I just realized the gain needs to be slightly more than 2.

specifically :
Gain A = 127*0.083333=10.583291 V / 5 V = 2.1166582
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

Go Up