Dependencies:   mbed

Revision:
1:ecca38babc13
Parent:
0:7c70badd2847
Child:
2:e1781d02ec0d
--- a/main.cpp	Wed Feb 16 23:20:42 2011 +0000
+++ b/main.cpp	Fri Feb 18 00:43:05 2011 +0000
@@ -10,7 +10,14 @@
       by a "vote" taken from three successive readings.
       
    3) Introduces a "glitch" suppression method that appears
-      to be effective.
+      to be effective.  I consider a glitch to have occurred
+      when two consecutive reading differ in value by more than
+      3 sigma (approximately 10 for the noise distributions
+      exhibited by the internal ADC).
+      
+   4) Provides for side-by-side comparison of an external ADC
+      (MCP3304 or MCP3208) running at about 20,000 sps (because
+      I'm running the part at 3.3v).
       
 With a 100nf capacitor from the analog pin to ground and
 a reasonably low impedance source ( < 5K ) and glitch suppression
@@ -20,25 +27,39 @@
 cleanest of inputs.  This program will help you determine for
 yourself whether that statement is true.  Play with it.
 
+The comparison of the internal ADC with the external ADC show that the
+external ADC is well behaved in circumstances that wipe out the internal ADC
+which is apparently quite sensitive to noise, whereas the external ADC is quite
+tolerant of noise.  The external ADC produces very narrow "distributions".
+
 */
 
 #include "mbed.h"
-#include "Serial.h"
-#include "AnalogIn.h"
 
 Serial pc( USBTX, USBRX );
 
 AnalogIn ain( p20 );
 
+DigitalOut mpc3304Select(p8);
+DigitalOut led4(LED4);
+
+SPI spi(p5,p6,p7);             // spi(mosi,miso,sck)
+
 #define NUM_SAMPLES 1000000
 #define HGRAM_MAX_INDEX 60
-int histoGram[ HGRAM_MAX_INDEX + 1 ];
+
+int histoGramA[ HGRAM_MAX_INDEX + 1 ];  // histogram array for internal ADC
+int histoGramB[ HGRAM_MAX_INDEX + 1 ];  // histogram array for (possible) external ADC
 
 int glitchCount = 0;
 bool glitchSuppressionWanted = false;
+bool useExternalADC = false;
 
-void setADCclockToMaxConversionRate(void);
-int glitchSuppressedAnalogIn( void );
+void setADCclockToMaxConversionRate( void );
+int  glitchSuppressedAnalogIn( bool );
+int  readExternalADC( void );
+void displayMenu( void );
+int getCenterValue( bool externalADC );
 
 int max( int a, int b ) {
     if ( a > b ) return a;
@@ -55,20 +76,33 @@
     return (a <= max(b,c)) && (a >= min(b,c));
 }
 
+// The MPC3304 chip select line is inverted: low == selected
+#define EXT_ADC_OFF 1 
+#define EXT_ADC_ON  0
+
+
+   
 int main() {
 
     int referenceValue;
     int delta;
     int newValue;
     
+    led4 = 0;  // This led shows progress during data acquisition.
+    
+    mpc3304Select = EXT_ADC_OFF;  // deselect
+    
+    spi.format( 8, 0 );
+    spi.frequency( 500000 );
+     
     // Speedup the AnalogIn conversion rate by readjusting
     // the ADC clock to 12 MHz (assuming SystemCoreClock = 96MHz)
     setADCclockToMaxConversionRate();
     
     while(1) {
-    
-        printf( "\nPress the s key to start stats gathering\n" );
-        printf( "Press the g key to toggle glitch suppression...\n" );
+
+        displayMenu();    
+       
         bool waitingForKeyInput = true;
         
         while ( waitingForKeyInput ){
@@ -77,52 +111,97 @@
               case 'G': 
                 glitchSuppressionWanted = ! glitchSuppressionWanted;
                 if ( glitchSuppressionWanted )
-                  printf( "...glitch suppression on...\n" );
+                  printf( "...glitch suppression on...\r\n" );
                 else
-                  printf( "...glitch suppression off...\n" );
+                  printf( "...glitch suppression off...\r\n" );
+                break;
+             
+              case 'x':
+              case 'X': 
+                useExternalADC = ! useExternalADC;
+                if ( useExternalADC )
+                    printf( "...external ADC will be used...\r\n\r\n" );
+                else
+                    printf( "...only internal ADC will be used...\r\n" );
+                break;
+                
+              case 't':
+                for ( int cnt = 0; cnt < 50; cnt++ )
+                   printf( "EXT ADC = %d\r\n", readExternalADC() );
                 break;
+             
               case 's':
-              case 'S': waitingForKeyInput = false;
+              case 'S': waitingForKeyInput = false; break;
+              
+              default:
+                displayMenu(); break;
             }
         }
+             
+        // Clear the histogram arrays.
+        for ( int k = 0; k <= HGRAM_MAX_INDEX; k++ ) histoGramA[k] = histoGramB[k] = 0;
+        
+        bool readFromExternalADC = false;
+        
+        referenceValue = getCenterValue( readFromExternalADC );
+        
+        printf( "Internal ADC center value = %d\r\n\r\n", referenceValue );     
+        printf( "...now gathering... LED4 toggles at each 10,000 readings\r\n\r\n" );
+        
+        glitchCount = 0;
+        for ( int i = 0; i < NUM_SAMPLES; i++ ) {
+            newValue = glitchSuppressedAnalogIn( readFromExternalADC );
+            delta = newValue - referenceValue + (HGRAM_MAX_INDEX / 2);
+            if ( delta < 0 ) histoGramA[0]++;
+            else if ( delta > HGRAM_MAX_INDEX ) histoGramA[HGRAM_MAX_INDEX]++;
+            else histoGramA[delta]++;
+            if ( (i % 10000) == 0 ) led4 = !led4;
+        }
+        led4 = 0;
+ 
+        int glitchCountInternal = glitchCount;
+        int glitchCountExternal;
+        
+        if ( useExternalADC )
+        {
+            readFromExternalADC = true;
+        
+            referenceValue = getCenterValue( readFromExternalADC );
+        
+            printf( "External ADC center value = %d\r\n\r\n", referenceValue );     
+            printf( "...now gathering... LED4 toggles at each 10,000 readings\r\n\r\n" );
+            
+            glitchCount = 0;     
+            for ( int i = 0; i < NUM_SAMPLES; i++ ) {
+                newValue = glitchSuppressedAnalogIn( readFromExternalADC );
+                delta = newValue - referenceValue + (HGRAM_MAX_INDEX / 2);
+                if ( delta < 0 ) histoGramB[0]++;
+                else if ( delta > HGRAM_MAX_INDEX ) histoGramB[HGRAM_MAX_INDEX]++;
+                else histoGramB[delta]++;
+                if ( (i % 10000) == 0 ) led4 = !led4;
+            }
+            led4 = 0;
+            
+            glitchCountExternal = glitchCount;
+        }
         
-        // Establish center point for histogram by taking three readings
-        // and selecting the one in the middle as the reference value around
-        // which deviations will be calculated.
-        int value1 = ain.read_u16() >> 4;
-        int value2 = ain.read_u16() >> 4;
-        int value3 = ain.read_u16() >> 4;
-   
-        if ( middle(value1,value2,value3) ) 
-            referenceValue = value1;
-        else if ( middle(value2,value1,value3) )
-            referenceValue = value2;
-        else
-            referenceValue = value3;
-    
-        printf( "\nreferenceValue: %d   value1: %d   value2: %d   value3: %d\n",
-            referenceValue, value1, value2, value3 );
-        printf( "\n...now gathering...\n\n" );
-             
-        // Clear the histogram array.
-        for ( int k = 0; k <= HGRAM_MAX_INDEX; k++ ) histoGram[k] = 0;
         
-        glitchCount = 0;
-             
-        for ( int i = 0; i < NUM_SAMPLES; i++ ) {
-            newValue = glitchSuppressedAnalogIn();
-            delta = newValue - referenceValue + (HGRAM_MAX_INDEX / 2);
-            if ( delta < 0 ) histoGram[0]++;
-            else if ( delta > HGRAM_MAX_INDEX ) histoGram[HGRAM_MAX_INDEX]++;
-            else histoGram[delta]++;
-        }
         
         // Output histoGram
         for ( int j = 0; j <= HGRAM_MAX_INDEX; j++ ) {
-            printf( "%4d %8d\n", j, histoGram[j] );
+            if ( useExternalADC )
+                printf( "%4d %8d %8d\r\n", j - (HGRAM_MAX_INDEX/2), histoGramA[j], histoGramB[j] );
+            else
+                printf( "%4d %8d\r\n", j - (HGRAM_MAX_INDEX/2), histoGramA[j] );
         }
         
-        printf( "glitchCount: %d\n", glitchCount );
+        if ( glitchSuppressionWanted ) {
+            if ( useExternalADC )
+                printf( "\nglitchCount: Internal =  %d  External = %d\r\n", 
+                        glitchCountInternal, glitchCountExternal );
+            else
+                printf( "\nglitchCountInternal =  %d\r\n", glitchCountInternal );
+        }
     }
 }
 
