delay processing interrupt

i'm trying to use an encoder to track motor position. i trigger an ISR on the rising edge of one of the encoder outputs.

the following plot shows the motor position vs time (msec). The circles on the plot show a point being plotted. It shows groups of points about ~0.3 msec apart separates by ~3 msec (time between groups).

this data, including the usec timestamp is captured in a buffer during each ISR event and dumped later. The isr is occurring with no other activity. A function is called from loop() and does not return until triggered by a button press.

the data shows that the motor position changes every ~0.3 msec. Tracking position will not be accurate if the isr cannot be processed for more than that time (~3msec).

is there some other interrupt enabled, perhaps for Serial processing?

Programming questions are more easily answered when accompanied with code. Read the forum guidelines.

This is the forum's programming section.

Have you forgotten something?

it's a question about the environment.

i didn't find a more appropriate forum to place this in.

The environment is screwed.
Ask Greta.

TheMemberFormerlyKnownAsAWOL:
The environment is screwed.
Ask Greta.

How dare you!!!

in case there's a coding problem see attached.

the following is how the isr is enabled

    attachInterrupt(digitalPinToInterrupt(PIN_E_B), isr, RISING);

the isr() showing how position is updated and how data is captured, among other remnants

void
isr (void)
{

    t1   = t0;
    t0   = micros();
    dt   = t0 - t1;          // inverse of speed
    tSpd = 0;

#define BIT_E_A     1
#define BIT_E_B     1<<1
    enc = (digitalRead(PIN_E_B) << 1) | digitalRead(PIN_E_A);

    switch (enc)  {
        case BIT_E_B | BIT_E_A:     // A rises CW
            pos++;
            dir =  1;
            if (tCw)
                tSpd = t0 - tCw;
            tCw  = t0;
            tCcw = 0;
            break;

        case BIT_E_B:               // A falls CCW
            pos--;
            dir = -1;
            if (tCcw)
                tSpd = t0 - tCcw;
            tCcw = t0;
            tCw  = 0;
            break;

        default:
            goto capture;
            break;
    }

    if (manual)
        goto capture;

    // -----------------------------------------------
    // capture data
capture:
#if 1
    buf [bufIdx++] = micros() & 0xFFFF;
    buf [bufIdx++] = pos;
    buf [bufIdx++] = mAmp;
    buf [bufIdx++] = (enc << 4) | h_dir;

    bufIdx = BUF_SIZE <= bufIdx ? 0 : bufIdx;
 // if (BUF_SIZE <= bufIdx)  {
 //     bufIdx = DUMP_SIZE;
 //     bufWrap++;
 // }
#endif

    // -----------------------------------------------
    // collect ISR duration
#if 0
    dt = micros() - t0;

    if (0 == maxIsr)
        maxIsr = minIsr = dt;

    else  {
        if (maxIsr < dt)
            maxIsr = dt;
        if (minIsr > dt)
            minIsr = dt;
    }
#endif

    isrCnt++;
}

the code executed while the isr is active. ButtonPress() monitors 2 inputs, returning true if either is LOW.

// ------------------------------------------------
void
simple (void)
{
    do {
        dist   = target - pos;
        if (Abs(dist) < 300)
            SetSpeed(0);

    } while (! buttonPress());

    SetSpeed(0);
    cond   = C_STOP;
}

the delay appears fairly period, so i think it may be some other interrupt. Just having a better understanding of what else the environment is doing could save me some time. I can try disabling all other interrupts and restoring them after my operation is complete.

Change the motor speed and graph again. Does the gap in data still happen every 10 counts at the new speed? Is the gap still about 10 counts long? That would indicate a problem in the encoder.

If, however, the periods of data (3 ms) and no data (3 ms) remain at the new speed, that would indicate that the encoder is not the problem and something is interfering or the code is incorrect. The only interrupt that is not under your control is the millisecond timer which happens for a few microseconds and happens every 900-something microseconds. Those times don't match your data.

it's not a precision encoder. just a couple photo transistors and a vane with gaps.

i removed the encoder and manually rotated ~1 turn and ~30 counts. The capture is plotted below. The initial jaggedness is probably me just getting it situated in my hand. It shows the ~ correct number of counts. It looks like there's nothing wrong with the encoder.

the following plot is nearer when the motor is started and running faster. Seems like there's more activity. It does appear that the gap widens, 25 msec, near when the motor stops turning. Could more freq ISR events exacerbate a problem

thanks for the thoughtful response.

Your code says you are using microseconds, not milliseconds. Big difference.

Standard 16MHz Arduinos can only measure time in 4 microsecond steps. Switch to a faster one if you need better time resolution.

the code captures usec. the plot is in msec.