Why different code order leads to different delay time and jitter time?

I have made a trigger generator for lamps with an Uno R3. It gets an trigger from external and generates a series of triggers by an interrupt subroutine. When I used a 'switch' statements to sort the Extrnal trigger, I found the delay time and the pulse jitter time of the generated trigger changed a lot. The delay time changed from 8us to 22us . The jitter time changed from 0.2us to 10us.

I tried to find what the problem is. And the 'switch' statements seems to be the reason:

  • a. When I don't use the 'switch', the delay time is 8us and the jitter time is 0.2us. (attached code : trigger_mod = 1)
  • b. When I use 'switch' and the code in 'case' stays the same, the delay time is 8us and the jitter time is 0.2us. (attached code : trigger_mod = 2)
  • c. When I use 'switch' and change the code even the code order, the delay time and the jitter time changes to 22us and 10us. (attached code : trigger_mod = 3)

The result of 'b' observated through oscilloscope is attached as 'same.jpg'
The result of 'c' observated through oscilloscope is attached as 'different.jpg'

It seems the difference of code order makes the trigger's delay time and jitter time change a lot. The question is why it is like this? I executive the same instructions, with only the code order different.
So why?

Thank you!

The code is attached.

The code is attached

Is it ?

UKHeliBob:
Is it ?

It is

// Trigger generator
// Get a trigger from Extrnal,and generate a serial of triggers by an interrupt subroutine. 	
// by Jiancun Wang 2016.4


int trigger_mod = 2; // Changes the mode of the generated triggers 

static int duration = 100;//last time for High level 
unsigned counter_self = 0;//variable for sorting the Extrnal trigger


static int time_0 = 1; //set delay time
static int intervalC_L = 1;   //delay time


const int lamp1 = 14;//set trigger pins
const int lamp2 = 15;
const int lamp3 = 16;

const int trigger_s = 3;//Interrupt source

void setup() {
  // put your setup code here, to run once:
//  Serial.begin(9600); //should be disable

  pinMode(lamp1,OUTPUT);
  pinMode(lamp2,OUTPUT);
  pinMode(lamp3,OUTPUT);
  TIMSK0 = TIMSK0 & B11111110;
  
  attachInterrupt(1, modChoose,RISING);//FALLING,RISING
  
}

void loop() 
{
 //  put your main code here, to run repeatedly:

}



//////////////////////////////////////////////


void modChoose()
{
 switch(trigger_mod)
 {
      case 1:mod1();break;
      case 2:mod2();break;
      case 3:mod3();break;
      case 4:mod4();break;
      default:break;
 }
 counter_self = counter_self + 1;
}




///////////////////////////////////////////////////////////////////


void mod4(void)
{;}

void mod1(void) //
{
  
  digitalWrite(lamp1,HIGH);
  digitalWrite(lamp2,HIGH);
  digitalWrite(lamp3,HIGH);
  delayMicroseconds(duration);
  digitalWrite(lamp1,LOW);
  digitalWrite(lamp2,LOW);
  digitalWrite(lamp3,LOW);

}

/////////////////////////////////////////////////

void mod2(void)
{
	  switch(counter_self%3)
	{
	case 1:
	  {
	  delayMicroseconds(time_0);
	  digitalWrite(lamp1,HIGH);
	  digitalWrite(lamp3,HIGH);
	  digitalWrite(lamp2,HIGH);
	  delayMicroseconds(intervalC_L);
	  delayMicroseconds(duration);
	  digitalWrite(lamp1,LOW);
	  digitalWrite(lamp2,LOW);
	  digitalWrite(lamp3,LOW);
	  }
	  break;
	case 2:
	  {
	   delayMicroseconds(time_0);
	  digitalWrite(lamp1,HIGH);
	  digitalWrite(lamp3,HIGH);
	  digitalWrite(lamp2,HIGH);
	  delayMicroseconds(intervalC_L);
	  delayMicroseconds(duration);
	  digitalWrite(lamp1,LOW);
	  digitalWrite(lamp2,LOW);
	  digitalWrite(lamp3,LOW);
	  }
	  break;
	case 0:
	  {
	  delayMicroseconds(time_0);
	  digitalWrite(lamp1,HIGH);
	  digitalWrite(lamp3,HIGH);
	  digitalWrite(lamp2,HIGH);
	  delayMicroseconds(intervalC_L);
	  delayMicroseconds(duration);
	  digitalWrite(lamp1,LOW);
	  digitalWrite(lamp2,LOW);
	  digitalWrite(lamp3,LOW);
	  }
	  break;
	}
}
 
 
 /////////////////////////////////////////////////

