In SX Microcontrollers, SX/B Compiler and SX-Key Tool, PJMonty wrote: Matthias, Skip all this interrupt on each line stuff. There is a much simpler way to decode quadrature encoders. 1 - Create a lookup table with 16 entries. The values should be the following: [code]0, 1, -1, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, -1, 1, 0[/code] 2 - Create an RTCC interrupt. The frequency of the interrupt should be at least twice as high as the highest frequency clock generated by the encoder. For example, if you have an encoder with 100 pulses per revolution (PPR) and the fastest it will turn is 10 revs per second (RPS), then the encoder's fastest clock generated will be 100 PPR X 10 RPS = 1000 pulses per second. You would need to have the RTCC interrupting at a rate of at least 2000 Hz. 3 - When the RTCC interrupt occurs, your interrupt handler needs to sample the state of the two encoder lines. It then needs to take the state of the inputs from the previous interrupt (more about that in a moment), shift them two places to the left, and OR them with the current state. 4 - The value you just calculated will create an entry into the lookup table. The value from the lookup table will either by 1 (turned one count forward), -1 (turned one count backward), or 0 (no change). 5 - Finally, store the current value of the inputs for use next time. If you want, you can pre-shift the value two places to the left. Assuming you have the encoder attached to bits 0 and 1 of Port A, the pseudo-code, it looks like this: [code]'Create a lookup table EncoderTable[16] = 0, 1, -1, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, -1, 1, 0 ' Get the current encoder values and mask un-used bits CurrentEncoderInput = PortA AND %00000011 ' Create entry into lookup table. NOTE: Multiplying times 4 is the same as left ' shifting two places. Depending on the compiler, the leftshift may be faster TableIndex = CurrentEncoderInput OR (PrevEncoderInput * 4) ' Update current position of encoder CurrentPosition = CurrentPosition + EncoderTable[TableIndex] ' Store current encoder inputs for next time PrevEncoderInput = CurrentEncoderInput [/code] As long as you sample at a rate at least twice the highest input clock value, you'll never miss an encoder pulse. This technique also has the added bonus of counting every clock edge, so it increases the number of clocks from the encoder by 4. Finally, this technique eliminates any problems that occur if the encoder stops with the disk partially covering the optical sensor. This can create a condition where the clock toggles high/low, making it seem as though the encoder is moving when it's simply the electronics being unable to settle on a logic state. Similar problems occur with contact bounce on a mechanical encoder. Anytime this happens, the lookup table will simply return zero, thus the encoder position variable doesn't show a change in position. Thanks, PeterM ---------- End of Message ---------- You can view the post on-line at: http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=375331#m376138 Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2009 (http://www.dotNetBB.com)