In SX Microcontrollers, SX/B Compiler and SX-Key Tool, mrchadwickusa wrote: [code] Encoders 101 Most encoders generate two signals, generally square waves 90 degrees out of phase. I say most, because you can get ones that also put out an index pulse once per revolution, and there are some that output analog sine waves instead of digital signals. The basic idea is that with the two phases 90 degrees apart, you can distinguish the direction of rotation. Position comes from keeping track of the number of pulses and the direction. This is also known as a Gray or Grey code. The key feature there is that only one bit can change at a time when moving from one state to another adjacent state. You can list them like this, I did two cycles. I labeled the phases A and B. If you look at it in sequence, each two bits from top to bottom, you can see each signal goes 0 to 1 then back again, but overlapped. Looking at it from top down might represent the output sequence of the encoder moving in a clockwise direction, looking at it from bottom up counterclockwise. AB 00 10 11 01 00 10 11 01 Side ways: A01100110011001100110011 B00110011001100110011001 If the encoder isn't moving, it outputs the same state continuously. To detect a change in position, we sample the encoder outputs at regular intervals and compare the current sample to the previous one. Using an XOR to do this works nicely because when you XOR two bits you get a one only if they are different. Truth table for XOR: XOR A B O 0 0 0 0 1 1 1 0 1 1 1 0 So if we went from encoder state 00 to state 01, and XOR'd the two, we would get 01. If we went from 01 to 11 we would get 10. So for some changes we get a result of 01, for others we get 10. If we only want to do one test to see if either bit has changed, we can do that by ORing the two bits together. I did it by shifting a copy of the original XOR result up one bit, and ORing it with the original. This gives me a single bit that will be a 1 if either channel of the encoder changed state. Consider your situation where you have two encoders as two pairs of bits next to each other in the same byte. Bits 0 and 1 are one encoder, bits 2 and 3 are the next: Encoder: AABB Phase: ABAB Bit # 76543210 00001100 :encoders sitting at rest, old state 00000100 :encoder A moved one tick clockwise, new state XOR 00000100 :result of XOR old and new << 00001000 :shifted copy of the XOR, low bit of comparison shifted into position to line up with the high bit. OR 00001100 :result of oring the two together Now, we have to be careful to pick the correct bits to test, we want the bit that is the OR of the two change bits for each encoder. In this case, since we shifted up, we want to pick the higher bit of each pair, because we OR'd the high bit of the pair with the lower bit. The low bit of each pair is now meaningless since the lower bit of the pair got OR'd with the high bit of the pair to its right. So we test bits 1 and 3 and we see we got a 1 in bit 3, which indicates encoder B moved, and a 0 in bit 1 which indicates encoder A didn't move. We need to work out how to detect the direction based on getting any two states in sequence. If we take the old sample B phase and XOR it with the new sample A phase, we get a one when the encoder is moving CW, and a zero when the encoder is moving CCW. You can see from the diagrams below that moving CW, the old B and new A are always different, moving CCW the old B and new A are always the same. I've used the slashes to indicate the two bits getting XORd, with the result to the right of the slash. I've labeled the phases A and B, keep in mind both sequences are the same, moving along them top to bottom represents clockwise, moving bottom to top is counter clockwise, the slashes indicate which bits get compared in each direction: XOR old B new A moving CW: Time Time moves moves down up Start End A B CW A B CCW 0 0 0 0 / 1 \ 0 1 0 1 0 / 1 \ 0 1 1 1 1 / 1 \ 0 0 1 0 1 / 1 \ 0 0 0 0 0 / 1 \ 0 1 0 1 0 / 1 \ 0 1 1 1 1 / 1 \ 0 0 1 0 1 End Start Referring to the previous example: Encoder: AABB Phase: ABAB Bit # 76543210 00001100 :encoders sitting at rest, old state 00000100 :encoder A moved one tick clockwise, new state << 00011000 :old state shifted left, old B now lined up with new A XOR 00011100 :result of XOR shifted old and unshifted new Again, since we shifted to the left one bit, we want to use the higher bit of each pair, the A phase bit of the result, to indicate direction. Encoder A bit A is a 1 in the result, which indicates clockwise movement. The direction bit is only meaningful if the encoder actually moved, so in the code we test for the change bit, and then the direction bit. Hopefully this shows how you could do 4 encoders on one 8 bit port, using one set of operations to calculate the change and direction bits. [/code] ---------- End of Message ---------- You can view the post on-line at: http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=147541#m147838 Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)