Shop Learn
FlexBasic and quadrature decode — Parallax Forums

FlexBasic and quadrature decode

I need to read six quadrature encoders (6-axis machine-tool) using FlexBasic on the P2.

I have been reading "Bob's Propeller P2 Guide" (HUGE) but it has only made my head spin :#

Is there a straightforward (simple) way for FlexBasic to nominate the 2 encoder-connected smartpins and to read/preset the count?

I realise that JM has a Spin object for this but can I do this directly within FB?

Comments

  • Do you want a native Basic implementation for the quadrature counters (or even completely re-write JonnyMac's spin object in FlexBasic) or would it be sufficient to include the object as class in FlexBasic?

  • MicksterMickster Posts: 1,941

    I would prefer native in Basic, if possible. I don't need the detent, button, range-limit stuff. Also, I can read Basic :D

  • AribaAriba Posts: 2,552

    Here is a simple example. I used a mechanical rotary encoder, which needs pullups. For a motor encoder this may not be necessary.

    '' simple quad-encoder in BASIC
    ''
    const _clkfreq = 160_000_000
    const enc_a = 32                ' encoder A pin, B pin must be 1 higher
    
    dim  encval as long
    
    pinstart(enc_a, P_PLUS1_B + P_QUADRATURE + P_SCHMITT_A + P_HIGH_15K + P_OE, 0, 0)  'init encoder with pullups
    pinhigh(enc_a)   'high for pullup
    wrpin(enc_a+1, P_SCHMITT_A + P_HIGH_15K)   'B pin: only schmitt + pullup
    pinhigh(enc_a+1)
    
    direction(enc_a) = input        ' reset count to zero by toggling DIR bit 
    direction(enc_a) = output
    
    do
      encval = rdpin(enc_a)         ' read encoder
      print "encoder: ";encval
      pausems 500                   ' wait 1/2 second
    loop
    

    Andy

  • JonnyMacJonnyMac Posts: 7,823

    My encoder object is fairly simple. If FlexBasic supports smart pins, it will be no trouble to translate. Keep in mind that you cannot preset the encoder value inside the pin. In my object I preset the value by resetting the encoder pin to 0, and putting my preset value into an offset.

    pub set_value(preset) : result
    
    '' Set encoder to preset value
    
      pinfloat(apin)                                                ' reset & clear
      pinlow(apin)                                                  ' re-enable
    
      preset := lolimit #> preset <# hilimit                        ' force into range
    
      result := offset := preset                                    ' set encoder value
    

    I have range limits in the object for things like volume controls where you'd want to stay between 0..100. When reading the encoder, this come into play in the event we've gone past a defined limit.

    pub value() : result
    
    '' Return encoder value
    '' -- returns encoder value turncated to lolimit..hilimit
    
      result := raw() + offset                                      ' read and update value
    
      if (result < lolimit)                                         ' limit range
        result := set_value(lolimit)
      elseif (result > hilimit)
        result := set_value(hilimit)
    

    In the end I was able to duplicate my P1 encoder cog -- without using a cog!

  • MicksterMickster Posts: 1,941

    @Ariba

    Holy moly....I wasn't expecting it to be this readable/understandable :D
    Many, many thanks!!! I had to leave the shop and now I can't wait to get back :+1:

    @JonnyMac

    Thanks Jon. Yeah, offset is fine....being able to zero the counter is what I really need :+1:

  • MicksterMickster Posts: 1,941

    Became side-tracked with an emergency but now have 3 encoders hooked up B)

    Smartpins totally ROCK! :lol::+1:

    Now I have another request that hopefully will be similarly elegant and self-explanatory. I'll start a new thread because on-topic titles might help future searchers.

  • aaaaaaaarghaaaaaaaargh Posts: 54
    edited 2021-11-18 15:49

    @Ariba said:
    pinstart(enc_a, P_PLUS1_B + P_QUADRATURE + P_SCHMITT_A + P_HIGH_15K + P_OE, 0, 0) 'init encoder with pullups

    Hi, I can't find the Pinstart function in the flexbasic documentation. But the this code compiles fine. Are there more hidden functions?

    Cheers

  • MicksterMickster Posts: 1,941

    Ditto:

    I have several, similar queries but I am attempting to track down the solutions before asking....a FlexBasic thread/repository would be useful :+1:

  • AribaAriba Posts: 2,552

    @aaaaaaaargh said:

    @Ariba said:
    pinstart(enc_a, P_PLUS1_B + P_QUADRATURE + P_SCHMITT_A + P_HIGH_15K + P_OE, 0, 0) 'init encoder with pullups

    Hi, I can't find the Pinstart function in the flexbasic documentation. But the this code compiles fine. Are there more hidden functions?

    Cheers

    These are lowlevel pin access functions coming from SPIN2. It makes a lot of sense to use the same function/methode names as in Spin also for BASIC and C. (In C they need an underscore at begin).

    The description of these functions can be found in the Parallax Spin2 document, together with the constant names. I've not looked into the flexBASIC documentation when I wrote that example, it was a translation from how I would write it in Spin, just with BASIC syntax.

    Andy

  • There are a BUNCH of C functions that just “magically” work in FlexBASIC. I know for a fact that most of the file IO calls work, as do many pin functions. There are probably more “undocumented” functions than there are documented functions. This seriously helps position FlexBASIC as a serious tool instead of a “toy” language. Many formal BASIC functions appear to be little more than just wrappers for underlying C functions. Play with them and see!

Sign In or Register to comment.