UNO Timer jitter

Hi,

I am trying to understand if what I am observing is being generated by the UNO or is an oscilloscope artefact.

  • I have 2 identical UNOs called Unit 1 and Unit 2.
  • They are set up with identical trivial programs that entirely confine the UNO to timer 1 CMP1A interrupt service routine (). Nominally set to a period of 25us (OCR1A = 399) but I have tried periods 5us up.
  • they do not use any library software whatever (this is important).
  • my test ISR simply toggles PIN13 in both Units.
  • Unit 1 PIN13 upper trace.
  • Unit 2 PIN13 lower trace.
    Both are independent, identical and their clocks should be very similar. But as you'd predict Unit 2 XTAL seems to be ever so slightly faster and the bottom scope trace trundles to the left when the upper trace scope is set to trigger (Channel 1 rising edge). They are clearly not phase-locked.

Fine: BUT

What I also observe is a 8ish microsecond jitter on the (Unit 2) lower trace that is on top of the gradual leftwards motion of the lower trace.

I have attached:

  1. The code (same for both)
  2. A JPEG of the wiring.
  3. A bitmap of the scope screen
  4. A video of the scope screen (.mp4)

I read somewhere here there's a system interrupt on a 8 or 10us basis, so my suspicions are raised that there's a relative jitter phenomenon going between the two asynchronous units.

But I can't tell if I'm being led astray by the oscilloscope.

If you play with the TIMR1 setting (various periods) the same 8us-ish duration jitter happens on Unit 2 while Unit 1 trace is rock solid.

I'd appreciate an appraisal by someone that has battled the timer jitter in the past....

Thanks!

Colin Hales

Exp002_08_TOGGLE_ONLY.ino.txt (965 Bytes)

Having trouble with attachments. The .MP4 is apparently too big (6MB)

Here's the scope JPG with timer set to 10us.

cheers
colin

TIMER1 10us.jpg

Firing an ISR every 8uS is fairly aggressive could the jitter be caused by the millis() interrupt firing? Try disabling the timer0 overflow interrupt (this will of course break millis(), delay, and the like)

Does the jitter occur if using the timer for hardware PWM (ie, output compare) instead of relying on an ISR to toggle the pin?

This may be due to millis()

DrAzzy got there first.
.

Dr Azzy & Larry D,

I have played with PWM some time back and as I remember there was 10us jitter.

I played with ISRs at 5, 10, 20, 25 and 30us and found the jitter continued and added the same 10us fuzz to the trace.

I'll experiment with disabling other interrupts and see if I can find anything.

I'll let you know what I find.

cheers
Colin

OK. The software as I posted it (see .TXT file) left the timer/counter interrupts as follows:

TEST #1
Detect actual timer interrupt masks. These were inspected and found to be:

TIMSK0 = 0b00000000
TIMSK1 = 0b00000010
TIMSK2 = 0b00000000

The bolded bits within the mask are are (Bit 2) OCIEnB, (Bit 1) OCIEnA, (Bit 0) TOIEn within the mask. n = 0,1,2 for timer 0 1,2. None of the remaining bits are used.

I am using timer 1 channel A compare, which uses OCIE1A, so this is exactly what I'd expect. I have no calls to any library software, so millis() functions should not be co-opting any timer/counter function.

TEST #2

I disabled global interrupts insider the ISR as follows (both UNO units). Under this condition, the entire ISR is as follows:

SREG &= 0b01111111; // mask
PORTB ^= 0b00100000; // toggle output port PIN13
SREG |= 0b10000000; // remove mask

This had no effect. The jitter remains.

Q. Is there any residual timing interference maybe due to the provision of serial comms for the IDE?
Q. Is there any residual timing interference maybe due to the calling of the main/loop?

Any other ideas (like scope artefact, as I originally asked)?

I just need to know if this is real and its origins. Once I know I can then work with it and know what I am observing.

cheers
colin

Serious question here:

The two clocks are running asynchronously. Why would you expect any sort of phase lock between them in any way whatsoever?

Get out the logic analyzer and look at the two channels in a time domain that is not locked to one clock as it is with the scope. There, any and all jitter will be apparent if the sample rate is high enough. I used this method today to find that my ISR was taking 105 clocks about 95% of the time, the remaining 5%, there was a variation of anywhere from 15 to 40 additional clocks required at some timer rollovers where the ISR updated several 16 bit values.

Now, OTH, if you had an external clock supplying both boards, I would expect the outputs from both boards to remain sync'ed.

