cancel
Showing results for 
Search instead for 
Did you mean: 

Encoder code acting strangely on

Omiks3
Associate

So I've got some very basic code for a STM32 to read an encoder using timer 1 in encoder mode.

This first routine works fine counting up and down as expected, printing CW (Clockwise) while counting up and CCW (Counter Clockwise) while counting down... The direction of the counter is read by the TIM_CR1_DIR bit with 1 for down.

cnt = TIM1->CNT;
// if counter counting down encoder is turning CW because i switched the wires
if (!(TIM1->CR1 & TIM_CR1_DIR) && cnt != prevCnt)
{
    printf("CCW, count = %d\n", 100 - cnt);
    prevCnt = cnt;
    pCnt = 0;
}
else if ((TIM1->CR1 & TIM_CR1_DIR) && cnt != prevCnt)
{
    printf("CW, count = %d\n", 100 - cnt);
    prevCnt = cnt;
    pCnt = 0;
}
HAL_Delay(50);

I thought I could clean it up a bit by taking out some of the redundant lines so I wrote this... But this routine acts really unpredictably sometimes it will print CCW while counting up and visa versa, or it will print CW while turning CCW. I'm fairly new to programming so I'd love to hear what I'm doing wrong.

Thanks!

cnt = TIM1->CNT;
if (cnt != prevCnt) {
   // if counter counting down encoder is turning CW because i switched the wires 
    if (TIM1->CNT & TIM_CR1_DIR)
        printf("CW, count = %d\n", 100 - cnt);
    else
        printf("CCW, count = %d\n", 100 - cnt);
 
     pCnt = 0;
     prevCnt = cnt;
 }
 else if (pCnt < 1)
 printf("No Change!, count = %d\n", cnt);
 
 pCnt++;
 HAL_Delay(50);

1 ACCEPTED SOLUTION

Accepted Solutions

> if (TIM1->CNT & TIM_CR1_DIR)

You probably meant

if (TIM1->CR1 & TIM_CR1_DIR)

JW

View solution in original post

3 REPLIES 3
TDK
Guru

Encoders, much like buttons, can be electrically noisy. I would ignore the DIR bit and compare TIM1->CNT to its previous value to determine the direction of rotation since the last time you checked it.

Your two code snippets are equivalent as far as I can see, except for the "no change" printout and the pCnt variable stuff.

If you feel a post has answered your question, please click "Accept as Solution".

> if (TIM1->CNT & TIM_CR1_DIR)

You probably meant

if (TIM1->CR1 & TIM_CR1_DIR)

JW

Thank you!

That makes sense why it was acting erratically, when bit 4 in TIM1->CNT was changing it was triggering a direction change in my code.