Encoder
1. Introduction
Rotating encoder is a input device that provides information about the direction and amount of rotation of a shaft. It has minimum two outputs, A and B, which are 90 degrees out of phase. The encoder generates a pulse each time it is rotated by a certain amount. The direction of rotation can be determined by the order of the pulses on the A and B channels.
![]() Magnetic Encoder |
![]() Open Drain Rotary Encoder |

Note
Above magnetic encoder does not need pull up resistors as it has built-in pull up resistors. But the open drain encoder needs pull up resistors. For 3V3
VDD, 4K7
pull up resistors are better. For 5V
VDD, 10K
pull up resistors are better.
2. CubeMX Configuration
Open CubeMX and generate basic code with:
microcontroller:
stm32f407vgt6
or board:STM32F407VG-DISC1
project name:
microsecond_tick
Toolchain/IDE:
Makefile
Go to
Pinout and Congiguration > Timers > TIM1
. SelectEncoder Mode
for Combined Channels.Under
Parameter Settings > Encoder
, change the Encoder Mode toEncoder Mode T1 and T2
. It is better to keep AutoReload Register value to65535
.Generate Code.
3. Code to Read Encoder Count
Navigate to
Core > Src
and openmain.c
.Include header file.
/* USER CODE BEGIN Includes */ #include <stdio.h> /* USER CODE END Includes */
/* USER CODE BEGIN Includes */ #include <stdio.h> #include "usbd_cdc_if.h" /* USER CODE END Includes */
Overwrite definition of
_write
as:/* USER CODE BEGIN 0 */ int _write(int file, char *data, int len) { for (int i = 0; i < len; ++i) { ITM_SendChar(data[i]); } return len; } /* USER CODE END 0 */
/* USER CODE BEGIN 0 */ int _write(int file, char *data, int len) { CDC_Transmit_FS((uint8_t*)data, (uint16_t)len); return len; } /* USER CODE END 0 */
Add code to read encoder count.
/* USER CODE BEGIN 2 */ HAL_TIM_Encoder_Start(&htim1, TIM_CHANNEL_ALL); uint32_t encoder_count = 0; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { encoder_count = htim1.Instance->CNT; // You also can use: // encoder_count = __HAL_TIM_GET_COUNTER(&htim1); printf("Count: %lu\n", encoder_count); HAL_Delay(100); } /* USER CODE END WHILE */
4. Observe Output
Connect encoder A and B channels to
TIM1_CH1
pin andTIM1_CH2
pin respectively.Open
STM32CubeProgrammer
and see count onSWV
by rotating encoder. If you used USB, see on terminal or serial monitor.
Caution
STM32F407VG-DISC1 TIM1 gives problem in high speed encoder reading if cable length is long. It is better to use other timers for high speed encoder reading.
Assignment: Calculate RPM.