Pages: [1]   Go Down
Author Topic: [SOLVED] precisely all 20 ms an interrupt - is this possible?  (Read 963 times)
0 Members and 1 Guest are viewing this topic.
Munich, Germany
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In the thread http://arduino.cc/forum/index.php/topic,97610.msg732311.html a generel solution for getting an timer based interrupt was given:

Code:
volatile boolean fired = false;

void setup()
{
  // CTC mode with clk/8 prescaler
  TCCR1A = 0;
  TCCR1B = 1<<WGM12 | 1<<CS11;
  
  TCNT1 = 0;         // reset counter
  OCR1A =  39999;       // compare A register value
  TIFR1 |= _BV (OCF1A);    // clear interrupt flag
  TIMSK1 = _BV (OCIE1A);   // interrupt on Compare A Match  
}

ISR (TIMER1_COMPA_vect)
{
    fired = true;
    TIFR1 = 1<<OCF1A;     // clear the Output Compare A Match Flag
}

void loop()
{
        while (! fired) { }  // waits for the next timer interrupt
        fired=false;         // clears the timer interrupt marker
        // ... do stuff here
}

This code indeed gives precisely all 20000 * 16 ticks a goo. But the ticks are not 1/16 us, as mentioned at other occassions already. Especially it was stated, that the millis() call has extra code to compensate for that.

So my question is, how one can achieve a real 20 ms goo. If lucky, we just have to change the 39999 to "something", but maybe the solution is to set it to 43123 in general, but each seventh time to 43128, just to give an example.

So if one has figured out this thing already, please let me know!
« Last Edit: May 07, 2012, 03:28:19 pm by Thomas33 » Logged

A mouse is a device to point at the xterm you want to type in.

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5145
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The timer is driven by the system clock which is in most cases very accurate. What people mean is the code for micros() where we have to take into account the clock cycles needed to add two (long) integers. This code is approximatively as exact as you clock source is.
Logged

Munich, Germany
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What people mean is the code for micros() where we have to take into account the clock cycles needed to add two (long) integers.

Really? The code shown above has 50 goos in around 0.9 seconds, so it is around 10% too fast. I thought the so called 16 MHz were actually around 10% off (of couse very preceice somehow 10 %).

How can it be then?
Logged

A mouse is a device to point at the xterm you want to type in.

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 207
Posts: 12921
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
ISR (TIMER1_COMPA_vect)
{
    fired = true;
//  TIFR1 = 1<<OCF1A;     // <<<<<<<<< REMOVE THIS LINE.  IT SERVES NO PURPOSE. <<<<<<<<<
}

This code indeed gives precisely all 20000 * 16 ticks a goo.

If that is true your processor is badly damaged and needs to be replaced (or the crystal is the wrong frequency or there is a design mistake).  As the code is written, fired is set true every 20 milliseconds for a processor running at 16 MHz.

Quote
So my question is, how one can achieve a real 20 ms goo.

The code you posted does exactly that.
Logged

Munich, Germany
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The code you posted does exactly that.

I just played around with that 39999, and the results were a bit suspicious. In the "do stuff here" part I do ethernet stuff. Can it be, that the ethernet (w5100) is using timer 1 too?
Logged

A mouse is a device to point at the xterm you want to type in.

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 207
Posts: 12921
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Can it be, that the ethernet (w5100) is using timer 1 too?

I don't know.  Someone else will have to answer that question.
Logged

Munich, Germany
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh my - I had a "bug" in my counting part. (I counted the arrived ethernet packets, but always got some "empty" packets too.)
Now it looks much better:

======================= Heartbeat 0 at 0.002 sec
======================= Heartbeat 500 at 9.968 sec
======================= Heartbeat 1000 at 19.977 sec
======================= Heartbeat 1500 at 29.986 sec
======================= Heartbeat 2000 at 39.994 sec
======================= Heartbeat 2500 at 50.002 sec
======================= Heartbeat 3000 at 60.011 sec
======================= Heartbeat 3500 at 70.019 sec
======================= Heartbeat 4000 at 80.028 sec
======================= Heartbeat 4500 at 90.037 sec
======================= Heartbeat 5000 at 100.045 sec
======================= Heartbeat 5500 at 110.054 sec
======================= Heartbeat 6000 at 120.063 sec
======================= Heartbeat 6500 at 130.071 sec
======================= Heartbeat 7000 at 140.080 sec

I think the remaining drift is within usual tolerance, hmm?
Logged

A mouse is a device to point at the xterm you want to type in.

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 207
Posts: 12921
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


If you are using a board with a resonator (like an Uno) then...

(((140.08000 - 130.07100) - 10) / 10) * 100 = 0.09

...0.09% error is very low.  (and I'm jealous.  I think my Uno has about a 1% error.)

If you are using a board with a crystal (like a Duemilanove) then 0.09% error is high.
Logged

Munich, Germany
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a mega2560. I think it is with crystal (the truth is hidden by the ethernet shield #-) )
However, this shall be good enough for my purpose.

Most of all: Thanks for sharing thoughts on this. Dragging me away from the believe, that it is not 16.000 MHz by design, was the push I needed! I'll mark it as solved :-)
Logged

A mouse is a device to point at the xterm you want to type in.

Pages: [1]   Go Up
Jump to: