# STM32CubeIDE control motors ###### tags: `Learning Notes` [TOC] ## DC motor 1. Add pin: left click -> GPIO_Output 2. Change pin name: right click -> Enter User Label 3. Rename: DC1_1, DC1_2, DC2_1, DC2_2... (If PWM is needed, then add a timer channel for each pwm: timers -> select one TIMx -> Channel x: PWM Generation CHx -> Click one pluse mode) 4. Generate Code 5. Add DC motor code in while loop: * **four wheels go forward** ``` for(int i=0;i<4;i++){ int a=1; int b=0; HAL_GPIO_WritePin(DC1_1_GPIO_Port, DC1_1_Pin, a); HAL_GPIO_WritePin(DC1_2_GPIO_Port, DC1_2_Pin, b); HAL_GPIO_WritePin(DC2_1_GPIO_Port, DC2_1_Pin, a); HAL_GPIO_WritePin(DC2_2_GPIO_Port, DC2_2_Pin, b); HAL_GPIO_WritePin(DC3_1_GPIO_Port, DC3_1_Pin, a); HAL_GPIO_WritePin(DC3_2_GPIO_Port, DC3_2_Pin, b); HAL_GPIO_WritePin(DC4_1_GPIO_Port, DC4_1_Pin, a); HAL_GPIO_WritePin(DC4_2_GPIO_Port, DC4_2_Pin, b); HAL_Delay(1000); } ``` * **four wheels go backward** ``` for(int i=0;i<4;i++){ int a=0; int b=1; HAL_GPIO_WritePin(DC1_1_GPIO_Port, DC1_1_Pin, a); HAL_GPIO_WritePin(DC1_2_GPIO_Port, DC1_2_Pin, b); HAL_GPIO_WritePin(DC2_1_GPIO_Port, DC2_1_Pin, a); HAL_GPIO_WritePin(DC2_2_GPIO_Port, DC2_2_Pin, b); HAL_GPIO_WritePin(DC3_1_GPIO_Port, DC3_1_Pin, a); HAL_GPIO_WritePin(DC3_2_GPIO_Port, DC3_2_Pin, b); HAL_GPIO_WritePin(DC4_1_GPIO_Port, DC4_1_Pin, a); HAL_GPIO_WritePin(DC4_2_GPIO_Port, DC4_2_Pin, b); HAL_Delay(1000); } ``` PWM: * Add PWM setup code in main function after user code: ``` HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4); ``` :small_orange_diamond: htim1 means TIM1 * Add PWM code in while loop ``` htim1.Instance-> CCR1 = 80; htim1.Instance-> CCR2 = 80; htim1.Instance-> CCR3 = 80; htim1.Instance-> CCR4 = 80; ``` ## Servo (PWM) 1. Set timer: Timers -> select one TIMx -> Channel x: PWM Generation CHx 2. Generate code 3. Add code to start PWM and set the value: ``` HAL_TIM_PWM_Start(&htim10, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim12, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim13, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim14, TIM_CHANNEL_1); htim10.Instance->CCR1 = 75; htim12.Instance->CCR1 = 80; htim13.Instance->CCR1 = 100; htim14.Instance->CCR1 = 120; ``` 4. Add code in while loop: ``` i=0; while(i<10) { htim10.Instance->CCR1 = 75-i; htim12.Instance->CCR1 = 80+i; htim13.Instance->CCR1 = 100-i; htim14.Instance->CCR1 = 120+i; i++; HAL_Delay(1000); } ``` ## Encoder (1 DC motor) :spiral_note_pad: https://www.youtube.com/watch?v=xqzWQgpqHmI ### **1. TIM2~TIM5: General Timer** ### **2. Combined Channels: Encoder Mode** > ![](https://i.imgur.com/YrCJ2EO.png) ### **3. Counter Period: 65535** > ![](https://i.imgur.com/DD0fhwA.png) ### **4. Encoder Mode: TI1 and TI2** > ![](https://i.imgur.com/vdmlHlZ.png) ### **5. Check TIM2 Global interrupt** ![](https://i.imgur.com/MUvza04.png) ### **6. Add the code below** /* Private user code --------*/ /* USER CODE BEGIN 0 */ :::info uint32_t counter = 0; int16_t count = 0; void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { counter = __HAL_TIM_GET_COUNTER(htim); count = (int16_t)counter; } ::: /* 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(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART2_UART_Init(); MX_TIM2_Init(); /* USER CODE BEGIN 2 */ :::info HAL_TIM_Encoder_Start_IT(&htim2, TIM_CHANNEL_ALL); ::: /* USER CODE END 2 */ ### **7. Debug -> Add Live Expression** **Result:** {%youtube dW4vUvS0FHg %} ## Encoder(Multiple DC motor) ### Method 1: (Failed) change the type of function **HAL_TIM_IC_CaptureCallBack** and return the variable counter ![](https://i.imgur.com/c2nOn0k.png) Also, change in the file **stm32f4xx_hal_tim.c** ![](https://i.imgur.com/CGOSWRZ.png) And change in the file **stm32f4xx_hal_tim.h** ![](https://i.imgur.com/LoWWqKy.png) Compile successfully, but no response in the variable counter ### Method 2: (successful) use if condition to set four different variable, other setup same as 1 DC motor Encoder ![](https://i.imgur.com/BC4LhJl.png) **Tutorial and Result:** {%youtube G1HU4VpBhw0 %} ## ROS teleop-twist-keyboard control STM32 https://blog.csdn.net/weixin_39752599/article/details/86552189 https://blog.csdn.net/weixin_45438653/article/details/96884478 ## Copy a project in STM32CubeIDE ![](https://i.imgur.com/sG00Qym.png) :warning: If you want to add other function to the same STM32 board, ensure to signal pinning when setting the pins. If not, the pin may change when adding more functions. ![](https://i.imgur.com/qlcWHA5.jpg) ## multiple threads :spiral_note_pad: https://www.twblogs.net/a/5c9f6ed1bd9eee59d3323683 ## Voltage Sensor https://www.taiwansensor.com.tw/product/voltage-sensor-%E9%9B%BB%E5%A3%93%E6%84%9F%E6%B8%AC%E5%99%A8-%E9%9B%BB%E5%A3%93%E6%AA%A2%E6%B8%AC%E6%A8%A1%E7%B5%84/ ![](https://i.imgur.com/VoIAp4h.png) :round_pushpin: While measuring, you need to connect negative electrode of voltage sensor to STM32 GND, and S pin is needed to connect to a STM32 pin. 1. Analog -> ADC1 -> IN8 2. ADC Settings -> Continuous Conversion Mode: Enabled 3. Generate code 4. Add code: ``` /* USER CODE BEGIN PV */ uint16_t readValue; float voltage; /* USER CODE END PV */ /* USER CODE BEGIN 2 */ HAL_ADC_Start(&hadc1); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { HAL_ADC_PollForConversion(&hadc1,1000); readValue = HAL_ADC_GetValue(&hadc1); voltage =(float)readValue/4095*16.5; HAL_Delay(100); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ ``` 5. Debug -> Live Expression -> Add Expression: voltage