ATmega16 Seems Fast Enough to Handle Encoder Input
The issue of an encoder sitting at a transition should not be a problem. The way to handle this is to require that counting always occurs on alternating channels. So if the last count was (say) up on channel A, then a transition back on channel A is ignored. If the encoder continues moving in that direction, the next count will be down, but it will be caused by the transition on channel B. This means that there is built in hysteresis of one transition (on a 500 line encoder, this is one 2000th of a revolution).
On an AVR (the ATmega16 is my current processor of choice because I already use them), it is a simple matter of disabling the interrupt on the last channel that it occurred on. So on an A interrupt, disable A and enable B. On a B interrupt, disable B and enable A.
I've written some prototype code and it appears that it will less than 4 usec to handle each interrupt on an ATmega16 running at 20 MHz. It's 53 words of code for each interrupt. Not all of it will need to execute. When I have some time, I'll try to get a better figure.
An encoder with 2000 transitions per revolution will take around 8msec per revolution. At 3600 rpm (60 revs per second), it will use about half of the processor cycles when running at full speed. -- But note, that other code had better not disable interrupts for more that around 4 usec.
Ken
Why I Would Not Use Counters
Quote:
Originally Posted by ESjaavik
@lerman: Did you consider using one of the built-in counters?
In real life a motor running at a speed approaching the (software) counting abilities of an ATMega16 @ 20MHz will simply not just begin rotating in the opposite direction! So why not change strategy from software counting with direction discriminator to just measure the speed? Then you would be able to follow a motor with 4096 transititions/rev and more up to when it throws it's windings. If you choose the input pins with care, this can all be done in software. It will only count on one flank of one of the phases, thus getting only 1/4 of the resolution but again, at that speed that will be a moot point anyway. Just shift the counter result left twice to make it correct.
If using step/dir control, use same strategy to keep up with this. If the host decides to swap direction while issuing step pulses at high speed, it's a lost case anyway. I know commercial drives that will not allow this either.
I did not try this out, so please shoot me down if I'm wrong.
I wouldn't say that you are wrong, but here are my thoughts.
At "zero" speed, you could sit at a transition. Any little vibration might cause rapid cycling up and down. Remember that every lost count on a servo represents an error in position -- it corresponds to a lost step on a stepper.
Of course, if you put a linear encoder on the table, then you can use the rotary encoder for speed feedback and the linear encoder for position.
One neat way (for me, at least -- I'm a programmer) to handle the problem might be to dedicate a chip to read the encoder and also read the commands from the host (PC). By writing the code in assembly language, I believe I could handle 3600 rpm with a 2000 transition per rev. encoder.
A second processor would read the current error (from the first processor) at the rate of a thousand times a second or so.
Ken