// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Rotary encoders 2 // This version does not use interrupts and culd be easily // used as a library for other projects. // This is an alternative to Rotary.fth, it possibly works // slightly better, uses a pattern to detect direction rather // then detent // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // REQUIRES: // #URL-lib "http://pin1.org/forthlib/flb/General/soft1.flb" sid=99 // #URL-lib "http://pin1.org/forthlib/flb/General/pinsel.flb" sid=100 // CONSTANTS: // define the three wires used for the encoder 25 constant line1 26 constant line2 6 constant pushb // integer ra integer rb integer det integer rch // A rotary encoder presents two switches that are alternatively // switched on and off. // This method works by detecting a pattern that is composed of the // state of the switched last read to this read. If ra,rb are the current // state andf Ra then then Ra ; : Rb@ rb@? // changed if rb@? if // still different line2 p@ 1+ => Rb then then Rb ; // push switch // ( value ---) : Rc@ pushb p@ ; // detects a change in any of the a,b switches -1 if there has been a change // since last read : ch? ( -- -1|0) ra@ rb@ + rch <> if -1 ra@ rb@ + => rch else 0 then ; // retunrs set and -1 or 0. Det is one of 4 values consisting of a pattern // for anti clockise [2,4,&b,&d] and clockwise [1,7,8,&e] // If there has been no change since last read, then it will return 0 : r-pat ( -- det, -1|0) ch? if det 2 rshift // move ra,rb to det // put back det -1 else 0 then ; // returns x = 1 for clockwise and -1 for anticlockwase followed by -1 // if there have been no chenges it returns 0 on its own : r-rot ( -- x, -1|0) r-pat // get rotary pattern if case 2 of -1 endof 4 of -1 endof &b of -1 endof &d of -1 endof otherwise 1 endcase -1 else 0 then ; : r-test int: tmp begin r-rot if +> tmp tmp . space then key? until ;