Go Down

Topic: Freerun mode for multiple analog inputs? (Read 620 times) previous topic - next topic

witchmaster

Mar 09, 2016, 10:25 am Last Edit: Mar 09, 2016, 01:34 pm by witchmaster
Hi!

I'm working on a project that needs a lot of analog inputs so I'm going to use multiplexers and I need to use all the analog inputs of the Due. From this topic: http://forum.arduino.cc/index.php?topic=224664.0 (code segment from that topic below) I see how to use freerun mode on one analog input.

Is it possible to use freerun for multiple analog inputs and how in that case? I need the smallest amount of latency for my project. Thanks for any help!

Code: [Select]

int x;                                           // read value

void setup()
{
  Serial.begin(57600);                           // initialize the serial port:
  REG_ADC_MR = 0x10380180;                       // change from 10380200 to 10380180, 1 is the PREESCALER and 8 means FREERUN
  ADC -> ADC_CHER = 0x80;                        // enable ADC on pin A0
}

void loop() {

  unsigned long t = micros();                    // init time an elapsed time, in micro seconds
  
  for(int i = 0; i < 1000; i++) {
    
    // instrucction to measure
    while((ADC->ADC_ISR & 0x80)==0);             // wait for conversion
    x = ADC->ADC_CDR[7];                         // read value A0
    
  }
  
  t = micros() - t - 2;                          // 2 us is nothing measured time
  
  Serial.print("Time (us) ");
  Serial.println( ( (double) t / 1000 ), 6 );
  
  delay(2000);
}

witchmaster

#1
Mar 09, 2016, 03:09 pm Last Edit: Mar 09, 2016, 03:27 pm by witchmaster
I figured this out myself, here is a working example that reads from all analog inputs. Time is 5.8µs for one read of all 12 analog inputs (~0.5µs per input). I have to do more tests to see how reliable this method is, for my project I only need 7-bits of precision though.

Code: [Select]

int x[12]; // read value
int mean[12]; // mean value
byte cdr[12] = {7,6,5,4,3,2,1,0,10,11,12,13}; // cdr indexes
int i, j;

void setup()
{
  Serial.begin(57600); // initialize the serial port:
  REG_ADC_MR = 0x10380180; // change from 10380200 to 10380180, 1 is the PRESCALER and 8 means FREERUN
  ADC -> ADC_CHER = 0x3CFF; // enable ADC on all pins
}

void loop() {

  unsigned long t = micros(); // init time an elapsed time, in micro seconds
  
  for(j = 0; j < 12; j++)
    x[j] = 0;
  for(i = 0; i < 1000; i++)
  {
    // instrucction to measure
    while((ADC->ADC_ISR & 0x3CFF)==0); // wait for conversion
    for(j = 0; j < 12; j++)
      x[j] += ADC->ADC_CDR[cdr[j]]; // read value
  }
  for(j = 0; j < 12; j++)
    mean[j] = x[j] / 1000;
  
  t = micros() - t - 2; // 2 us is nothing measured time
  
  Serial.print("Time (us): ");
  Serial.println( ( (double) t / 1000 ), 6 );
  for(j = 0; j < 12; j++) {
    Serial.print("Value");
    Serial.print(j);
    Serial.print(": ");
    Serial.println( mean[j]/32 );
  }

  delay(2000);
}

Go Up