Pages: [1]   Go Down
Author Topic: Due ADC Example  (Read 670 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 41
nothing worth doing was ever easy
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:
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


* Screen Shot 2013-09-03 at 10.05.22 PM.png (19.59 KB, 797x687 - viewed 28 times.)
Logged

New England
Offline Offline
Sr. Member
****
Karma: 7
Posts: 295
Natural Semiinductor
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Code:
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.
« Last Edit: September 04, 2013, 03:26:46 am by AmbiLobe » Logged

I am going to get going.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 41
nothing worth doing was ever easy
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Pages: [1]   Go Up
Jump to: