Hackscribble:
Hello panther3001
I think I've got a sense of the statistical process in the Atmel paper. Having just built a device with added outboard ADCs, I'll be a bit miffed if it turns out I could have done it in software 
There are also limitations set out in that paper and your posts: the need for random noise, the extended sample period, the assumption that the signal under test does not vary during the sample period.
So I guess the proof of whether this is a practical technique will come through testing.
Personally, I'm willing to invest in an ADC and time to do some testing. I think it's important to define the test method and expected results in advance.
Maybe you could suggest what the testing should involve, and others can comment. I'll probably start with the MCP4725, since I've used it recently.
All the best
Ray
Ray, here's the testing method I recommend. It will take just under 23 hrs per test, at a maximum of 16-bit ADC resolution, with 20 readings per DAC step, unless you modify my code to do fewer readings per step, or fewer steps.
Here it is:
-All you need to do is add in the part that writes to the DAC.
//create flat-toothed sawtooth output signal, and sample it via oversampling (using eRCaGuy_analogReadXXbit library)
//By Gabriel Staples
//Code to test my "eRCaGuy_analogReadXXbit" library, and the concept of oversampling, according to AVR121 application note.
//http://electricrcaircraftguy.blogspot.com/2014/05/using-arduino-unos-built-in-16-bit-adc.html
//17 May 2014
//include the library
#include <eRCaGuy_analogReadXXbit.h>
//instantiate an object of this library class; call it "adc"
eRCaGuy_analogReadXXbit adc;
//Global constants
const uint8_t pin = A0; //analogRead pin
//constants required to determine the voltage at the pin
const float MAX_READING_10_bit = 1023.0;
const float MAX_READING_11_bit = 2046.0;
const float MAX_READING_12_bit = 4092.0;
const float MAX_READING_13_bit = 8184.0;
const float MAX_READING_14_bit = 16368.0;
const float MAX_READING_15_bit = 32736.0;
const float MAX_READING_16_bit = 65472.0;
const float MAX_READING_17_bit = 130944.0;
const float MAX_READING_18_bit = 261888.0;
const float MAX_READING_19_bit = 523776.0;
const float MAX_READING_20_bit = 1047552.0;
const float MAX_READING_21_bit = 2095104.0;
unsigned long output_dt_des = 10 * 1e6; //us, desired output time step; 10 seconds; GS Note: this output time step was chosen purposefully
//so that we can get ~20 readings per time step, even with a resolution setting up to 16-bit. Note that according to my table,
//a single 16-bit reading takes ~0.5 sec, so getting 20 readings takes ~0.5x20 = 10 seconds, or 10,000,000 us. Table found here: http://electricrcaircraftguy.blogspot.com/2014/05/using-arduino-unos-built-in-16-bit-adc.html
void setup()
{
Serial.begin(115200);
//print test info
Serial.print("output_dt_des (time per DAC output step) = "); Serial.print(output_dt_des / 1e6); Serial.println(" sec");
Serial.print("Estimated time to run test = "); Serial.print(output_dt_des / 1e6 * 4096 * 2 / 3600.0); Serial.println(" hours");
Serial.println("");
//print data header
Serial.println("time_stamp(ms),DAC_output,Vout_commanded,ADC_reading,Vin_ADC_reading");
}
void loop()
{
//----------------------------------------------------------------------------------
//DAC OUTPUT
//----------------------------------------------------------------------------------
static int output = 0; //DAC output value from 0-4095 for a 12-bit DAC
static int8_t d_output = 1; //output change, per output time step
static unsigned long t_start_out = micros();
unsigned long t_now = micros();
if (t_now - t_start_out >= output_dt_des) //the time step period has elapsed, so let's change the DAC output value
{
t_start_out = t_now; //update
//SET YOUR DAC OUTPUT HERE; HOWEVER THAT IS DONE
//write_to_DAC(output);
output += d_output;
//constrain DAC output values to those possible for a ********12-bit DAC**********
if (output > 4095)
{
d_output = -1;
}
else if (output < 0)
{
d_output = 1;
Serial.println("END OF TEST");
while (1) {}; //go into infinite loop here, to stop test, since one full cyle has now been completed
}
}
//----------------------------------------------------------------
//ADC INPUT, & PRINTING DATA TO SERIAL MONITOR FOR PLOTTING
//----------------------------------------------------------------
static uint8_t bits_of_resolution = 10; //<--------THIS IS THE VALUE YOU WILL HAVE TO CHANGE EACH RUN, TESTING 10-BIT, 11, 12, 13, 14, 15, AND 16-BIT RESOLUTION SETTINGS
static unsigned long input_dt_des = output_dt_des / 20; //us, desired time step for taking analog readings; we want the time-step to be ~20x shorter than the output
//time-step for the DAC, so that we can get ~20 ADC readings per discretized DAC output step
static unsigned long t_start_in = micros();
t_now = micros();
if (t_now - t_start_in >= input_dt_des) //the time step period has elapsed, so let's change the DAC output value
{
t_start_in = t_now; //update
unsigned long t_now_ms = millis(); //grab a time stamp in ms, so that I don't have to worry about overflows every ~70 min on micros(), during long tests
unsigned long reading = adc.analogReadXXbit(A0, bits_of_resolution, 1); //take a single reading at specified resolution
float Vin = (float)reading / MAX_READING_10_bit * 5.0; //V read on the pin; <--------------DON'T FORGET TO CHANGE MAX_READING_XX_bit here too, according to your setting
float V_commanded = (float)output / 4095.0 * 5.0; //V commanded on DAC, assuming *************12-bit DAC*************
//print data to serial monitor, for plotting in Excel:
Serial.print(t_now_ms); Serial.print(","); Serial.print(output); Serial.print(","); Serial.print(V_commanded, 8); Serial.print(","); Serial.print(reading); Serial.print(","); Serial.println(Vin, 8);
}
} //end of loop()
What you'll need to do is run the code with various ADC resolutions from 10 to 16-bit. I recommend you do them all. Be sure to change this setting in two places in the code. One, you must set bits_of_resolution to the correct value, and two: you must set the constant divisor (ex: MAX_READING_10_bit) to the correct value. My code above also assumes you are using a 12-bit DAC. If you ever use a higher resolution DAC, you'll need to change the code in a handful of places, but I'm sure you'll read the code carefully and see that anyway.
Here is what the commanded DAC output "sawtooth" wave looks like, for one cycle:

