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:
stm32f407vgt6or board:STM32F407VG-DISC1project name:
microsecond_tickToolchain/IDE:
Makefile
Go to
Pinout and Congiguration > Timers > TIM1. SelectEncoder Modefor 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 > Srcand 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
_writeas:/* 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; // CNT value ranges from 0 to ARR value // 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_CH1pin andTIM1_CH2pin respectively.Open
STM32CubeProgrammerand see count onSWVby 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.