Confused at the function "pulseIn()"

hello everyone, I am working on a rc signal mixed system. And I found a useful library function: pulseIn()
I was interested at the function's completed, I finally found the source code at arduino-1.0.5/hardware/arduino/cores/arduino/wiring_pulse.c
I am confused with the solution returned.

return clockCyclesToMicroseconds(width * 21 + 16);

And the annotate says:
// The loop has been determined
// to be 20 clock cycles long and have about 16 clocks between the edge
// and the start of the loop. There will be some error introduced by
// the interrupt handlers.

then why width multi by 21?? Why not 22 or multi by 20 and plus a constant? How do you guys work out it?

In my case, I would code it in assembly to make it immune to compiler changes and just count the number of cycles.

In lieu of coding in assembly, I would use avr-objdump to create an assembly listing and count the cycles. I use this Python script to wrap avr-objdump (named "ds.py" for Dump Sketch)...

import fnmatch
import os
import subprocess
import string

pathok = False
pathlist = os.environ['PATH'].split( os.pathsep )
for path in pathlist:
  testme = os.path.join(path,'avr-objdump.exe')
  if os.path.exists(testme):
    pathok = True
    break

if not( pathok ):
  arduinoroot = 'C:\\Arduino\\arduino-1.0.5\\'
  pathlist.append( arduinoroot + 'hardware\\tools\\avr\\utils\\bin' )
  pathlist.append( arduinoroot + 'hardware\\tools\\avr\\bin' )
  pathlist.append( arduinoroot + 'hardware\\tools\\avr\\etc' )
  pathnew = os.pathsep.join( pathlist )
  os.environ['PATH'] = pathnew

tempdir = os.environ.get('TEMP')
tempfile = os.path.join(tempdir,'Junk.cpp')

matches = []
for root, dirnames, filenames in os.walk(tempdir):
  for filename in fnmatch.filter(filenames, '*.elf'):
    matches.append(os.path.join(root, filename))

matches.sort( key=os.path.getmtime )

if len(matches) > 0:
  f = open(tempfile, 'w')
  subprocess.call(['avr-objdump.exe','-S','-z',matches[len(matches)-1]],stdout=f)
  f.close()
  os.system( 'start ' + tempfile )

And the annotate says:
// The loop has been determined
// to be 20 clock cycles long and have about 16 clocks between the edge
// and the start of the loop. There will be some error introduced by
// the interrupt handlers.

then why width multi by 21?? Why not 22 or multi by 20 and plus a constant? How do you guys work out it?

These formulas are determined as above by cycle counting and adjusted by trial and error. Probably 21 fits real life better :wink:

Its also a horrible way to do anything RC related because it blocks until it gets a pulse.

Try this interrupt based approach instead -

Duane B

rcarduino.blogspot.com

Every time I see Python code, I want to edit it and insert semicolons.

SirNickity:
Every time I see Python code, I want to edit it and insert semicolons.

You too?

Python actually does not care.