Here is what it looks like zoomed in. It would be really useful to see how the different sampling resolutions affect how close the ADC gets to actually picking out these discrete steps. Sampling this at 10-bits, for example, would show that many of the steps are indistinguishable, so effectively the sampling would show a staircase with larger stairs than what you see here. Of course there will be noise, so precision (as we have learned it from dlloyd [see reply #27 on pg 2]) will not be as good as the sampling resolution, but if the sampling resolution works as expected, each individual staircase will be able to be detected, once the selected input level of resolution is >= the output resolution. Ex: to detect every stair on this 12-bit staircase, I predict that the ADC resolution will have to be set to 12-bit or higher. I also predict, however, that the higher the resolution you choose, the less noise you will see in the readings. This is all to be seen, however, by your testing, if you are able to do it.

Here is the code I used to generate the sawtooth:
//create flat-toothed sawtooth output signal
//By Gabriel Staples
//17 May 2014
void setup()
{
Serial.begin(115200);
}
void loop()
{
static int output = 0; //DAC output value from 0-4095 for a 12-bit DAC
static int8_t d_output = 1; //output change
while (1)
{
//SET YOUR DAC OUTPUT HERE; HOWEVER THAT IS DONE
//write_to_DAC(output);
for (int i=0; i<20; i++){
Serial.println(output);
}
output += d_output;
//constrain DAC output values to those possible for a ******12-bit DAC********
if (output > 4095)
{
d_output = -1;
}
else if (output < 0)
{
d_output = 1;
Serial.println("END OF TEST");
while (1) {}; //go into infinite loop here, to stop test, since one full cyle has now been completed
}
}
}
To plot the data you'll need to use FreeMat or MATLAB or something similar, as Excel can't handle it. It's 163,860 rows of data.
FreeMat is available for download here: http://freemat.sourceforge.net/
My FreeMat code I used to generate the plots above is attached. The data text file is also attached. Put it in the same directory as the .m file.
Note that FreeMat is a MATLAB clone, and most functions in FreeMat are the same as MATLAB, so feel free to copy MATLAB tutorials when learning FreeMat. The FreeMat documentation can otherwise be found here:
http://freemat.sourceforge.net/help/index.html
Let me know if you have problems.
plot_sawtooth.m (1.42 KB)
sawtooth_single_cycle.txt (917 KB)