@@ -141,10 +220,14 @@
     return;
 }
 
-int glitchSuppressedAnalogIn( void ) {
+int glitchSuppressedAnalogIn( bool externalADC ) {
     int v1,v2,delta;
     
-    v1 = ain.read_u16() >> 4;
+    if ( externalADC )
+        v1 = readExternalADC();
+    else    
+        v1 = ain.read_u16() >> 4;
+        
     if ( ! glitchSuppressionWanted ) return v1;
     
     // While this has the possiblity of never returning,
@@ -152,10 +235,56 @@
     // that we will eventually find two successive readings that are
     // within the tolerance band --- i.e., no glitch
     while(1){
-        v2 = ain.read_u16() >> 4;
+        if ( externalADC )
+            v2 = readExternalADC();
+        else
+            v2 = ain.read_u16() >> 4;
         delta = v1 - v2;
         if ( (delta > -10) && (delta < 10)) return (v1+v2)/2;
         v1 = v2;
         glitchCount++;
     }
+}
+
+int readExternalADC( void ) {  // Hardcoded for channel 0 (for quick test)
+    mpc3304Select = EXT_ADC_ON;
+    int byte1 = spi.write( 0xc  );        // start=1  sgl=1 d2=0 d1=0
+    int byte2 = spi.write( 0x0  ) & 0xf;  // d0 = 0
+    int byte3 = spi.write( 0xaa );        // dummy value, but nice pattern of logic analyzer
+    mpc3304Select = EXT_ADC_OFF;
+    int value = (byte2 << 8) | byte3;
+    //printf( "byte2 = %2x  byte3 = %2x  value = %d\r\n", byte2, byte3, value );
+    return value;
+}
+
+void displayMenu( void ) {
+   
+   if ( glitchSuppressionWanted )
+       printf( "\r\n\r\nglitch suppression is enabled.\r\n" );
+   else
+       printf( "\r\nglitch suppression is disabled\r\n" );
+   if ( useExternalADC )
+       printf( "Results from an external ADC will be included.\r\n" );
+   else
+       printf( "External ADC not in use.\r\n" );
+       
+   printf( "\r\nPress the s key to start data acquisition.\r\n" );        
+   printf( "Press the g key to toggle glitch suppression.\r\n" );
+   printf( "Press the x key to toggle use of external ADC.\r\n\r\n" );
+}
+
+int getCenterValue( bool externalADC ) {
+    // Establish center point for histogram by taking three readings
+    // and selecting the one in the middle as the reference value around
+    // which deviations will be calculated.
+    int value1 = glitchSuppressedAnalogIn( externalADC );
+    int value2 = glitchSuppressedAnalogIn( externalADC );
+    int value3 = glitchSuppressedAnalogIn( externalADC );
+    
+    if ( middle(value1,value2,value3) ) 
+        return value1;
+    else if ( middle(value2,value1,value3) )
+        return value2;
+    else
+        return value3;
 }
\ No newline at end of file