Guys:
This might be a good start. I’m sure there are other more streamlined/elegant approaches and I’m sorry that this is just a description and not actual Flowcode (I haven’t actually coded and tested it yet).
The encoder you’re probably going to use is a quadrature type that generates a two bit gray code where the A and B outputs are staggered by 90 degrees. For the encoder I have, both outputs are zero (open) when the encoder is in a mechanical detent (I happen to have a Bourns ECW style encoder so that’s my model for this pseudo-code - to look at a data sheet search
digikey.com for part number ECW1DB24BC0024-ND). When the encoder is between detents (in motion) the A and B outputs will generate a binary coded decimal (BCD) sequence that changes with the direction of rotation. For mine in clockwise (CW) rotation the sequence is 0 (detent), 1, 3, 2, 0 (next detent) and for counter-clockwise (CCW) rotation the sequence is 0 (detent), 2, 3, 1, 0 (next detent). Any port can be used to interface the encoder. This example assumes that that BCD values 0, 1, 2 and 3 are the possible return values for a port read so port bits 0 and 1 are used as inputs and they are pulled low (4.7K Ohm resistors to ground should work). The encoder common is assumed to be connected either to Vcc or to another port bit (so that you can enable or disable the encoder when you want to).
The routine employs tests to determine the numerical sequence and, hence, the direction of rotation. That done, β€upβ€ events (presume clockwise) and β€downβ€ events (presume counter-clockwise) are generated. The value of the variable UP is the running total of β€upβ€ events and the value of the variable DOWN is the running total of β€downβ€ events. Anything you may want to do about an event (other than incrementing the value of UP or DOWN) can be done at the time an event is generated or later in the main loop, based on a reading of the value of UP or DOWN.
You may want to add code to limit the minimum UP/DOWN totals to zero and the maximum totals to 255 to prevent the variable values from under-flowing or over-flowing and/or you may want to add code to keep track of the running numerical difference between β€upβ€ and β€downβ€ events.
Up and down events are not generated and the UP/DOWN totals are left unchanged if the current port value (VALUE) is determined to be the same as the port value on the previous pass (PREVAL).
This is a β€polledβ€ approach (no interrupts) and it assumes that the main-loop-time is short enough to catch the encoder in motion. In principal it may not matter much if some of the events are missed so long as the User has some form of feedback like the volume level changing, changing menu items, etc. to guide his/her actions while using the β€controlβ€. In an application where I currently use an β€upβ€ switch, a β€downβ€ switch and an β€enterβ€ switch (and where I may want to use an encoder instead) things are pretty simple in that I jump out of the main loop and into a control-only loop for User input - then back out into the main loop after User adjustments have been made.
Note that whether the numerical sequence is a CW or a CCW sequence, the direction can be determined simply by looking at the value of PREVAL when and only when VALUE = 0. For CW rotation that would be PREVAL = 2 and for CCW rotation that would be PREVAL = 1. For any other values of VALUE or when VALUE = PREVAL (nothing has changed), I think you should be able to leave the encoder loop and go do things in the main loop for awhile (that is if VALUE = 1, 2, or 3, I don’t think that you need to stay in the encoder loop until a sequence has completed to be able to jump back into the main loop – I may be wrong about that).
Well, here goes. I think this will work - hope you can make sense and use of it (I tried to indent to make it clearer but the indents were gone when I previewed the post). If I actually get this translated into Flowcode and running I’ll report the results. Comments are in ().
Create variables:
ELOOP (encoder loop control, variable tested at end of encoder loop to exit)
UP (cumulative number of β€upβ€ events)
DOWN (cumulative number of β€downβ€ events)
VALUE (the BCD value of port x, bits 0 and 1)
TEMPVAL (temporary value)
PREVAL (previous value)
(Connect encoder channel A output to portx, bit 0. In Flowcode, attach switch to portx,0)
(Connect encoder channel B output to portx, bit 1. In Flowcode, attach switch to portx,1)
(Make VALUE the value of Port x, b0 and b1. In Flowcode, read the two-bit value of portx and return the variable VALUE)
Start
(Initialize UP, DOWN and PREVAL)
UP = 0
DOWN = 0
PREVAL = 0
(Enter main loop)
Loop while 1 = 1
(Enter encoder loop)
ELOOP = 0 (Re-zero ELOOP each time through the encoder loop)
(Enter de-bounce loop)
Read portx (update VALUE)
TEMPVAL = VALUE
Delay (try 20 ms)
Read portx (update VALUE)
Loop while VALUE <> TEMPVAL (exit de-bounce loop when VALUE = TEMPVAL)
(End of de-bounce loop. Either loop again or exit to encoder loop)
(Re-enter encoder loop)
VALUE = PREVAL? (Has the encoder moved since the last time through the encoder loop? Remember, the first time through PREVAL will have been arbitrarily preset to 0)
Yes
ELOOP = 1 (Encoder hasn’t moved. Skip everything and exit to the main loop. Structure your test β€yesβ€ branch this way in Flowcode by β€nestingβ€ other tests or instructions under the β€noβ€ branch of this test)
No (Continue)
VALUE = 0?
Yes
PREVAL = 1?
Yes
DOWN = DOWN + 1 (Do something now in response to a β€downβ€ event or check the value of DOWN later and decide whether or not to do something then)
ELOOP = 1
No (Continue)
PREVAL = 2?
Yes
UP = UP + 1 (Do something now in response to an β€upβ€ event or check the value of UP later and decide whether or not to do something then)
ELOOP = 1
No (Continue)
No (Continue)
PREVAL = VALUE
ELOOP = 1
Loop while ELOOP = 0 (Exit encoder loop if ELOOP is anything other than 0)
(End of encoder loop. Either loop again or exit to main loop)
(Re-inter main loop)
(Do other stuff you may want to do within the main loop before returning to the top of the main loop)
End (never!)