void mod3(void)
{
	  switch(counter_self%3)
	{
	case 1:
	  {
	  delayMicroseconds(time_0);
	  digitalWrite(lamp1,HIGH);
	  digitalWrite(lamp3,HIGH);
	  digitalWrite(lamp2,HIGH);
	  delayMicroseconds(intervalC_L);
	  delayMicroseconds(duration);
		  digitalWrite(lamp1,LOW);
	  digitalWrite(lamp2,LOW);
	  digitalWrite(lamp3,LOW);
	  }
	  break;
	case 2:
	  {
	   delayMicroseconds(time_0);
	  digitalWrite(lamp1,HIGH);
	  digitalWrite(lamp3,HIGH);
	  digitalWrite(lamp2,HIGH);
	  delayMicroseconds(intervalC_L);
		delayMicroseconds(duration);
	  digitalWrite(lamp1,LOW);
	  digitalWrite(lamp2,LOW);
	  digitalWrite(lamp3,LOW);
	  }
	  break;
	case 0:
	  {
	  delayMicroseconds(time_0);
	  digitalWrite(lamp3,HIGH);
	  digitalWrite(lamp2,HIGH);
	  digitalWrite(lamp1,HIGH);
	  delayMicroseconds(intervalC_L);
	  delayMicroseconds(duration);
	  digitalWrite(lamp1,LOW);
	  digitalWrite(lamp2,LOW);
	  digitalWrite(lamp3,LOW);
	  }
	  break;
	}
}

try using different pins like 9,10,11 which are all the same type

AxeMurderer:
try using different pins like 9,10,11 which are all the same type

The result shows the same problem. The only difference is that jitter time from pin 9 is about 15us but pin 10,11 are 8us.
Also I detected the jitter times of pin 14,15,16 again. The jitter time from pin 14 is 10us but pin 15,16 is about 6us.
So, maybe PWM pin affect the pulse jitter time. But this could not explain why the difference of code order leads to different jitter time.

have you tried direct port manipulation?

PORTD = B10101000; // sets digital pins 7,5,3 HIGH

much faster

BulldogLowell:
have you tried direct port manipulation?

PORTD = B10101000; // sets digital pins 7,5,3 HIGH

much faster

Why pin 7,5,3? If I use your code, should I genenate the triggers by PORTx? Maybe this is another way to achieve my purpose,I'll try. The phenomenon I showed is so weird, how to explain it?

Thank you!

what do you mean here:

a. When I don't use the 'switch', the delay time is 8us and the jitter time is 0.2us. (attached code : trigger_mod = 1)
b. When I use 'switch' and the code in 'case' stays the same, the delay time is 8us and the jitter time is 0.2us. (attached code : trigger_mod = 2)

can you show the comparative code?

BulldogLowell:
what do you mean here:

can you show the comparative code?

These showed what I did in 3 ways(3 different mode,they are mod1(),mod2(),mod3().)
The comparative code is on the floor 2

osler:
These showed what I did in 3 ways(3 different mode,they are mod1(),mod2(),mod3().)
The comparative code is on the floor 2

For another way, I tried your suggestion. The jitter time reduced to 0.5us,a litter bigger than 0.2us which is what I wanted. And the delay time is about 18us. While if the code is all the same in 'case' statement,the delay time is about 4us.
I need to chang the flash order of lamps, so the code could not be the same.

The code of your suggestion is below:

// Trigger generator
// Get a trigger from Extrnal,and generate a serial of triggers by an interrupt subroutine. 	
// by Jiancun Wang 2016.4


int trigger_mod = 2; // Changes the mode of the generated triggers 

