Shop Learn P1 Docs P2 Docs
32bit counter to 64bits — Parallax Forums

32bit counter to 64bits

Now that we have 64bit integers I would like to extend the range of the 32bit quadrature count. I can think of several ways to accomplish this but they will all be clunky :lol:

Anyone have a bit of slick-trickery to accomplish this, please?

Craig

Comments

  • evanhevanh Posts: 13,568

    I'd use the delta readings you get when X register is set. Upon each period, just accumulate the resulting delta into a 64-bit variable. Here's a C example:

    #include <stdio.h>
    #include <stdint.h>
    
    enum {
        // _xinfreq = 20_000_000,
        _xtlfreq = 20_000_000,
        _clkfreq = 320_000_000,
        DOWNLOAD_BAUD = 230_400,
        DEBUG_BAUD = DOWNLOAD_BAUD,
    
        ENCPIN = 25,
        CYCLERATE = 5,   //Hertz
    };
    
    
    void  main( void )
    {
        uint64_t  position = 1_000_000;
    
        _waitms( 200 );
        printf( "\n   clkfreq = %d   clkmode = 0x%x\n", _clockfreq(), _clockmode() );
    
        _pinstart( ENCPIN, P_QUADRATURE | P_PLUS1_B, _clockfreq() / CYCLERATE, 0 );  // SmartB = base+1
    
        while( true )
        {
            if( _pinread( ENCPIN ) )
            {
                position += _rdpin( ENCPIN );
                printf( " position = %lld  \r", position );
            }
        }
    }
    
  • MicksterMickster Posts: 2,216
    edited 2022-09-12 12:24

    So each _rdpin returns the delta from the previous _rdpin?
    So rollover never occurs?

    Edit: If the _pinread function = false, there is no delta to be read?
    Craig

  • evanhevanh Posts: 13,568
    edited 2022-09-12 13:09

    @Mickster said:
    So each _rdpin returns the delta from the previous _rdpin?
    So rollover never occurs?

    Technically -1 is an unsigned rollover. On that note, it might work better to cast the delta to signed and make the 64-bit variable signed too. Not sure, I haven't actually tested anything.

    Edit: If the _pinread function = false, there is no delta to be read?

    Correct, you'll just get the pre-existing delta until a new one is ready. The X timer can be used as the servo loop timer - can also generate a metronomic event or interrupt.

  • MicksterMickster Posts: 2,216

    This is pretty exciting stuff :+1:

    Yeah the aim is to end-up with signed 64-bit.

    Many thanks.

    Craig

  • evanhevanh Posts: 13,568
    edited 2022-09-12 14:31

    I think it's working okay as is. Signed doesn't seem to matter. However, FlexC's printf() is doing weird emits with 64-bit negative values. If I use %d instead of %lld then I get what appears to be a pair of 32-bit signed numbers printed that would be correct as a combined 64-bit integer. Eg: -1, -1 for negative one. But with %lld it prints a huge negative number when it should be negative one. EDIT: -18446744069414584321

  • evanhevanh Posts: 13,568
    edited 2022-09-12 14:45

    If you're programming a continuous rotary machine that flows in one direction, then there's no need to go 64-bit. The 32-bit rollover is clean. You don't get overflows or accumulated errors as long as you're using true integers.

    What I did was do all the profile calculations with velocity and curve fitting using floats but always converted back to integers for the final positional mapping. Everything neatly packed into exact lossless full turns.

  • MicksterMickster Posts: 2,216

    @evanh said:
    I think it's working okay as is. Signed doesn't seem to matter. However, FlexC's printf() is doing weird emits with 64-bit negative values. If I use %d instead of %lld then I get what appears to be a pair of 32-bit signed numbers printed that would be correct as a combined 64-bit integer. Eg: -1, -1 for negative one. But with %lld it prints a huge negative number when it should be negative one. EDIT: -18446744069414584321

    Partially resembles unsigned 64-bit:
    18446744073709551615

  • evanhevanh Posts: 13,568
    edited 2022-09-12 15:35

    %lld is a 64-bit signed integer emit. It ignores the actual data type of the variable, although will be bound to the variable's memory space.

  • MicksterMickster Posts: 2,216

    @evanh said:
    If you're programming a continuous rotary machine that flows in one direction, then there's no need to go 64-bit. The 32-bit rollover is clean. You don't get overflows or accumulated errors as long as you're using true integers.

    What I did was do all the profile calculations with velocity and curve fitting using floats but always converted back to integers for the final positional mapping. Everything neatly packed into exact lossless full turns.

    Not so much need 64-bit but if it can be had, it would be nice to have a position range of -9223372036854775808 to 9223372036854775807 quad-counts. :smile:

    Craig

  • ersmithersmith Posts: 5,433

    @evanh said:
    I think it's working okay as is. Signed doesn't seem to matter. However, FlexC's printf() is doing weird emits with 64-bit negative values. If I use %d instead of %lld then I get what appears to be a pair of 32-bit signed numbers printed that would be correct as a combined 64-bit integer. Eg: -1, -1 for negative one. But with %lld it prints a huge negative number when it should be negative one. EDIT: -18446744069414584321

    There was a bug with casts from 32 to 64 bit values. It should be fixed in github now.

  • evanhevanh Posts: 13,568

    @ersmith said:
    There was a bug with casts from 32 to 64 bit values. It should be fixed in github now.

    Fixed indeed. :)

Sign In or Register to comment.