To use this file copy and paste this:    // #URL-lib "http://pin1.org/forthlib/flb/Examples/rotary-shed.flb"   into BV Terminal 3 or here to download.

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Rotary encoders schedule library // This version is incorporated into the scheduler and is intended // to be used as a library, the the example for how to use. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

// HISTORY: // March 2008 * error in r-pause fixed

// 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 // #URL-lib "http://pin1.org/forthlib/flb/Interupts/interrupt.flb" // #URL-lib "http://pin1.org/forthlib/flb/Interupts/b-shed.flb"

// 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 variable r-change variable r-value


Full Contents of File

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// Rotary encoders schedule library
// This version is incorporated into the scheduler and is intended
// to be used as a library, the the example for how to use.
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

// HISTORY:
// March 2008 * error in r-pause fixed

// 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
// #URL-lib "http://pin1.org/forthlib/flb/Interupts/interrupt.flb"
// #URL-lib "http://pin1.org/forthlib/flb/Interupts/b-shed.flb"

// 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
variable  r-change
variable  r-value

// 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 rb
// 0 1 0 0 4
// 1 1 0 1 D
// 1 0 1 1 B
// 0 0 1 0 2
// 0 1 0 0 4 etc.
//
// For the other way
// ra rb
// 1 1 1 0 E
// 0 1 1 1 7
// 0 0 0 1 1
// 1 0 0 0 8
// 1 1 1 0 E etc.
//
// r-pat creates this pattern, by determining which pattern is presented
// the direction of rotation can be obtained.
//

// Set up rotary encoder lines A and B
: r-set
        line1  io-in
        line2  io-in
        pushb  io-in          // push switch
;

// return 1 if the values are different
// from last time
// ( --- 1|0)
: ra@?          // detect change
        line1  p@  1+  Ra  1  and  xor
;       
// ( --- 1|0)
: rb@?          // detect change
        line2  p@  1+  Rb  1  and  xor
;       
// this is a pin detect with switch debounce
// returns 1 when off 0 when on
// ( --- 1/0)
: Ra@     
        ra@?  // changed
        if
                ra@?    // delay if required here for switch debounce
                if            // still different
                        line1  p@  1+  =>  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
 
      3  and                      // clear bits 2&3
        ra@  8  *  +        // ad ra
        rb@  4  *  +        // add rb
        =>  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
;           

// this word gets called as part of the schedule
// it will update the variable rvalue
: r-rot1
    r-rot
        if
            r-value  +!
            -1  r-change  !
        then   
;

// ---------------- Public words ------------------------------
// adds rotary to schedule and starts it
: <0>rot-start
    r-set          // setup
    0  r-value  !    // reset
    0  r-change  !
    [']  r-rot1  s-add      // add to schedule
    if   
        s-start      // start scheduler
        // 10 interval ! // should be set elsware
    else
        cr  ."  in  file  rotary-shed.flb,  cant  add  r-rot1  to  schedule"
        abort
    then       
;

: <0>rotvr-value  ;      // gets rotary variable address
: <0>rotv?r-change  ;  // gets address of change value -1 if changed

// the following are just tools that could be removed
// form an actual application
: <0>lookps.  ;
: <0>r-pause[']  r-rot1  s-pause  ; 
: <0>r-resume[']  r-rot1  s-resume  ;