I'm not expecting perfect synchrony between the arduinos/clocks.

What I expected was to see the output signal on each unit drift by (with respect to the other) as a clean waveform due to their tiny difference in XTAL frequency, not additionally phase-precess forward and jump back in phase with an overall average frequency.

That is, I didn't expect to see (what I expected) + (jitter superimposed).

I don't like mysteries. I'm doing science, not building a gizmo. It's important I can have an accurate story about performance.

I'll see what I can do about an independent scope or generator or something else that might shed some light on the matter.

Meanwhile if you or anyone else has some guidance as to the potential origins of such an effect that'd be cool.

thanks!

colin

Okay, it's science you want...

So start with a known. Disable interrupts and toggle a port pin using direct port access on both boards and compare what should be unchanging clock timed pulses. That should show you what the frequency difference does to your scope display. I think you'll see that a very minor difference in clock frequency creates only one viewable/locked/sync'ed/triggered signal on a dual trace scope. You'll never see the second pulse until it is the trigger source then the first signals visibility will be lost.

I'm on a tablet so it's a little tough to provide examples but you should be able to find direct port pin manipulation on this sites' example code area with Google.

BionicBrain:
Q. Is there any residual timing interference maybe due to the provision of serial comms for the IDE?

Serial communications for Arduino AVR boards is interrupt driven. That will interfere with other interrupt service routines.

Q. Is there any residual timing interference maybe due to the calling of the main/loop?

I assume you are asking if anything in main interferes with interrupt service routines. The answer is no.

I have played with PWM some time back and as I remember there was 10us jitter.

Your memory has failed you.

Final Report

I used a separate signal generator instrument (square wave) as an external trigger reference on the oscilloscope. This was accepted for, purposes here, as a phase-jitterless reference.

Under these conditions (for two different UNO timer settings), adjusting the reference trigger frequency down to around 19984+/-3 Hz (instead of the expected 20KHz) and 49950+/-5 Hz (instead of the expected 50kHz) ...I was able to stabilise and reverse the asynchrony-drift on the two channels of the scope. It reveals that the two UNOS are different by a few Hz (XTAL clock) and that the timer setting maths is not quite right. It does not produced the frequency expected.

The important result, however, is that under these conditions the apparent jitter could be reduced or increased based on the disparity in frequency between the reference and the timer-based interrupt signals from the two arduino UNOs. As the drift increases the jitter appears to increase.

This behaviour can be explained as a scope artefact.

Although it is never explained anywhere in the scope manuals, the scope display appears to present more than one set of samples (approximately 10 sets?) on the screen. It then appears to clear and start again. The effect, for asynchronous but nearly frequency-matched signals is that the relative drift between signal and a trigger-stabilised reference is captured and displayed multiple times on the screen. The repetition rate of this refresh cycle and the signals themselves creates a jitter effect in the presentation on the screen that does not exist in reality.

The back story on this is that in the real system I am exploring there were 3 different jitters, all confusingly intermixed. This is closure (I hope) on the third of the three.

As far as I can tell, if I discount the scope effect, the jitter on the timer interrupt calls is down around the duration of 1 or 2 processor instruction cycles.

BTW I tracked down and checked most of the interrupt-enables and mask settings. At no time did I find any active USART interrupts (I was not using serial comms at any time except when uploading to the UNO). If I reset the global mask in SREG it shut my timer-interrupt down as expected.

thanks.

Colin

Welcome to the real world - it never matches theory.

Some of the problem will be due to the timer interrupts taking place at different points in the rest of the code. Interrupts MUST wait until the current instruction is completed and not all instructions take the same number of clocks. In addition the interrupts will take place at different points in the code.

Try it using

L1: goto L1;

instead of letting the code go round loop()

Hope I got the goto code right 35 years of writing C and it's the first time I found a use for goto!

Mark

Jitter is a big problem when trying to get a 14KHz square wave. MP4 zipped video attached.

This is the code:

#include <TimerThree.h> // inyectores
#define pulso_O2 7

void setup() {
Serial.begin(9600);
Timer3.initialize(35); // para 6 grados y 100 rpm

// Pines salida
pinMode(pulso_O2, OUTPUT);
Timer3.attachInterrupt(timer_4cil);
}

void timer_4cil()
{
digitalWrite(pulso_O2, digitalRead(pulso_O2) ^ 1);
}

void loop()
{
static int i=0;
Serial.println(++i);
delay(1000);
}

WhatsApp Video 2018-10-22 at 11.57.03.zip (1.55 MB)