static int duration = 100;//last time for High level 
unsigned counter_self = 0;//variable for sorting the Extrnal trigger


static int time_0 = 1; //set delay time
static int intervalC_L = 1;   //delay time


const int trigger_s = 3;//Interrupt source

void setup() {
  // put your setup code here, to run once:
//  Serial.begin(9600); //should be disable

  TIMSK0 = TIMSK0 & B11111110;
  DDRC = B00000111;
  attachInterrupt(1, modChoose,RISING);//FALLING,RISING
  
}

void loop() 
{
 //  put your main code here, to run repeatedly:

}



//////////////////////////////////////////////


void modChoose()
{
 switch(trigger_mod)
 {
      case 1:mod1();break;
      case 2:mod2();break;
      case 3:mod3();break;
      case 4:mod4();break;
      default:break;
 }
 counter_self = counter_self + 1;
}




///////////////////////////////////////////////////////////////////


void mod4(void)
{;}

void mod1(void) //
{
  PORTC = B00000111;
//  digitalWrite(lamp1,HIGH);
 // digitalWrite(lamp2,HIGH);
 // digitalWrite(lamp3,HIGH);
  delayMicroseconds(duration);
 // digitalWrite(lamp1,LOW);
 // digitalWrite(lamp2,LOW);
 // digitalWrite(lamp3,LOW);
  PORTC = B00000000;
}

/////////////////////////////////////////////////

void mod2(void)
{
	  switch(counter_self%3)
	{
	case 1:
	  {
	 PORTC = B00000111;
//  digitalWrite(lamp1,HIGH);
 // digitalWrite(lamp2,HIGH);
 // digitalWrite(lamp3,HIGH);
  delayMicroseconds(duration);
 // digitalWrite(lamp1,LOW);
 // digitalWrite(lamp2,LOW);
 // digitalWrite(lamp3,LOW);
  PORTC = B00000000;
	  }
	  break;
	case 2:
	  {
	   PORTC = B00000111;
//  digitalWrite(lamp1,HIGH);
 // digitalWrite(lamp2,HIGH);
 // digitalWrite(lamp3,HIGH);
  delayMicroseconds(duration);
 // digitalWrite(lamp1,LOW);
 // digitalWrite(lamp2,LOW);
 // digitalWrite(lamp3,LOW);
  PORTC = B00000000;
	  }
	  break;
	case 0:
	  {
	  PORTC = B00000111;
//  digitalWrite(lamp1,HIGH);
 // digitalWrite(lamp2,HIGH);
 // digitalWrite(lamp3,HIGH);
  delayMicroseconds(duration);
 // digitalWrite(lamp1,LOW);
 // digitalWrite(lamp2,LOW);
 // digitalWrite(lamp3,LOW);
  PORTC = B00000000;
	  }
	  break;
	}
}
 
 
 /////////////////////////////////////////////////

void mod3(void)
{
	  switch(counter_self%3)
	{
	case 1:
	  {
	  PORTC = B00000111;
//  digitalWrite(lamp1,HIGH);
 // digitalWrite(lamp2,HIGH);
 // digitalWrite(lamp3,HIGH);
  delayMicroseconds(duration);
 // digitalWrite(lamp1,LOW);
 // digitalWrite(lamp2,LOW);
 // digitalWrite(lamp3,LOW);
  PORTC = B00000000;
	  }
	  break;
	case 2:
	  {
	  PORTC = B00000101;
//  digitalWrite(lamp1,HIGH);
 // digitalWrite(lamp2,HIGH);
 // digitalWrite(lamp3,HIGH);
  delayMicroseconds(duration);
 // digitalWrite(lamp1,LOW);
 // digitalWrite(lamp2,LOW);
 // digitalWrite(lamp3,LOW);
  PORTC = B00000000;
	  }
	  break;
	case 0:
	  {
	   PORTC = B00000011;
//  digitalWrite(lamp1,HIGH);
 // digitalWrite(lamp2,HIGH);
 // digitalWrite(lamp3,HIGH);
  delayMicroseconds(duration);
 // digitalWrite(lamp1,LOW);
 // digitalWrite(lamp2,LOW);
 // digitalWrite(lamp3,LOW);
  PORTC = B00000000;
	  }
	  break;
	}
}

