Pages: [1]   Go Down
Author Topic: Timing the little things  (Read 1200 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 0
Posts: 203
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have stumbled several times now by poorly guessing how long a function takes. I suspect others have as well. For example, I see people looking for help debugging code that measures a couple of microseconds between digitalWrite() calls, neglecting that these calls take something near 10 microseconds each.

Here is a way to very accurately time how many clock cycles a tiny operation takes without an oscilloscope.

Code:
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  unsigned long loops = 0;

  // TCNT0 is the timer used to compute milliseconds and drive PWM0.
  // It is an 8 bit value that increments every 64 clock cycles and
  // rolls over from 255 to 0.
  //
  // We repeatedly run the test code as the timer goes from 156 through 255
  // which gives use 64*100 clock cycles.
  //
  // In practice this works for timing operations that take from 1 to
  // hundreds of clock cycles. The results get a little chunky after that
  // since the last one will have gone a fair bit past the end period.
  //
  while( TCNT0 != 155);        // wait for 155 to start
  while( TCNT0 == 155);        // wait until 155 ends
  
  cli(); // turn off interrupts
  while( TCNT0 > 150 ) {       // that 150 acknowledges we may miss 0
    // vvvvvv---- your code to be timed
    digitalWrite(7,1);
    // ^^^^^^---- your code to be timed
    loops++;
  }
  sei(); // turn interrupts back on
  
  Serial.print("loops: ");
  Serial.print(loops,DEC);
  Serial.print(" clocks: ");
  Serial.print( (int) (( 100UL*64UL) / loops) - 8 /* empty loop cost */, DEC);
  Serial.println();

  delay(500);
}

Run that and watch your serial monitor at 9600 bps and you will see how many clock cycles a digitalWrite() takes.

The interesting section is where I have a digitalWrite(). You would replace that line with something you cared to time. If it is a simple computation you will have to be careful that it doesn't get optimized away. Assigning the result to a "volatile" variable and using "volatile" variables as inputs is a good tactic, but it can still do tricky things with your constants.

(I made this because I was dismayed at how slow digitalWrite() was. I've recoded it and it is now much faster, smaller, and saves 100+ bytes of RAM. I'll write about that in another entry.)
Logged

Pages: [1]   Go Up
Jump to: