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
|
|
|
|
|
|