# 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**
> 
### **3. Counter Period: 65535**
> 
### **4. Encoder Mode: TI1 and TI2**
> 
### **5. Check TIM2 Global interrupt**

### **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

Also, change in the file **stm32f4xx_hal_tim.c**

And change in the file **stm32f4xx_hal_tim.h**

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

**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

: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.

## 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/

: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