microsecond interrupt?

Hi,

Is it possible to set an interrupt to go off every x number of microseconds? I've searched some and not found anything.

Or is there anyway to get something like a millis() function for micros? Right now I use 2 calls to millis and subtract the difference to get an approx microsend count.

Thanks.

the timer that drives millis() ticks every 4 microseconds, but only interrupts on overflows (256 ticks, which is "about" 1 millisecond.) Interrupting every microsecond would probably be a bad idea, but you can get a higher resolution clock by reading the timer and timer overflow directly instead of using millis(); I'll see if I can come up with a concise example.

This seems to work ok:

/*
 * High precision time demo
 */

extern volatile unsigned long timer0_overflow_count;

unsigned long hpticks (void)
{
    return (timer0_overflow_count << 8) + TCNT0;
}
void setup (void)
{
    Serial.begin(38400);
}

void loop (void)
{
    unsigned long hptime, mstime;

    if (Serial.read() > 0) {
        mstime = millis();
        hptime = hpticks()*4; // convert ticks to microseconds
        Serial.print("millis = ");
        Serial.print(mstime);
        Serial.print(",  high precision time = ");
        Serial.print(hptime);
        Serial.println(" ");
    }
}
And from the serial monitor:

millis = 2948,  high precision time = 2948816 
millis = 7030,  high precision time = 7031796 
millis = 17497,  high precision time = 17497508

awesome!

thanks very much for that function westfw. its pretty much exactly what i was looking for. here's a question:

what timespan do those ticks represent? from what i gather, they are about 4 usecs, is that right? i plan on using this function to determine when to send a pulse for a stepper that needs < 1 milli resolution, so hopefully it will work for that.

thanks!

nevermind... i posted that before i read the rest of your code. i think i got it now.

hey, just wanted to say thanks again for your help. with this function, i was able to get non-blocking stepper control working!!! if you've ever used the built-in stepper library for arduino, you know that its blocking... ie you either have to call each step manually, or just deal with waiting until the steps are done to do more stuff.

using this function, i made a class so that you simply do if(stepper.canStep()) stepper.step(); and the stepper will step at the appropriate time, at the appropriate RPM. this is nice because you can do things like control multiple steppers independently, etc.

more info, video, and code in blog post: http://builders.reprap.org/2007/11/non-blocking-stepper-control.html

This code doesn't seem to work any more. I get an error when compiling: undefined reference to 'timer0_overflow_count'

Any suggestions on how to fix this?

Thanks,
Mike

I managed to work out my own solution, but I'd still be interested in why timer0_overflow_count doesn't seem to exist anymore.

My code for the curious:

  double tElapsed=0;
  
  //Refer to document http://www.atmel.com/dyn/resources/prod_documents/doc7530.pdf
  TCCR1A=0; //set WGM mode to normal. Refer to table 15-4 of above doc
  TCCR1B=B100; //set prescaler = 256.  Refer to table 15-5 of above doc
  int prescaler=256;
  TCNT1=0; //set timer to 0. This is a 16 bit timer. Timer overflows at 1.048 seconds with prescaler=256

//...time an event or some code
  
  tElapsed = TCNT1*1.0/16E6*prescaler; //time in seconds

Hi MikeD,

Floating point is wasteful processing time (and memory) and should be avoided if possible in code that is time critical. Also, the code posted above uses a prescaler of 256 so with a 16mhz clock it can have an error of up to 127 microseconds.

Here is a thread that has a discussion on precise timing on the Arduino: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1226014847

I'd still be interested in why timer0_overflow_count doesn't seem to exist anymore.

The old timer0/millis() algorithms had a significant problem with integer overflows after sketches had been running for "a while." In 0012, the way times were calculated was changed to fix this, and in the process it eliminated the timer0_overflow_count()