Skip to main content
garzarolli
Associate II
March 4, 2010
Question

32bit quadrature encoder

  • March 4, 2010
  • 6 replies
  • 1560 views
Posted on March 04, 2010 at 23:16

32bit quadrature encoder

    This topic has been closed for replies.

    6 replies

    darcy23
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:42

    Goddam forum threw an exception (three times) and lost my reply.  Fix this bloody thing guys!  Enough of us have been complaining about it.  It's a real disincentive to start all over again

    This method will mean you don't need to sacrifice a timer.  I'd make it a very high priority interrupt

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    void TIM2_IRQHandler(void)

    {

        uint16_t    snap = TIM2->CNT;

        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

        if ( snap < 0x7FFF )

            rotary_encoder_control.encoder_total_count_tracker += (sint32_t)0xFFFF;        //Roll over in upwards direction (high, then reset to low)

        else

            rotary_encoder_control.encoder_total_count_tracker -= (sint32_t)0xFFFF;        //Roll over in downwards direction (low, then reset to high)

        rotary_encoder_control.encoder_count_interrupt_catcher = false;

    }

    In the function that retrieves the encoder count

        do

        {

            //encoder_count_interrupt_catcher is set to false in the interrupt that modifies encoder_total_count_tracker

            //  If this process is interrupted by that interrupt we should detect it with the while condition below and

            //  take another snapshot of the values

            rotary_encoder_control.encoder_count_interrupt_catcher = true;

            snap_tracker = rotary_encoder_control.encoder_total_count_tracker;

            snap_counter = TIM2->CNT;

        } while ( rotary_encoder_control.encoder_count_interrupt_catcher == false );

        result = snap_tracker + (sint32_t)snap_counter;

    Darcy

    darcy23
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:42

    Looking at that, yes, it probably should inc/dec by 0x10000  :)

    Singh.Harjit
    Senior
    May 17, 2011
    Posted on May 17, 2011 at 13:42

    I like how you have created a ''lock'' around the counter read and the upper word increment. I implemented the same functionality but I like your implementation better.

     

    One question - shouldn't the 0xFFFF be ''0x10000'' since the overflow happens at 0x10000 (65536) pulses?

    Harjit

    Tomas DRESLER
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:42

    It does have LDREX/STREX.

    Thanks for this clever idea :)

    Btw. it's not possible by HW, there is no direction link between timers, except (probably) paralelizing the timers and setting the second one a prescaler by 32768 - and getting 31 bits. Never tested, though.
    davidwalker9
    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 13:42

    I haven't tried this yet, but does the STM32 support the STREX instruction? If so you could replace the access to the wrapped count as

    do {

      snap_tracker = __LDREX(&rotary_encoder_control.encoder_total_count_tracker);

      result = snap_tracker + (sint32_t)TIM2->CNT;

    } while (__STREX(snap_tracker, &rotary_encoder_control.encoder_total_count_tracker);

    If the tracker is touched in between the LDREX and STREX instructions by the ISR the operation will be retried.

    jveith
    Associate II
    July 28, 2012
    Posted on July 28, 2012 at 17:25

    Edison wrote:

    Btw. it's not possible by HW, there is no direction link between timers, except (probably) paralelizing the timers and setting the second one a prescaler by 32768 - and getting 31 bits. Never tested, though.

    Seems not working. I tried to use the prescaler as electronic gear to switch the rotary encoder between mm and cm. User must not use the prescaler in encoder mode. In case of changing the rotary direction, the counter cannot follow the wheel becouse the prescaler generates a ''dead zone''. Reversing the direction several times, moves the index reference more and more away.