Due ADC Example

Hey folks,

I had some time today to wade through the SAM3X Datasheet and figured out how to get the ADC up and running. I thought I would share, in case it's useful to others. Please don't make fun of my limited skills.

uint32_t result = 0;
time_t elapsedtime = 0;
time_t totaltimeelapsed = 0;
int counter = 0;

void ADC_Handler(void)  {
       //Check the ADC conversion status
       if ((adc_get_status(ADC) & ADC_ISR_DRDY) == ADC_ISR_DRDY)
       {
       //Get latest digital data value from ADC and can be used by application
           result = adc_get_latest_value(ADC); 
     //     Serial.println("test"); 
       }
   }

void setup(){

Serial.begin(115200);

adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST); 

adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1); 

//Port 0 = ADC_Channel_7
adc_enable_channel(ADC, ADC_CHANNEL_7); 

NVIC_EnableIRQ(ADC_IRQn);

adc_set_comparison_channel(ADC, ADC_CHANNEL_7);

adc_set_comparison_mode(ADC, ADC_EMR_CMPMODE_IN);

adc_set_comparison_window(ADC, 0, 3300); 

adc_enable_interrupt(ADC, ADC_IER_DRDY); 
   
adc_configure_trigger(ADC, ADC_TRIG_SW, 0); 
    
}

void loop(){

 
while (totaltimeelapsed <= 1000){
 // counter = counter + 1;
  time_t capturetimestart = millis();
//  time_t timestart = micros();
  adc_start(ADC);
//  time_t timeend = micros();
//  elapsedtime = timeend - timestart;
//  Serial.print(counter);
//  Serial.print(" , ");
  Serial.println(result);
//  Serial.print(" , ");
//  Serial.print(elapsedtime); 
//  Serial.print(" , ");
  time_t capturetimeend = millis();
  time_t capturetimeelapsed = capturetimeend-capturetimestart;
  totaltimeelapsed = totaltimeelapsed + capturetimeelapsed;
//  Serial.println(totaltimeelapsed); 

  }

}

I pulled 1000 millis of data and plotted in Matlab (see attached). It looks like it's pulling about 2.5k/s.

One question: Does this pull at a consistent rate (as it would with a timer interrupt)? Or is this dependent on the code in the loop?

Cheers,
Mike

That would be shocking to see such inaccuracy on my Due. But I get good ADC results at 10,000 samples per second. I use a 3k pot on analog channel 7 with perfect results. In the same loop, analogRead(4) from a photo transistor with 10k ohm load with good ADC values. Your software seems more detailed than necessary.

void detectANDknob()
     {
     detect = analogRead(4);   // light detector
     knob = long(analogRead(7));     // on potentiometer
     TD = millis();
     evaluateDetector();
     }

If you do not Serial.println in the middle of each loop, your may see better results. I wait 200,000 loops before Serial.print, and use the adc result in logic, not printing.

Thanks for your note. Tonight I'm going to try reading the data into an array and hold off on the Serial communications.

What do you mean by 'That would be shocking to see such inaccuracy on my Due'? I have a 5k pot hooked up to analog channel 7, and it seems to be converting the correct data?

Cheers,
Mike