Arduino 16 bit DAC: INL, DNL, Gain and Offset.
Following on with step 1c from the article: Making a high resolution ADC from an Arduino Mini Pro
Well since the PWM output is only capable of 61069 steps, it really is not 16 bits, as 16 bit resolution would allow for 65535 discrete steps so I will call it a 15+ bit DAC.
Now that we actually have the DAC working, it is time to verify how well it works. Here is a look at some of the data from the first unit I tested but first a quick description of how the data was taken for this: I set up the PWM to take a step approximately every 1.2 seconds. I programmed the PWM to start from zero then when it reached 61069 it would start back down again. The PWM output was fed through the 4th order RC filter. To take the DC value I used an 18bit measure system (over +/-10V) that was programmed to average a about 16,000 measurements every 950mS from the filter output. We ended up with a total of 72064 data points over the 61069 output steps. Since I did not fully synchronize the data measured with every step taken the actual INL and DNL are approximate. The measured values I came up with for this Arduino Mini Pro board:
LSB = ~ 0.000076V (76uV)
INL= ~ 0.00225V (2.25mV)
DNL= ~ 0.0015V (1.5mV)
Min Measurement = 0.00313686V
Maximum Measurement = 4.64705V
Gain error = 0.928782628 ( Hmm.. this seems to explain the step response we were seeing on the scope capture in the filter article, when I was expecting a 409mV step and was seeing about 374mV on the scope)
Offset error = 0.00313686V
The DNL is really bad news. Why? Because it means effectively we are losing a little more than 4 bits of resolution. It is like this: From step to step there can be an error of 1.5mV so there is no point in looking for anything smaller than 1.5mV then for the full scale range of 4.647V divided by 1.5mV gives us about 3100 discrete values which is a little more than 11 bits of resolution. I really need to see if this is an inherent problem with the PWM generator design or if it is just an issue with this one device. So I will end up running this test again on another one or two more devices.
Below are The Mad Scientist Hut graphs of the actual data for the first device, and also a copy of the raw data if you are interested in looking it over.
Here is a copy of the raw data, you will need office 2010 to open this since it has more than 65,535 rows of data
This is a graph of the measured data:
So our 15+ bit DAC seems to work pretty well.
To calculate INL We took the end points of the data and subtracted a linear line from the actual data taken and ended up with a worst case measurement of about 0.00225V or approximately an error of 0.5% of the expected programmed output.
Here is what the INL graph looks like:
To calculate DNL We just took every data point and subtracted the previous measurement and graphed the result. This resulted in about a 0.0015V error from measurement to measurement, really this is a pseudo DNL, this would work much better with a synchronized step to measurement.
Here is a look at the DNL graph:
So if you are wondering why is the DNL getting wider, lets examine the output a little closer.
Here is the output for several steps around 0.5V, looks pretty decent….
Here is the output for several steps around 2.5V, starting to see a real monotonicity issue here. I am going to take a guess that this part has some divider issue that is occurring on every forth step (it is the 3rd bit in the clock divider that may be does not do what is expected)
Here is the output for several steps around 4.5V and here it is getting close to the maximum output and where the worst case DNL was happening.