The best?? quadrature decoding I found is shown below, for a mouse. I don't
know who the author was, since this is the only text I copied. It has to be
translated into code though.
_____________
First verify that you can read the two phases for each direction as digital
inputs,
doing level shifting if necessary. Write a simple test program that reads
the four
signals and outputs them to four outputs connected to LEDs (or check the
outputs
with your multimeter). Then move the mouse and verify that one pair of LEDs
changes
state when you move the mouse one way and the other pair changes when you
move the
mouse in the perpendicular direction.
The quadrature pulse rate from a mouse is quite slow, so you can use pure
software
methods to keep track of the count. (Faster quadrature signals would require
hardware
pulse counting.)
The basic principle is to sample the A and B phase signals (the two
quadrature
signals) often enough so that you never get more than one signal change from
one
sample to the next. This could be done with a timer interupt, or even with
foreground
polling, depending on what else you PIC needs to do at the same time.
Each sample gives you two bits. You combine these two bits with the two bits
you got
from the previous sample to get 4 bits. Use these 4 bits in a lookup table
to count
up, count down, or do nothing:
0 0 0 0 - do nothing
0 0 0 1 - count up
0 0 1 0 - count down
0 0 1 1 - do nothing (*)
0 1 0 0 - count down
0 1 0 1 - do nothing
0 1 1 0 - do nothing (*)
0 1 1 1 - count up
1 0 0 0 - count up
1 0 0 1 - do nothing (*)
1 0 1 0 - do nothing
1 0 1 1 - count down
1 1 0 0 - do nothing (*)
1 1 0 1 - count down
1 1 1 0 - count up
1 1 1 1 - do nothing
The first two bits are the old A and B phases and the last two bits are the
new A and B
phases. The "do nothing(*)" cases are ones where something went wrong. You
got both the
A and B phases to change in one sample time. Either you are not sampling
fast enough,
or else there is some noise. If you want to make a better guess as to what
to do when
both phases change, then keep track of whether the last real count was "up"
or "down".
Due to inertia, chances are it is still going the same way. So it might be
safe to count
two "up" or "down" counts in the same direction as you were last going when
one of these
things happens.
Of course you will need to do this entire algorithm twice to keep track of
the two
channels in a mouse (unless you are only concerned with one channel).
____________
Regards
Roland
2009/11/3 erikc <firewevr@airmail.net>
>
>
> I'm working one one right now. I just got started playing with AVRs
> (professionally I work with Freescale parts)
>
> My personal goal is to create digital readouts for the little lathe
> and mill I have out in the garage. I intend this to be a
> multiprocessor device, with a separte AT90S2313 doing the quadrature
> (the scales attached to the machine put out a 90 degree phase-shifted
> waveform) decoding and counting for each axis (2 for the lathe, 3 for
> the mill) and I haven't made up my mind what I'm going to use for a
> master display processor. At first, I'm going to want to just have a
> basic display of position, but then, as I go along, I want to add
> really fancy features such as: "Enter a center point, a diameter, a
> number of holes, and whether or not I'm making an arc or a circle.
> Then compute the locations for each hole in the arc or circle and
> adjust the display so I can manually center the workpiece for each
> hole before drilling". Maybe some day perhaps go all the way to
> complete numerical control.
>
> If someone could share a nice quadrature decoding routine?
>
>
> Zack Widup wrote:
> > Is there an assembly language version of that?
> >
> > Zack
> >
> > On Tue, Nov 3, 2009 at 4:19 AM, Marc R.J. Brevoort <mrjb@dnd.utwente.nl<mrjb%40dnd.utwente.nl>
> >wrote:
> >
> >>
> >> Hi Erik,
> >>
> >>
> >>> Who ever came up with this orignally was a frickin' genius.
> >>> Sure, it's for PIC but the code is in C.
> >>> A little helpful cut-n-paste to give you the basic idea.
> >>>
> >>> ;static unsigned clock_A,clock_B,debounced_state;
> >>> ;unsigned debounce(unsigned new_sample)
> >>> ;{
> >>> ; unsigned delta;
> >>> ; unsigned changes;
> >>> ;
> >>> ; delta = new_sample ^ debounced_state; //Find all of the changes
> >>> ;
> >>> ; clock_A ^= clock_B; //Increment the counters
> >>> ; clock_B = ~clock_B;
> >>> ;
> >>> ; clock_A &= delta; //Reset the counters if no changes
> >>> ; clock_B &= delta; //were detected.
> >>> ;
> >>> ; changes = ~(~delta | clock_A | clock_B);
> >>> ; debounced_state ^= changes;
> >>> ;
> >>> ; return changes;
> >>> ;} /* debounce */
> >>> ;
> >>>
> >>> The cool thing is that this can debounce a whole port at once. It
> >>> runs in an interrupt routine.
> >> Thanks. I've got a single button debounce by now, but this one is
> >> quite nice due to its multi-input nature. I've saved it to my favs for
> >> future reference.
> >>
> >> Best,
> >> Marc
>
>
>
[Non-text portions of this message have been removed]Message
Re: [AVR-Chat] ATtiny2313 button handler
2009-11-03 by Roland Jollivet
Attachments
- No local attachments were found for this message.