0

Very slow sampling frequency...
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Very slow sampling frequency...

by manor on Tue Jun 19, 2018 1:33 am

I am getting a sampling frequency of 2.4KHz, shouldn't this be much higher (especially on a Metro Express)?

Code: Select all | TOGGLE FULL SIZE

void setup()
{
  Serial.begin(9600);
  pinMode(A1, INPUT);
}

void loop()
{
  unsigned long t0, t;

  t0 = millis();
  for(int i=0; i<1000; i++) {
    analogRead(A1);
  }
  t = millis()-t0;  // calculate elapsed time

  Serial.print("Frequency: ");
  Serial.println((float)1000*1000/t);
  delay(1000);
}


manor
 
Posts: 5
Joined: Fri Mar 30, 2018 3:24 pm

Re: Very slow sampling frequency...

by manor on Tue Jun 19, 2018 11:57 am

The same code on a Metro "classic" gives 9000... Very disappointing.

manor
 
Posts: 5
Joined: Fri Mar 30, 2018 3:24 pm

Re: Very slow sampling frequency...

by adafruit_support_mike on Wed Jun 20, 2018 3:48 am

The SAMD21 can sample up to about 350ksps, but you have to do a lot more poking around in the registers to make it work. The analogRead() convenience function is only the version that's easiest to use in generic circumstances.

Take a look at section 32 of the SAMD21 datasheet, and the files wiring_analog.h and .c in the board support package.

The biggest source of delay is probably the fact that the ADC uses a different clock source than the microcontroller, and analogRead() has to call a routine to sync those clocks every time you use it. If you want high-speed sampling, you have to keep the clock domains in sync while it's happening, which means you can't execute arbitrary code between samples.

adafruit_support_mike
 
Posts: 52085
Joined: Thu Feb 11, 2010 2:51 pm

Re: Very slow sampling frequency...

by westfw on Sat Jun 23, 2018 3:43 am

Grr. The SAMD21 "analogRead()" code LOOKS really stupid - it completely disables the ADC in between each call, and then it has to re-enable it as well. As Mike says, that involves a lot of clock synchronization, in addition to just being a lot more code than ought to be needed. (In comparison, the AVR analog code enables the ADC at reset, and only needs to make sure that the correct pin is multiplexed to the ADC input in analogRead())

(Note, this is Arduino standard core code, not Adafruit code!)

Unfortunately, I don't know if there is some reason that the code is written that way - there isn't any special documentation. And I don't know enough about the SAMD21 to confidently say that none of it is necessary, and the re-write would be drastic enough to need substantial testing that I wouldn't be very good at doing :-(

However, this has come up before, and Albert van Dalen has written a much faster version (including a nice write-up): http://www.avdweb.nl/arduino/libraries/ ... t-adc.html
User avatar
westfw
 
Posts: 1420
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: Very slow sampling frequency...

by westfw on Sat Jun 23, 2018 5:41 am

On closer examination, it looks like the ADC is slow mostly because it’s initialized with a divide-by-512 prescaler, when 32 would have been enough. Albert’s function reset the prescaler rather than addressing the other issues. Since the main ADC clock is set to the same 48MHz as the cpu, synchronization shouldn’t be too bad... (still about 6clocks, but 6 clocks at a Pclk of 48MHz is much better than if the Pclk was much slower.)

Edit: Apparently the Arduino code also set up a very long "sample time" (~32 clocks) that happens before the the actual conversion. Albert also reduces that to a single clock. So instead of ~50 clocks at ~100kHz (~500us), the conversion takes ~20 clocks at 750kHz (~30us)...
User avatar
westfw
 
Posts: 1420
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: Very slow sampling frequency...

by adafruit_support_mike on Sun Jun 24, 2018 11:58 pm

Making the sampling window narrower puts limits on the impedance of the signal connected to the ADC.

Every microcontroller ADC I've ever seen uses a switched sample-and-hold capacitor to read the input. The SAMD21's sampling capacitor is 3.5pF, which is pretty small, but to get a sample that matches the actual input to within 12-bit resolution, the sampling window has to be at least nine RC time constants wide.

The resistance of the sampling input is 3.5k, which puts the minimum possible 12-bit sampling window at about 110ns, and that assumes zero impedance from the signal source. If the source has 1k of resistance, the sampling window has to be at least 142ns wide. For a 10k source resistance, the window needs to be 425ns wide.

At 48MHz, one clock cycle lasts about 21ns, so 20 to 21 cycles would be a reasonable window for signal sources with resistance up to 10k. If you want to reduce that, you have to make sure you're using a low-resistance signal.

adafruit_support_mike
 
Posts: 52085
Joined: Thu Feb 11, 2010 2:51 pm

Re: Very slow sampling frequency...

by westfw on Mon Jun 25, 2018 4:09 am

For a 10k source resistance, the window needs to be 425ns wide.
At 48MHz, one clock cycle lasts about 21ns, so 20 to 21 cycles would be a reasonable window for signal sources with resistance up to 10k.

Ok. But the way I read the documentation, the SAMPLEN value is in CLKadc/2 units, AFTER the prescaler (which is set to /512 on SAMD21)
At 48MHz/512, each clock is 10667ns wide... (max CLKadc is 2.1MHz, or about 500ns period. So a samplen of 2 should allow ~10k sources even if the clock is set to the maximum rate...) (although 10k is pretty low, compared to the things I've seen people connect to arduino-like boards. 100k might be a better goal.)
User avatar
westfw
 
Posts: 1420
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: Very slow sampling frequency...

by adafruit_support_mike on Tue Jun 26, 2018 3:51 am

Good point.

That's one of the challenges with 32-bit microcontrollers.. there are so many layers of settings and configuration that you can spend weeks learning to make a single peripheral work. And then good luck trying to reuse code on another project that wants different settings.

adafruit_support_mike
 
Posts: 52085
Joined: Thu Feb 11, 2010 2:51 pm

Re: Very slow sampling frequency...

by westfw on Wed Jun 27, 2018 5:31 am

good luck trying to reuse code

Indeed. I've found the Atmel ARMs to be particularly frustrating in the subtle differences between like-named peripherals on different SAM chips.

(For example, the RTC on SAMD10 runs off a GCLK, and I have nice code that uses a 1MHz input and a compare value of 1000, this giving me millis() and micros() essentially in hardware. On SAMC21 and SAMD51, the RTC will only run off the 32kHz oscillator(s). And some of the chips have more SERCOM USART pinout choices than others)
User avatar
westfw
 
Posts: 1420
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Please be positive and constructive with your questions and comments.