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 | | | | | |
Message
RE: [AVR-Chat] Quadrature encoding, passing to another uController over serial...
2006-01-20 by Larry Barello
Attachments
- No local attachments were found for this message.