Using micros() to measure analogRead() time varies based on Serial.print location?
Not sure if it is related to your problem but... if I were to try such a
measurement, I would use local variables, like



unsigned int start = micros();
int value = analogRead(sensorPin);
unsigned int end = micros();
sensorValue[ind] = value;
starts[ind] = start;
ends[ind] = end;
vals[ind] = end - start;


This way you would be measuring the time it takes to call both
analogRead() and micros(), and very little more. If you do something
like

sensorValue[ind] = analogRead(sensorPin);


then you are also measuring the time taken by the pointer arithmetic and
the memory access.

I generally program AVR-based Arduinos. These have a load-store
architecture, where saving to a local variable costs essentially
nothing, as the variable is typically assigned a CPU register by the
compiler. Saving to a global takes more time because of the RAM access.

I have no experience with ARM-based Arduinos, like the Zero, but I
believe it's also a load-store architecture, thus the same
considerations should probably apply.

Update: I tried the following experiment on my Uno:

#define PRINT_WHILE_READING

#define READ_COUNT 100

void setup() {
    unsigned int starts[READ_COUNT];
    unsigned int ends[READ_COUNT];
    unsigned int vals[READ_COUNT];

    Serial.begin(57600);
    Serial.println("Ready to begin");

    // Take the readings.
    for (int i = 0; i &lt; READ_COUNT; i++) {
        starts[i] = micros();
        analogRead(A1);
        ends[i] = micros();
        vals[i] = ends[i] - starts[i];
#if defined(PRINT_WHILE_READING)
        Serial.print(i);
        Serial.print('\t');
        Serial.print(starts[i]);
        Serial.print('\t');
        Serial.print(ends[i]);
        Serial.print('\t');
        Serial.println(vals[i]);
#endif
    }

#if !defined(PRINT_WHILE_READING)
    // Print them now.
    Serial.println("All data taken");
    for (int i = 0; i &lt; READ_COUNT; i++) {
        Serial.print(i);
        Serial.print('\t');
        Serial.print(starts[i]);
        Serial.print('\t');
        Serial.print(ends[i]);
        Serial.print('\t');
        Serial.println(vals[i]);
    }
#endif
}

void loop() {}


If PRINT_WHILE_READING is defined as above, I get times that fluctuate
between 108 and 116&nbsp;µs. If I comment out the line
#define PRINT_WHILE_READING, I get mostly 116&nbsp;µs and,
occasionally, 124&nbsp;µs. In both cases, the first reading takes longer
(208 and 212&nbsp;µs respectively).

The fact that the first reading takes longer is explained in the
datasheet: the ADC does some initializations in that first reading. All
measured times are multiples of 4&nbsp;µs because that is the resolution
of micros().

Now, trying to understand the differences between the two cases:


With PRINT_WHILE_READING the times are shorter on average. This is
because the numbers are not stored in RAM, as the compiler figured
out the arrays starts[], ends[] and vals[] are not really
needed and optimized them away. When PRINT_WHILE_READING is not
defined, I can see the “store in RAM” instructions in the generated
assembly.
With PRINT_WHILE_READING the numbers fluctuate more. I guess this
is due to the printing through the serial port taking a variable
amount of time depending on the numbers being printed, and thus
creating timing inconsistencies.


The last point deserves some explanation. The ADC is clocked by a
prescaler that divides the frequency of the main clock by 128. This
gives a clock period of 8&nbsp;µs. When an ADC conversion is started,
the ADC waits for the next rising edge of its clock, which can take
anywhere between 0 and 8&nbsp;µs, then it does the conversion in
13&nbsp;cycles of its clock. This means the whole process can take
anywhere between 104 and 112&nbsp;µs depending on the exact time the
conversion is started relative to the phase of the prescaler. If the
conversions are started at irregular intervals, you expect to see
roughly 8&nbsp;µs of fluctuation in the measured times.

All these observations have been done on an Uno, which is based on an
AVR clocked at 16&nbsp;MHz. I know the Zero is quite different. You will
have to look at the datasheet of the ATSAMD21G18 to see whether anything
of the above can be extrapolated to the Zero.