Go Down

Topic: Confused at the function "pulseIn()" (Read 1 time) previous topic - next topic

NetWilliam

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.
Code: [Select]

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?

Coding Badly


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)...
Code: [Select]

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 )


robtillaart

Quote
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 ;)
Rob Tillaart

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

DuaneB

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

Try this interrupt based approach instead -

http://rcarduino.blogspot.ae/2012/01/how-to-read-rc-receiver-with.html

Duane B

rcarduino.blogspot.com
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

SirNickity

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

Coding Badly

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


You too?

Python actually does not care.

Go Up