AnsweredAssumed Answered

Two rotary encoders on same board

Question asked by paul sauv on Aug 3, 2017
Latest reply on Aug 3, 2017 by paul sauv

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

 

 

#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_tim.h"
#include "delay.h"
#include "lcd16x2.h"
#include <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

Outcomes