This is relatively interesting:
You'll note that only mod3() is doing the modulus operation (and slowly at that!) for one of your modN routines. I guess that makes sense - the cases in mod2() are all identical, so the compiler optimizes away the test! That certainly explains the low jitter...

I suggest some things need to be "volatile", and your modulous operations be replaced with bitwise and (if they can be.):

volatile uint8_t counter_self = 0;
   :
void mod3(void)
{
   switch(counter_self & 3)
  {
void mod1(void) //
{
  digitalWrite(lamp1,HIGH);
 128:    61 e0           ldi    r22, 0x01    ; 1
 12a:    8e e0           ldi    r24, 0x0E    ; 14
 12c:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
  digitalWrite(lamp2,HIGH);
 130:    61 e0           ldi    r22, 0x01    ; 1
 132:    8f e0           ldi    r24, 0x0F    ; 15
 134:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
  digitalWrite(lamp3,HIGH);
 138:    61 e0           ldi    r22, 0x01    ; 1
 13a:    80 e1           ldi    r24, 0x10    ; 16
 13c:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
  delayMicroseconds(duration);
 140:    84 e6           ldi    r24, 0x64    ; 100
 142:    90 e0           ldi    r25, 0x00    ; 0
 144:    0e 94 eb 01     call    0x3d6    ; 0x3d6 <delayMicroseconds>
  digitalWrite(lamp1,LOW);
 148:    60 e0           ldi    r22, 0x00    ; 0
 14a:    8e e0           ldi    r24, 0x0E    ; 14
 14c:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
  digitalWrite(lamp2,LOW);
 150:    60 e0           ldi    r22, 0x00    ; 0
 152:    8f e0           ldi    r24, 0x0F    ; 15
 154:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
  digitalWrite(lamp3,LOW);
 158:    60 e0           ldi    r22, 0x00    ; 0
 15a:    80 e1           ldi    r24, 0x10    ; 16
 15c:    0c 94 93 02     jmp    0x526    ; 0x526 <digitalWrite>

00000160 <mod2()>:
   digitalWrite(lamp3,LOW);
   }
   break;
  case 0:
   {
   delayMicroseconds(time_0);
 160:    81 e0           ldi    r24, 0x01    ; 1
 162:    90 e0           ldi    r25, 0x00    ; 0
 164:    0e 94 eb 01     call    0x3d6    ; 0x3d6 <delayMicroseconds>
   digitalWrite(lamp1,HIGH);
 168:    61 e0           ldi    r22, 0x01    ; 1
 16a:    8e e0           ldi    r24, 0x0E    ; 14
 16c:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
   digitalWrite(lamp3,HIGH);
 170:    61 e0           ldi    r22, 0x01    ; 1
 172:    80 e1           ldi    r24, 0x10    ; 16
 174:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
   digitalWrite(lamp2,HIGH);
 178:    61 e0           ldi    r22, 0x01    ; 1
 17a:    8f e0           ldi    r24, 0x0F    ; 15
 17c:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
   delayMicroseconds(intervalC_L);
 180:    81 e0           ldi    r24, 0x01    ; 1
 182:    90 e0           ldi    r25, 0x00    ; 0
 184:    0e 94 eb 01     call    0x3d6    ; 0x3d6 <delayMicroseconds>
   delayMicroseconds(duration);
 188:    84 e6           ldi    r24, 0x64    ; 100
 18a:    90 e0           ldi    r25, 0x00    ; 0
 18c:    0e 94 eb 01     call    0x3d6    ; 0x3d6 <delayMicroseconds>
   digitalWrite(lamp1,LOW);
 190:    60 e0           ldi    r22, 0x00    ; 0
 192:    8e e0           ldi    r24, 0x0E    ; 14
 194:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
   digitalWrite(lamp2,LOW);
 198:    60 e0           ldi    r22, 0x00    ; 0
 19a:    8f e0           ldi    r24, 0x0F    ; 15
 19c:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
   digitalWrite(lamp3,LOW);
 1a0:    60 e0           ldi    r22, 0x00    ; 0
 1a2:    80 e1           ldi    r24, 0x10    ; 16
 1a4:    0c 94 93 02     jmp    0x526    ; 0x526 <digitalWrite>

000001a8 <mod3()>:
 
 /////////////////////////////////////////////////

void mod3(void)
{
   switch(counter_self%3)
 1a8:    80 91 06 01     lds    r24, 0x0106
 1ac:    90 91 07 01     lds    r25, 0x0107
 1b0:    63 e0           ldi    r22, 0x03    ; 3
 1b2:    70 e0           ldi    r23, 0x00    ; 0
 1b4:    0e 94 d9 02     call    0x5b2    ; 0x5b2 <__udivmodhi4>
 1b8:    81 30           cpi    r24, 0x01    ; 1
 1ba:    91 05           cpc    r25, r1
 1bc:    11 f0           breq    .+4          ; 0x1c2 <mod3()+0x1a>
 1be:    02 97           sbiw    r24, 0x02    ; 2
 1c0:    79 f4           brne    .+30         ; 0x1e0 <mod3()+0x38>
   digitalWrite(lamp3,LOW);
   }
   break;
  case 2:
   {
    delayMicroseconds(time_0);
 1c2:    81 e0           ldi    r24, 0x01    ; 1
 1c4:    90 e0           ldi    r25, 0x00    ; 0
 1c6:    0e 94 eb 01     call    0x3d6    ; 0x3d6 <delayMicroseconds>
   digitalWrite(lamp1,HIGH);
 1ca:    61 e0           ldi    r22, 0x01    ; 1
 1cc:    8e e0           ldi    r24, 0x0E    ; 14
 1ce:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
   digitalWrite(lamp3,HIGH);
 1d2:    61 e0           ldi    r22, 0x01    ; 1
 1d4:    80 e1           ldi    r24, 0x10    ; 16
 1d6:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
   digitalWrite(lamp2,HIGH);
 1da:    61 e0           ldi    r22, 0x01    ; 1
 1dc:    8f e0           ldi    r24, 0x0F    ; 15
 1de:    0e c0           rjmp    .+28         ; 0x1fc <mod3()+0x54>
   digitalWrite(lamp3,LOW);
   }
   break;
  case 0:
   {
   delayMicroseconds(time_0);
 1e0:    81 e0           ldi    r24, 0x01    ; 1
 1e2:    90 e0           ldi    r25, 0x00    ; 0
 1e4:    0e 94 eb 01     call    0x3d6    ; 0x3d6 <delayMicroseconds>
   digitalWrite(lamp3,HIGH);
 1e8:    61 e0           ldi    r22, 0x01    ; 1
 1ea:    80 e1           ldi    r24, 0x10    ; 16
 1ec:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
   digitalWrite(lamp2,HIGH);
 1f0:    61 e0           ldi    r22, 0x01    ; 1
 1f2:    8f e0           ldi    r24, 0x0F    ; 15
 1f4:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
   digitalWrite(lamp1,HIGH);
 1f8:    61 e0           ldi    r22, 0x01    ; 1
 1fa:    8e e0           ldi    r24, 0x0E    ; 14
 1fc:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
   delayMicroseconds(intervalC_L);
 200:    81 e0           ldi    r24, 0x01    ; 1
 202:    90 e0           ldi    r25, 0x00    ; 0
 204:    0e 94 eb 01     call    0x3d6    ; 0x3d6 <delayMicroseconds>
   delayMicroseconds(duration);
 208:    84 e6           ldi    r24, 0x64    ; 100
 20a:    90 e0           ldi    r25, 0x00    ; 0
 20c:    0e 94 eb 01     call    0x3d6    ; 0x3d6 <delayMicroseconds>
   digitalWrite(lamp1,LOW);
 210:    60 e0           ldi    r22, 0x00    ; 0
 212:    8e e0           ldi    r24, 0x0E    ; 14
 214:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
   digitalWrite(lamp2,LOW);
 218:    60 e0           ldi    r22, 0x00    ; 0
 21a:    8f e0           ldi    r24, 0x0F    ; 15
 21c:    0e 94 93 02     call    0x526    ; 0x526 <digitalWrite>
   digitalWrite(lamp3,LOW);
 220:    60 e0           ldi    r22, 0x00    ; 0
 222:    80 e1           ldi    r24, 0x10    ; 16
 224:    0c 94 93 02     jmp    0x526    ; 0x526 <digitalWrite>

00000228 <modChoose()>:
//////////////////////////////////////////////

westfw:
This is relatively interesting:
You'll note that only mod3() is doing the modulus operation (and slowly at that!) for one of your modN routines. I guess that makes sense - the cases in mod2() are all identical, so the compiler optimizes away the test! That certainly explains the low jitter...

I suggest some things need to be "volatile", and your modulous operations be replaced with bitwise and (if they can be.):

volatile uint8_t counter_self = 0;

:
void mod3(void)
{
  switch(counter_self & 3)
  {

I'm very happy that when I defined counter_self as volatile uint_8 the delay time deduced about 5us. And when I do the modulus operation by counter_self & 3 ,another 5us was reduced. But the jitter time seems to be the same.

I will follow your ASM code. I need to learn more to get a better understanding.
Thank you!

I will follow your ASM code.

Not mine; that was what the compiler generated from your code (find the .elf file and avr-objdump, and do "avr-objdump -SC file.elf"

Note that it's not necessary to fully understand the assembly language to get useful info from the listing. The lack of the modulus operator was pretty glaring.

What exactly are you calling "jitter"?

The code will probably get noticeably faster if you cram all the cases into the ISR function itself. avr-gcc has to use a much longer "function prologue" if the ISR calls another function.

westfw:
Not mine; that was what the compiler generated from your code (find the .elf file and avr-objdump, and do "avr-objdump -SC file.elf"

Note that it's not necessary to fully understand the assembly language to get useful info from the listing. The lack of the modulus operator was pretty glaring.

What exactly are you calling "jitter"?

The code will probably get noticeably faster if you cram all the cases into the ISR function itself. avr-gcc has to use a much longer "function prologue" if the ISR calls another function.

'jitter' means the rising edge of a pulse is not at a constant time point. It will be a little faster or slower and it changes randomly.

unsigned counter_self = 0;//variable for sorting the Extrnal trigger

Since you are changing that in an ISR, it should be declared volatile.

Thank you! I will pay attention to it. :slight_smile:

'jitter' means the rising edge of a pulse

I know what it means, formally. What I want to know is where you're measuring the jitter - between different instances of the trigger pulse and a particular output pulse? Between different outputs? And over what sort of time frames? The other Arduino interrupts (Serial, millis) can introduce quite a bit of jitter in ISR response (but I don't think it should vary by
setting of trigger_mod) Is the trigger source at a steady frequency (60Hz zero-crossing)?

Note that many instances of a case statement will compile to the equivalent of:

if (a == CONST1) {
  // LAMP1
} else if (a == CONST2) {
  // LAMP2
} else if (a == CONST3) {
  // LAMP3
} else {
  // default
}

So it's normal for the delay to light lamp3 to be different from the delay to light lamp1.
(The compiler will build a jump table for large and dense case statements when it decides that that will be "better." I don't think there is any way to force time-invariant cases.)

BTW, I noticed that "x % 3" is NOT the same as "x & 3" (blush; it's the same as "x % 4") - but avoiding the divide if you can is a good idea!

Things have changed enough that it's probably time to post new code and scope shots if we're continuing...

Thank you, westfw! The jitter time is between the external trigger and output pulses. The trigger source is steady of about 400Hz. I have found that maybe it's not so serious for my application, because what I care is the flash order and interval time between servel lamps.

Thank you again for your explain about the puzzle of different code order leading to different delay time and jitter time. I have learn a lot!

westfw:
I know what it means, formally. What I want to know is where you're measuring the jitter - between different instances of the trigger pulse and a particular output pulse? Between different outputs? And over what sort of time frames? The other Arduino interrupts (Serial, millis) can introduce quite a bit of jitter in ISR response (but I don't think it should vary by
setting of trigger_mod) Is the trigger source at a steady frequency (60Hz zero-crossing)?