incredibly slow A/D

running following code with scope on pin 4 you find it takes 420 microseconds to do a 12 bit conversion. That is unbelievable given the processor data sheet states 350K samples/sec or 2.8 microseconds. Code below. Makes the device unworkable for me. Any ideas?

void setup() {
  analogReadResolution(12);
  pinMode(4,OUTPUT);
}

void loop() {
  unsigned int analogLaser, analogRefl;
  
  digitalWrite(4, HIGH);
  analogLaser = analogRead(A0);
  digitalWrite(4, LOW);
  delay(2);
}

Processor?

Yes, the basic Arduino software uses the ADC in a very slow way.

That maximum quoted in the datasheet is fictitious. You would not want to deal with the limitations and problems caused by driving the hardware to the max like that. If you are willing to work all of the settings available and you have a way of dealing with the flood of data, the Arduino framework won't stop you.

I think I saw that number in the Teensy datasheet yesterday. I'm not motivated to go looking for it.

kitch:
running following code with scope on pin 4 you find it takes 420 microseconds to do a 12 bit conversion. That is unbelievable given the processor data sheet states 350K samples/sec or 2.8 microseconds. Code below. Makes the device unworkable for me. Any ideas?

void setup() {

analogReadResolution(12);
 pinMode(4,OUTPUT);
}

void loop() {
 unsigned int analogLaser, analogRefl;
 
 digitalWrite(4, HIGH);
 analogLaser = analogRead(A0);
 digitalWrite(4, LOW);
 delay(2);
}

I assume you are using a scope to time this. Realize that you aren't just timing the analog read, but also the two digital writes which are rather slow themselves. I would suggest using direct port writes for something like this if you want good timing data.

Thanks for the responses. I am using a zero. How do I do direct port writes?

The two digital writes take around 2 us each (measured using scope) and this is insignificant compared to the 420 us timing.

I can handle the flood of data since it will be timed and process and down-sampled. How do I learn to directly run the processor bypassing the slower arduino coding? I have not found any documents on this on the site.

kitch:
How do I learn to directly run the processor bypassing the slower arduino coding? I have not found any documents on this on the site.

Take a look at the datasheet for the processor. It explains the functions of the registers and how the peripherals work. Arduino sketches are written in C, so you can do all the sorts of things you could do in straight C with it.

Bear in mind that the headline ADC spec is probably best-case, and may not use the full resolution. Read the datasheet for details.

Also - when you ask a question, you should really specify which board it is. Especially when it's something weird like a Zero - the majority of discussion here is definitely centered on the AVR boards, not these newfangled things.

Just out of curiosity, try setting the resolution to 8-bit and measuring the rate. Maybe also try 10-bit as well.

Pete

Use this to do a port write :

digitalWrite(YOUR_PIN,HIGH) ==

  PORT->Group[g_APinDescription[YOUR_PIN].ulPort].OUTSET.reg = (1ul << g_APinDescription[YOUR_PIN].ulPin) ;

digitalWrite(YOUR_PIN,LOW) ==

  PORT->Group[g_APinDescription[YOUR_PIN].ulPort].OUTCLR.reg = (1ul << g_APinDescription[YOUR_PIN].ulPin) ;

By the way, you can look here for a fast ADC read method using DMA (2us/sample).

The problem is that when the Zero is initialized, the ADC is set to values which make it much slower than it is capable of.
The relevant code (in wiring.c) is:

ADC->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV512 |    // Divide Clock by 512.
                   ADC_CTRLB_RESSEL_10BIT;         // 10 bits resolution as default

  ADC->SAMPCTRL.reg = 0x3f;                        // Set max Sampling Time Length

  while( ADC->STATUS.bit.SYNCBUSY == 1 );          // Wait for synchronization of registers between the clock domains

The ADC is initialized to 10 bits with a prescaler of 512 and sample time length of 63. The minimum possible value of the prescaler is 4 and the sample length can be zero, so if you can figure out how to change these to give you a prescaler of 4 and sampling length set to zero, your sampling interval will be significantly improved.

Pete

el supremo. I have no documentation. Downloaded the file from website and only got the app. I need ton more like library source codes, mapping from arduino pin names to processor pins and ports, ....

I had assumed, since is open source project, these would be provided withe the download. Like the wiring.c you mention.

Where do I go (mac) for a complete package?

Every files are here on my Mac :

/Users/[USERNAME]/Library/Arduino15/packages/arduino/hardware/samd/1.6.4

You can also check on github here :