Arduino Timer Precision I am using the ATMega32u4 to generate multiple pulses at 2.5 kHz. I am using Timer 3, which is a 16-bit timer and using a prescaler of 1, so I have a 0.0625uS resolution. I want to generate pulses with pretty high accuracy and consistency. I have my previous post here, which gave me accuracy. But when I look at the pulse with my oscilloscope it has some jitter. Youtube Video of Jitter.

My final goal is to create a pulse on multiple different pins in this configuration.


What I am assuming is that the reason there is jitter is that there are other interrupts going on in the background, that could be shifting when the pulse stops and starts by a few microseconds. Looking through the datasheet, I found this, which seems to show interrupt priority.


It seems that my TIMER3 COMPA and COMPB are very low down the list of priorities, is there a way to change this priority list? Or is there something else that is causing the jitter?

I have posted my code below:

#define pin2 12
#define pin3 6
#define pin4 8

#define REFRESH 6400

int PULSEIndex;

class Pulse {
  public:
    int pulseLength;
    void Begin(byte GPIO_PIN) {
      pinMode(GPIO_PIN, OUTPUT);
    }
    void writeMicro(double pulse) {
      pulseLength = (pulse * 16);
    }
};

Pulse PULSE1;
Pulse PULSE2;
Pulse PULSE3;
Pulse PULSE4;

void setup() {
  PULSE1.Begin(pin1);
  PULSE2.Begin(pin2);
  PULSE3.Begin(pin3);
  PULSE4.Begin(pin4);

  // Reset Timer 3 Control Register to 0
  TCCR3A = 0;
  TCCR3B = 0;

  // Set CTC Mode
  TCCR3B &amp;= ~(1 &lt;&lt; WGM33); //0
  TCCR3B |= (1 &lt;&lt; WGM32);  //1

  // Set prescaler to 1
  TCCR3B &amp;= ~(1 &lt;&lt; CS32); //0
  TCCR3B &amp;= ~(1 &lt;&lt; CS31); //0
  TCCR3B |= (1 &lt;&lt; CS30);  //1

  //Reset Timer 3 and set compare value
  TCNT3 = 0;

  // Enable Timer 3 compare interrupt A and B
  TIMSK3 |= (1 &lt;&lt; OCIE3B);
  TIMSK3 |= (1 &lt;&lt; OCIE3A);

  //Enable global interrupts
  sei();

  //Set Refresh Rate
  OCR3A = REFRESH;
  OCR3B = 1000;
}

void loop() {
  PULSE1.writeMicro(40);
  PULSE2.writeMicro(40);
  PULSE3.writeMicro(40);
  PULSE4.writeMicro(40);
  delay(2);
}

ISR(TIMER3_COMPA_vect) {
  digitalWrite(pin1, HIGH);
  OCR3B = PULSE1.pulseLength;
}

ISR(TIMER3_COMPB_vect) {

  if (PULSEIndex == 1) {
    digitalWrite(pin1, LOW);
    digitalWrite(pin2, HIGH);
    OCR3B += PULSE2.pulseLength;
  }

  if (PULSEIndex == 2) {
    digitalWrite(pin2, LOW);
    digitalWrite(pin3, HIGH);
    OCR3B += PULSE3.pulseLength;
  }

  if (PULSEIndex == 3) {
    digitalWrite(pin3, LOW);
    digitalWrite(pin4, HIGH);
    OCR3B += PULSE4.pulseLength;
  }

  if (PULSEIndex == 4) {
    digitalWrite(pin4, LOW);
  }

  PULSEIndex++;
  if (PULSEIndex &gt; 4) PULSEIndex = 1;
} ```
What I am assuming is that the reason there is jitter is that
  there are other interrupts going on in the background


This seems like a reasonable assumption. Since you are not doing serial
communication, the Timer 0 interrupt is likely the only one triggering
in the background. You can disable it with:

TIMSK0 = 0;


but then all the Arduino timing functions will stop working. You will
have to #include &lt;util/delay.h&gt; and replace delay() with
_delay_ms(). Note that this avr-libc function only works with
compile-time constant delays. On the other hand, it is cycle-accurate
and accepts floating point delays.


  is there a way to change this priority list?


There is not, and even if this was possible, it would not be that
useful. Interrupts in the Arduino are not interruptible: if a
low-priority interrupt is running when a high-priority one triggers, the
high-priority interrupt has to wait for the currently running one to
terminate. Priorities are only relevant when the processor is about to
serve an interrupt request but has to decide which one, among several
pending requests, it will serve first.

Now, a small remark about this:

void loop() {
  PULSE1.writeMicro(40);
  PULSE2.writeMicro(40);
  PULSE3.writeMicro(40);
  PULSE4.writeMicro(40);
  delay(2);
}


There is no point in rewriting those values over and over again. If you
plan to change the code in order to make those widths non-constant, then
you have to take care to:


make the pulseLength properties (or the whole Pulse objects)
volatile
within writeMicro(), disable interrupts while changing
pulseLength.