Yahoo Groups archive

AVR-Chat

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

Thread

Quadrature encoding, passing to another uController over serial...

Quadrature encoding, passing to another uController over serial...

2006-01-20 by eccamacho

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.

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

2006-01-20 by Zack Widup

On Fri, 20 Jan 2006, eccamacho wrote:

> 
> 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?). 
> 

I see no reason why that wouldn't work.  You should be able to store your 
data in the on-chip RAM or the EEPROM with plenty of room to spare. No 
need to try to store it in a timer register. The mega128 has a lot of 
capacity.

I'm working on implementing a digital compass chip made by a company 
called PNI. It has six data/control leads.  I've never done floating-point 
math in a micro before, and I'm trying to implement something called the 
Pade approximation of arctangent in the AVR to compute compass direction 
from the output X and Y data.  It's a learning experience! 

Zack

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

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.