Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Message

RE: [AVR-Chat] Quadrature encoding, passing to another uController over serial...

2006-01-20 by Larry Barello

7 rps * 256 strips * 4 interrupts/strip * 2 encoders = ~57,000
interrupts/second.  That is ~18us/interrupt or 260 instructions @ 16mhz.
This should be doable.

You can't interrupt on any edge with most AVRs (not true with newest
variations) so I only use the A line for interrupts and the B line to
determine whether to increment or decrement the counter.  In the interrupt
handlers I switch the edge sense so the handler can capture both posative
and negative edges.  I call this pseudo 2x quadrature decoding.  Capturing
both edges is essential to make it work as mechanical jitter can introduce
spurious counts if you only capture a single edge (imagine the encoder
stalled with the strip hoverring near the edge and a slight mechanical
jitter).  This all takes just a couple lines of assembly code.

With careful coding I got the total cycle time down to ~60 instructions
(~5us @ 16mhz) which allows my system (a three channel motor controller
based upon the mega128) to handle a combined interrupt rate of 100khz
without missing a single interrupt and still have ~50% of the CPU available
for the host comm's, PID, etc.

The mega128 is gross overkill for this project unless you are doing a bunch
of other stuff.  It might be better to use a smaller newer chip with
"interrupt on pin change" and then implement you table lookup.  Then you
should be able to sustain much higher interrupt rates and get full 4x
decode.
-----------
Larry Barello
www.barello.net


| -----Original Message-----
| From: AVR-Chat@yahoogroups.com [mailto:AVR-Chat@yahoogroups.com] On Behalf
| Of eccamacho
| Sent: Thursday, January 19, 2006 10:11 PM
| To: AVR-Chat@yahoogroups.com
| Subject: [AVR-Chat] Quadrature encoding, passing to another uController
| over serial...
| 
| 
| Pardon me if this has been discussed before.  I searched through a few
| messages and found some things which are similar, but not quite the same.
| 
| I'll be programming on a Atmega128 which will be connected over serial
| to another microcontroller to do higher level processing.  The Atmega
| will be connected to 2 quadrature optical encoders.  Each encoder will
| be connected to a shaft which will do about 7 revolutions/sec.  The
| encoders have 256 CPS (is that clocks per second or cycles per second?).
| 
| If I understand the quadrature encoding, for maximum resolution, I can
| hook up the 2 outputs of the encoder to 2 external interrupts and
| trigger on any edge.  Using a state machine and lookup table, I can
| determine the direction, and since I'll be triggering on every edge,
| I'll know the distance (presumably, only 1).  Will this be too much
| for the Atmega?   Where can I store the computed value?  I'm hoping I
| can put it in one of the 16-bit counters.  That should be a fairly
| small amount of work for the interrupt.  Since I have 2 encoders,
| that's 4 interrupt pins and 2 16-bit counters total.
| 
| I'm hoping to send the data over the serial port when requested by the
| master.  I'll reset the counters when they are read, thus, giving me
| the difference since the last read every time.
| 
| Here's the quadrature encoding lookup table:
| LR = Last Read
| CV = Current Values
| A, B are the seperate output channels of the encoder:
| _LR_|_CV_|_VALUE_|
| _AB_|_AB_|_______|
| 
|  00   01  +1
|  00   10  -1
|  01   00  -1
|  01   11  +1
|  10   00  +1
|  10   11  -1
|  11   01  -1
|  11   10  +1
| 
| Assume +1 and -1 indicate direction.  Of the 16 possible combinations,
|  8 aren't possible (assuming I don't miss any edges).  Right?
| 
| Any glaring mistakes in my plans/logic?
| 
| Thanks.
| 
| 
| 
| 
| 
| 
| 
| 
| 
| 
| Yahoo! Groups Links
| 
| 
| 
| 
| 
|

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.