Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 1 of 1

Thread: T3.1 DAC -> ADC loopback

  1. #1

    T3.1 DAC -> ADC loopback

    I took advantage of the OSH Park deal on T3.1. Had to laugh when I got the purple mailer, they certainly have a color theme going. It's great to have a micro with built-in DAC so I tried the obvious thing, a loopback into the 16-bit ADC by connecting A14 (DAC out) to A0 (ADC in). As expected there are on average 16 ADC counts per DAC step, although the last 8 DAC steps are all saturated around a reading of 65524. Looks like the worst-case differential nonlinearity is at a DAC count of 1000 with a spike of just over 1/2 LSB. This is a test of the combined DAC and ADC performance, I don't know that either one can be considered "ideal", so the reported error is the sum of the inaccuracy of DAC plus ADC at that voltage level.

    Loopback test code:
    Code:
    // DAC->ADC loopback test for Teensy 3.1    March 4 2014 J.Beale
    
    #define VREF (3.266)         // ADC reference voltage (= power supply)
    #define ADCMAX (65535)       // maximum possible reading from ADC
    #define SAMPLES (100)      // how many samples to combine for pp, std.dev statistics
    #define DACRES (12)          // bits of resolution for DAC output
    
    const int analogInPin = A0;  // Analog input is AIN0 (Teensy3 pin 14, next to LED)
    const int LED1 = 13;         // output LED connected on Arduino digital pin 13
    
    int sensorValue = 0;        // value read from the ADC input
    long oldT;
    int DACval = 0;             // value to write to DAC
    
    void setup() {    // ==============================================================
      analogWriteResolution(DACRES);  // Teensy 3.1 DAC output
      pinMode(LED1,OUTPUT);       // enable digital output for turning on LED indicator
      analogReference(EXTERNAL);  // set analog reference
      analogReadRes(16);          // Teensy 3.0: set ADC resolution to this many bits
      analogReadAveraging(16);    // average this many readings
         
      Serial.begin(115200);       // baud rate is ignored with Teensy USB ACM i/o
      digitalWrite(LED1,HIGH);   delay(1000);   // LED on for 1 second
      digitalWrite(LED1,LOW);    delay(12000);   // wait for slow human to get serial capture running
         
      Serial.println("# Teensy 3.1 ADC-DAC loopback test");
      Serial.println("DAC,ADC,PP,STDEV");
    } // ==== end setup() ===========
    
    void loop() {  // ================================================================ 
         
      long datSum = 0;  // reset our accumulated sum of input values to zero
      int sMax = 0;
      int sMin = 65535;
      long n;            // count of how many readings so far
      double x,mean,delta,sumsq,m2,variance,stdev;  // to calculate standard deviation
         
      oldT = millis();   // record start time in milliseconds
    
      sumsq = 0; // initialize running squared sum of differences
      n = 0;     // have not made any ADC readings yet
      mean = 0; // start off with running mean at zero
      m2 = 0;
      analogWrite(A14, DACval);  // update DAC output
        
      for (int i=0;i<SAMPLES;i++) {
            // x = analogRead(analogInPin);
            x = 0;
            for (int j=0;j<5;j++) {
              x += analogRead(analogInPin);
            }
            x /= 5;        
            datSum += x;
            if (x > sMax) sMax = x;
            if (x < sMin) sMin = x;
                  // from http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
            n++;
            delta = x - mean;
            mean += delta/n;
            m2 += (delta * (x - mean));
      } 
    
      variance = m2/(n-1);  // (n-1):Sample Variance  (n): Population Variance
      stdev = sqrt(variance);  // Calculate standard deviation
    
      float datAvg = (1.0*datSum)/n;
      Serial.print(DACval);  Serial.print(",");
      Serial.print(datAvg,2); Serial.print(",");
      Serial.print(sMax-sMin); Serial.print(",");
      Serial.println(stdev,3);
    
      DACval += 1;
      if (DACval >= (1<<DACRES))
        DACval = 0;
    
    } // end main()  =====================================================
    Output of loopback test:
    Code:
    DAC,ADC,PP,STDEV
    0,19.36,6,1.394
    1,30.72,8,1.495
    2,42.46,7,1.657
    3,58.08,10,1.854
    4,74.56,9,1.727
    5,90.52,7,1.529
    ...
    4082,65447.05,14,2.717
    4083,65460.54,13,2.603
    4084,65477.86,19,3.235
    4085,65494.84,19,3.091
    4086,65508.89,17,2.513
    4087,65520.77,14,2.426
    4088,65524.31,12,2.248
    4089,65524.59,12,2.222
    4090,65524.64,15,2.440
    4091,65524.70,13,2.100
    4092,65524.32,12,2.223
    4093,65524.87,14,2.318
    4094,65524.55,11,2.207
    4095,65524.37,13,2.231
    Raw data file: T31-DAC-loop2.zip
    Plot of differential nonlinearity: Click image for larger version. 

Name:	T31-DAC-loop2.png 
Views:	187 
Size:	15.9 KB 
ID:	1563
    Last edited by JBeale; 03-05-2014 at 04:17 PM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •