Searching \ for '[PIC]: High speed DUAL 4x Resolution Quadrature en' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: techref.massmind.org/techref/microchip/ios.htm?key=quadrature
Search entire site for: 'High speed DUAL 4x Resolution Quadrature en'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: High speed DUAL 4x Resolution Quadrature en'
2003\04\21@192406 by Bob Ammerman

picon face
I have written a high-performance quadrature encoder decoder routine that
handles 2 quadrature encoders at once at 4x resolution at 100,000 edges per
second on each of the two encoders when using a 20MHz PIC16.

The full source code may be found at:

http://www.piclist.com/techref/microchip/ramquaddesc.htm


Bob Ammerman
RAm Systems

The header from the source file follows (rewrapped to fit!):

;====================================
; Very high speed DUAL 4X-resolution quadrature encoder routine.
;
; This module defines a routine that will allow a 20MHz PIC16xxx to
; encode two simultaneous quadrature encoders. Transitions on both
; edges of both signals from each encoder are processed to provide
; 4x resolution.
;
;     (c) 2003 - Robert V. Ammerman
;     RAm Systems
;     spam_OUTrammermanTakeThisOuTspamadelphia.net (as of 21-Apr-2003)
;     via the PICLIST (http://www.piclist.com)
;
; This code may be freely used in any application, commercial or otherwise,
; with the following provisos:
;
; 1. The above copyright notice and these conditions remain intact within
;     the source code.
; 2. Robert V. Ammerman, RAm Systems, the PICLIST and PICLIST.COM
;     have no responsibility for this code working in your application, or
;     any consequences of it not working.
; 3. This code is provided without any form of warranty whatsoever.
; 4. You must make a diligent effort to contact Robert V. Ammerman via
;     email or the PICLIST to inform him, in general terms, about how you
;     are using this code (he is curious!)
;
; PERFORMANCE: Unlike many quadrature decoding schemes, this code
; does not depend on interrupts from edges of the input signals. Rather, it
; periodically checks the inputs to see what changes have occurred. It can
; be driven either from a timer interrupt, or simply by being called from a
; non-interrupt-driven loop.
;
; In the non-interrupt-driven case, each call of the encoder polling routine
; uses a maximum of 22 instruction cycles, including the call and return.
; It uses as few as 12 cycles if no inputs have changed.
;
; A reasonable computation for the maximum edge rate at which this routine
; can work is:
;
;    22 instructions per poll
; x 1.5 (to allow for 'distortion' in the encoder waveforms)
; x 1.5 (to give the 'application' code at least 1/3 of the total CPU time).
; -------
; = 50 instructions per edge
;
; At a 20Mhz clock rate, or 5Mhz instruction rate, this gives a maximum
; edge rate of 100,000 edges per second or 25,000 full encoder cycles
; per second.
;
; Note that at the rate given above, an application has to limit itself to
; no more than 11 instruction times between calls on the ENCPOLL
; macro to meet the 1.5 factor in the above computation. Changing
; that factor, for example, to 2.0 would allow 22 application
; instructions per poll at a maximum edge rate of about 67,000 per
; second. A factor of 3.0 would allow 44 application instructions per
; poll at a maximum edge rate of about 50,000 per second.
;
; When interrupt driven, a number of cycles will be used to enter and
; exit the interrupt routine, which will reduce the maximum possible
; edge rate.
;
; Note that if any interrupts are enabled, then the worst case ISR time
; has to be added to the clocks per edge. This is true even if the encoder
; is using the polling mode.
;
; This code is provided in ABSOLUTE mode to avoid the complexity of
; defining and distributing a linker control file with it (sorry Olin).

--
http://www.piclist.com hint: To leave the PICList
.....piclist-unsubscribe-requestKILLspamspam@spam@mitvma.mit.edu>

2003\04\21@204855 by Ted Larson

flavicon
face
You rock Bob!  Looks really good!

I have a suggestion of something to add that will make it even more useful.
Track the times beween rising and falling edges, calc and store away a
current velocity and acceleration value in a register somewhere, and send it
out as part of the poll.....i.e. edges per msec, and edges per msec-squared.

Thanks,

- Ted


{Original Message removed}

2003\04\21@221849 by Bob Ammerman

picon face
> I have a suggestion of something to add that will make it even more
useful.
> Track the times beween rising and falling edges, calc and store away a
> current velocity and acceleration value in a register somewhere, and send
it
> out as part of the poll.....i.e. edges per msec, and edges per
msec-squared.
>
> Thanks,
>
> - Ted

Ted,

This would typically be a part of the higher level software in whatever
device was polling the PIC.

BTW: here is a snippet of how C code would interpret the values coming back
from the poll. Note that the 16 bit counters in the PIC can overflow quite
quickly, so the next level of code has to handle the rollover intelligently.
It turns out that this is very simple to do.

long    pos1 = 0;       // assumed initial positions of encoders
long    pos2 = 0;

unsigned short last_count1 = 0;
unsigned short last_count2 = 0;
unsigned short last_faults1 = 0;
unsigned short last_faults2 = 0;

unsigned char new_faults1, new_faults2;


for (;;) // process forever
{
   unsigned short count1, count2;
   unsigned char faults1, faults2;

   // get the values from the encoder
   pollencoder( &count1, &count2, &faults1, &faults2 );

   // We compute the amount the count has changed. It turns out the
unsigned
   // arithmetic used below will properly handle the rollover cases. The
result of
   // the subtraction is cast to a signed value before adding it to the
current position
   // to compute the new position.
   pos1 = (short) (count1 - last_count1);
   pos2 = (short) (count2 - last_count2);
   last_count1 = count1;
   last_count2 = count2;

   // We compute the number of new faults, if any. Again, wraparound
arithmetic
   // does the right thing for us.
   new_faults1 = faults1 - last_faults1;
   new_faults2 = faults2 - last_faults2;
   last_faults1 = faults1;
   last_faults2 = faults2;

   if ( new_faults1 )
       report_faults( 1, new_faults1 );
   if ( new_faults2 )
       report_faults( 2, new_faults2 );
}

Bob Ammerman
RAm Systems

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestspamKILLspammitvma.mit.edu>

More... (looser matching)
- Last day of these posts
- In 2003 , 2004 only
- Today
- New search...