Go Down

Topic: Code Correction (Read 1 time) previous topic - next topic


Mar 30, 2012, 04:40 pm Last Edit: Mar 30, 2012, 05:29 pm by scorp84 Reason: 1
Hello Everyone the code given below is used for pulse width measurement for pulses as short as 5 to 5 microseconds which I am giving to arduino from function generator. The code makes almost 3 counts every 3 microsecond which is not good since the count should be much more for a 16MHz clock frequency of arduino so if anyone can help me with this in achieving the correct counts every microsecond.

Thank you all in advance!

Code: [Select]


unsigned int pulse_counts = 0;

unsigned int count = 0;
void setup()
 pinMode(3, INPUT);  

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

 float usec = 1.0 * count * 6/12;
 Serial.print("Count = ");
 Serial.print(" , Width = ");
 Serial.print(usec, 2);
 Serial.println ("  microseconds");

//  delay(1000);


Please use the code tags to properly format your code.

So bascially you say you need ~1 microsecond per count. Let's see what I would expect the while loop to translate to:

reading pin
and operation
compare operation
branch operation
increment two byte integer
jump operation

--> I would not expect much more from this code. I suggest to use avrdump to disassemble the .elf file. Then use the datasheet to count the cycles. Once you understand how many cycles this code takes you can start to tune it.

I would expect that

Code: [Select]
while ((PIND & B00001000) == B00001000)

would be better implemented as

Code: [Select]
((PIND & B00001000))

Also I would suggest to use 1 byte integers
Check out my experiments http://blog.blinkenlight.net


Thanks for following up but actually I don't need 1 count per microsecond I am already getting 3 counts per microsecond but I need accuracy in my measurements for which it is not enough. What do you think using a external fast counter with following sequence would solve my problem?

providing 12 MHz clock from function generator
providing the pulse to the enable input.
Make an interrupt into the Arduino when the pulse has a negative edge (end of pulse.)
Read and reset the counter from the Arduino.

If I use 8 bit external fast counter with the above sequence?


IMHO you should first specify in more detail what you exactly need. How much precision, how much resolution and what is the maximum expected pulse width. What are you doing?
Check out my experiments http://blog.blinkenlight.net


I am measuring pulse widths between 5 microseconds to 15 microseconds. I am giving these pulses from function generator by setting 1 Hz frequency. The code which I posted in my thread displays 1 microsecond or 0.5 microsecond when I give 1 microsecond width pulse similarly it gives either 10 or 9.5 when I apply 10 microsecond pulse width and so on so if for example when I give 10.3 or 10.2 or 10.1 it keeps on giving me 10 or 10.5 so it is not giving me correct reading for such values and that's what my problem is....

So what do you think now?


The accuracy of the code is 6/12 micro second which is 0.5 usec, so it measures in units of 0.5 micros. That is the accuracy of the algorithm.

If you have a pulse of 10.1 it will be approached to 9.5, 10.0, 10.5. [because there is no compensation yet for startup effects in the algorithm it can still  have a fixed error]

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)


What I think now: now I know what you are measuring.

I also learn that you do not really understand how to do precision measurements. This is because you can not tell why you would need the precision.

Would you please tell why the measurements are not accurate enough for your purposes? What are you after?
Check out my experiments http://blog.blinkenlight.net

Go Up