cancel
Showing results for 
Search instead for 
Did you mean: 

Two rotary encoders on same board

paul sauv
Associate III
Posted on August 03, 2017 at 13:17

Hi everyone,

I'm working on a project where I need to set up two encoders.

I use included timers as timer encoder.

encoder 1 is configured on GPIO PB7/PB6

encoder 2 is configured on GPIO PB5/PB4

In order to isolate the mistake (hardware/software), here is what I tried:

  1. First, only 1 encoder wired to the board, only 1 timer configured on my board/code, on GPIO PB7/PB6:

    1. encoder 1 on PB7/PB6: working fine

    2. encoder 2 on PB7/PB6: working fine

    3. So hardware seems to be bine

  2. Then I modify my test code, I kept same code excepted I changed PB7/PB6 for PB5/PB4

    1. encoder 1 on PB5/PB4: not working

    2. encoder 2 on PB5/PB4: not working

What is really strange and I don't understand:

In case scenario 2, if I put encoder 1 on PB7/PB6 and encoder 2 on PB5/PB4, only PB5/PB4 are initialized in my sketch, encoder 2 is not working but encoder 1 on PB7/PB6 is working.

I'm using STD Periph lib, STM32F103 and Keil

here is my simple test code

&sharpinclude 'stm32f10x.h'

&sharpinclude 'stm32f10x_rcc.h'

&sharpinclude 'stm32f10x_gpio.h'

&sharpinclude 'stm32f10x_tim.h'

&sharpinclude 'delay.h'

&sharpinclude 'lcd16x2.h'

&sharpinclude <stdio.h>

uint16_t enc_cnt;

char enc_cnt_buf[8];

void init_lcd(void);

void init_rotary_encoder(void);

void lcd_update(void);

int main(void)

{

DelayInit();

init_lcd();

init_rotary_encoder();

while (1)

{

lcd_update();

}

}

void init_lcd()

{

// Initialize LCD

lcd16x2_init(LCD16X2_DISPLAY_ON_CURSOR_OFF_BLINK_OFF);

}

void init_rotary_encoder()

{

GPIO_InitTypeDef GPIO_InitStruct;

// Step 1: Initialize GPIO as input for rotary encoder

// PB7 (TIM4_CH2) (encoder pin A), PB6 (TIM4_CH1) (encoder pin B)

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_Init(GPIOB, &GPIO_InitStruct);

// Step 2: Setup TIM4 for encoder input

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising,

TIM_ICPolarity_Falling);

TIM_Cmd(TIM4, ENABLE);

}

void lcd_update()

{

// Get encoder value

enc_cnt = TIM_GetCounter(TIM4);

// Print encoder value

sprintf(enc_cnt_buf, '%i', enc_cnt);

lcd16x2_clrscr();

lcd16x2_puts(enc_cnt_buf);

lcd16x2_gotoxy(0,1);

lcd16x2_puts('Running');

DelayMs(250);

}

maybe answer is obvious but I can't find it.

Thank you for your help

#stm32f103 #rotary-encoder
6 REPLIES 6
Posted on August 03, 2017 at 13:28

0690X00000607rBQAQ.png0690X00000607rLQAQ.png

JW

paul sauv
Associate III
Posted on August 03, 2017 at 13:32

Ok, so obvious...

I will test it

Thank you

Posted on August 03, 2017 at 13:41

Make sure to enable the AFIO clock to allow for the Remap. The F1 design is a decade old, it had peripheral level remapping (block/group of pins), newer designs have pin level remapping.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on August 03, 2017 at 14:01

Thank you i will look for an example 

Posted on August 03, 2017 at 14:13

Watch the JTAG also, might want to remap or constrict that, should be a GPIO/JTAG example in the SPL release. There's a setting to just use the SWD subset of pins, don't have the resources at hand to check.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on August 03, 2017 at 14:18

According to what I found,

I should manage to do what I want with adding:

RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE

and

GPIO_PinRemapConfig

(GPIO_PartialRemap_TIM3, ENABLE);

As i want TIM3 to be on PB4 and PB5

I will test tonight