Measuring Pulse Width

@scorp84

I improved on my previous version, I rewrote the counting loop from a while do into a do while.

it seems to measure pulsewidths now in 5/16th (< 1/3) of a micro. Please confirm if my math / code is correct.

measure the count++ loop sketch

//
//    FILE: PulseWidthMeter.pde
//  AUTHOR: Rob Tillaart
//    DATE: 2012-mar-28
//
//    LINK: http://arduino.cc/forum/index.php?action=post;topic=96971.0
//

unsigned int count = 0;
void setup()
{
  Serial.begin(9600);
  Serial.println("pulse width meter 0.1");

  pinMode(3, INPUT);  
}

void loop()
{
  count = 0;
  while ((PIND & B00001000) == B00000000); // wait for HIGH
  unsigned long start = micros();
[color=red]  do count++;
  while (PIND & B00001000); // start counting until LOW[/color]
  unsigned long stop = micros();  

  Serial.print("CNT: ");
  Serial.println(count, DEC);
  Serial.print(stop-start, DEC);
  Serial.println(" microseconds ");
  Serial.print((1.0*count)/(stop-start), 3);
  Serial.println(" count per microseconds ");

  delay(1000);
}

Output:

CNT: 9264
2916 microseconds 
3.177 count per microseconds 
CNT: 27698
8712 microseconds 
3.179 count per microseconds 
CNT: 22776
7164 microseconds 
3.179 count per microseconds 
CNT: 11891
3744 microseconds 
3.176 count per microseconds 
CNT: 9634
3032 microseconds 
3.177 count per microseconds

results in ~3.178 counts per usec. => 1/3.178 = 0.3147 uSec/count
this implies 0.3147 x 16 = 5.035 => 5 instructions per loop instead of 6 in the previous version.
The 0.035 indicates a 0.7% error margin which is not too bad (probable causes the rounding of micros() 0.1-0.2% + crystal inaccuracy?).

[please confirm these measurements & math]

This results in a new 0.3 version of the pulseWidthMeter sketch:

//
//    FILE: PulseWidthMeter.pde
//  AUTHOR: Rob Tillaart
//    DATE: 2012-mar-28
//
//    LINK: http://arduino.cc/forum/index.php?action=post;topic=96971.0
//

unsigned int count = 0;
void setup()
{
  Serial.begin(9600);
  Serial.println("pulse width meter 0.3");

  pinMode(3, INPUT);  
}

void loop()
{
  count = 0;
  while ((PIND & B00001000) == B00000000); // wait for HIGH
  do count++;
  while (PIND & B00001000); // start counting until LOW

  float usec = 1.0 * count * 5/16;
 
  Serial.print("CNT: ");
  Serial.println(count, DEC);
  
  Serial.print(" equals ");
  Serial.print(usec, 2);
  Serial.println(" microseconds.");

  delay(1000);
}