Brise

[STM32CubeMX] STM32F429-DISC0 엔코더값 입력받기(quadrature encoder pulse) -2 본문

MCU

[STM32CubeMX] STM32F429-DISC0 엔코더값 입력받기(quadrature encoder pulse) -2

naudhizb 2017. 4. 29. 10:34
반응형

2017/04/28 - [STM32CubeMX] STM32F429-disc0 엔코더값 입력받기(quadrature encoder pulse) -1


이전 예제에서 이어 이 예제에서는 엔코더가 감지한 실제 각도를 액정에 출력해보겠습니다.


또한, 엔코더에 있는 Index 엔코더를 이용하여 한바퀴의 시작이 어느 부분인지 확인할 수 있도록 해보겠습니다.


설정 방식은 이전의 설정에 새로운 엔코더 모드로 동작하는 타이머를 동작시켜 실행합니다. 


수도 코드는 다음과 같습니다.


1. 엔코더값 감지

2. 각도 산출

3. 바퀴값이 바뀐경우 --> 산출된 각도를 갱신

4. 각도를 디스플레이



구현 코드는 다음과 같습니다.

버퍼링을 하면 좀 더 깔끔히 나오겠지만, 굳이 예제에 할필요는 없을 것 같네요;;


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_hal.h"
 
/* USER CODE BEGIN Includes */
#include "math.h"
#include "stm32f429i_discovery_lcd.h"
/* USER CODE END Includes */
 
/* Private variables ---------------------------------------------------------*/
DMA2D_HandleTypeDef hdma2d;
 
I2C_HandleTypeDef hi2c3;
 
LTDC_HandleTypeDef hltdc;
 
SPI_HandleTypeDef hspi5;
 
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim5;
 
SDRAM_HandleTypeDef hsdram1;
 
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_DMA2D_Init(void);
static void MX_FMC_Init(void);
static void MX_I2C3_Init(void);
static void MX_LTDC_Init(void);
static void MX_TIM2_Init(void);
static void MX_TIM5_Init(void);
static void MX_SPI5_Init(void);
 
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
 
/* USER CODE END PFP */
 
/* USER CODE BEGIN 0 */
uint32_t enc_counter = 0;
uint32_t enc_round = 0;
/* USER CODE END 0 */
 
int main(void)
{
 
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration----------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA2D_Init();
  MX_FMC_Init();
  MX_I2C3_Init();
  MX_LTDC_Init();
  MX_TIM2_Init();
  MX_TIM5_Init();
  MX_SPI5_Init();
 
  /* USER CODE BEGIN 2 */
  BSP_LCD_Init();
  BSP_LCD_LayerDefaultInit(LCD_BACKGROUND_LAYER, LCD_FRAME_BUFFER);
  BSP_LCD_LayerDefaultInit(LCD_FOREGROUND_LAYER, LCD_FRAME_BUFFER);
  BSP_LCD_SelectLayer(LCD_FOREGROUND_LAYER);
  BSP_LCD_DisplayOn();
  BSP_LCD_Clear(LCD_COLOR_WHITE);
  BSP_LCD_SetTextColor(LCD_COLOR_DARKGRAY);
  BSP_LCD_SetFont(&Font16);
 
  HAL_TIM_Encoder_Start(&htim2,TIM_CHANNEL_1);
  HAL_TIM_Encoder_Start(&htim5,TIM_CHANNEL_1);
  uint8_t arr[100= {0,};
  uint8_t arr2[100= {0,};
  uint8_t arr3[100= {0,};
  uint32_t width_c = BSP_LCD_GetXSize()/2;
  uint32_t height_c = BSP_LCD_GetYSize()/2;
  float angle = 0.0f;
  float rem_angle = 0.0f;
  uint32_t rem_round = 0;
 
 
 
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
      enc_counter = TIM2->CNT;
      enc_round = TIM5->CNT;
      angle = (enc_counter % 1024)/1024.0f*(2*M_PI);
      if (rem_round != enc_round){
          rem_angle = angle;
      }
      rem_round = enc_round;
      sprintf(arr,"CNT : %05d",enc_counter);
      sprintf(arr2,"RND : %05d",enc_round);
      BSP_LCD_DisplayStringAtLine(1,arr);
      BSP_LCD_DisplayStringAtLine(2,arr2);
 
      sprintf(arr3,"deg : %01.04f",angle);
      BSP_LCD_DisplayStringAtLine(3,arr3);
      BSP_LCD_SelectLayer(LCD_BACKGROUND_LAYER);
//      BSP_LCD_Clear(LCD_COLOR_WHITE);
      BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
      BSP_LCD_FillRect(width_c-50, height_c-50100100);
 
      BSP_LCD_SetTextColor(LCD_COLOR_RED);
      BSP_LCD_DrawLine(width_c, height_c,width_c+(50*cos(angle)), height_c+(50*sin(angle)));
 
      BSP_LCD_SetTextColor(LCD_COLOR_BLUE);
      BSP_LCD_DrawLine(width_c, height_c,width_c+(50*cos(rem_angle)), height_c+(50*sin(rem_angle)));
 
      BSP_LCD_SetTextColor(LCD_COLOR_DARKGRAY);
      BSP_LCD_DrawCircle(width_c, height_c,50);
      BSP_LCD_SelectLayer(LCD_FOREGROUND_LAYER);
  /* USER CODE END WHILE */
 
  /* USER CODE BEGIN 3 */
 
  }
  /* USER CODE END 3 */
 
}
cs


실행 영상은 다음과 같습니다. 





qep코드의 경우 값을 잘 입력받고 있으나, 
인덱스의 경우 하나의 핀으로만 인식하기 때문에 
반대방향으로 돌려도 바퀴수가 늘어나는 것을 알 수 있습니다. 

엔코더가 동작하는 방향을 공유하는 것이 필요하며 다음번 예제는 이부분을 개선하려 합니다.
(다만, 소프트웨어적으로 구현하면 결국 시간차가 생기는데...)


반응형
Comments