STM32 y Raspberry Pi (computadora host) controlan interactivamente el brazo robótico


、 El
brazo robótico habitual se compone de varios engranajes de dirección. Yo uso un brazo robótico de cinco grados de libertad (poco común) en cierto tesoro. Aunque los comerciantes lo llaman seis grados de libertad.

Aquí, los 6 canales de salida PWM de STM32F407VGT6 se utilizan para controlar el movimiento de los servos 6. La Raspberry Pi (computadora host) se comunica con STM32 a través del módulo USB a TTL.

Principio de servocontrol PWM

El servo PWM estándar tiene tres líneas de control: líneas de potencia, tierra y señal.
Pequeño mecanismo de dirección
La mayoría de los engranajes de dirección de 180 ° en el mercado requieren un período de onda PWM de 20 ms, el tiempo de recepción de alto nivel suele ser de 0,5 ~ 2,5 ms y el ángulo de rotación del mecanismo de dirección correspondiente es de 0 ~ 180 °. Cuando use la onda PWM para controlar el servo, solo necesita configurar el ciclo del reloj en 20ms (50Hz) y cambiar el tiempo de alto nivel de la onda PWM cambiando el pulso del valor de comparación para controlar el ángulo de rotación del servo.

Configuración principal de STM32CubeMx

Para STM32, uso STM32CubeIDE + Mx para el desarrollo. El diagrama de bloques del reloj es la configuración predeterminada, como se muestra en la figura.
Diagrama de bloques del reloj STM32

TEMPORIZADOR

Debido a la necesidad de controlar 6 servos, elegí TIM3 (4 salidas PWM) y TIM9 (2 salidas PWM).
La frecuencia de la salida PWM está determinada por el reloj APB2. A partir del diagrama de bloques del reloj, la frecuencia APB2 aquí es 16MHz; la fórmula para calcular la frecuencia de la onda PWM es:

W = APB2 / (PSC + 1) (ARR + 1)

Entre ellos, PSC es el coeficiente de división de frecuencia y ARR es el valor de recarga automática. Aquí configuro PSE en 39 y ARR en 7999.
Configuración del temporizador
Tenga en cuenta que cuando el modo de contador es diferente, la dirección de rotación del servo será diferente cuando el valor de comparación sea el mismo.

Dado que el tiempo de alto nivel de la onda PWM debe controlarse dentro de 0.5 ~ 2.5ms, el valor de comparación (pulso) de cada canal PWM debe controlarse dentro de 200 ~ 1000; (8000 x 0.5 / 20 = 200) (8000 x 2.5 / 20 = 1000)

Cuando el ángulo de rotación del mecanismo de dirección es de 90 °, el valor del pulso debe ser 600. Aquí establezco el valor de comparación de cada canal de salida PWM en 600.
Configuración del canal PWM
Dado que uno de los engranajes de dirección en el brazo robótico que tengo a mano se usa para controlar las garras mecánicas, es un mecanismo de dirección de 90 °, por lo que al configurar el canal PWM para controlar el mecanismo de dirección, el rango de valores de comparación solo puede ser 200 ~ 600, y el valor medio es 400 El microordenador de un solo chip que utilizo es STM32F407VGT6, y los canales de salida PWM correspondientes a TIM3 y TIM9 son PA6, PA7, PB0, PB1 y PE5, PE6 respectivamente.
Solo necesita configurar estos puertos IO como multiplexación de salida push-pull y pull-up.
GPIO - EQUIPO

Configuración del puerto serie

Aquí elijo USART_2 para la comunicación en serie, y su Tx y Rx corresponden a PA2 y PA3 respectivamente.

La configuración del puerto serie se muestra en la figura. Configuración del puerto serie
Aquí se utiliza el modo de comunicación asíncrona Tenga en cuenta que la velocidad en baudios y otros parámetros deben coincidir con la computadora superior.

GPIO en serie
Tanto PA2 como PA3 están configurados para multiplexar la salida push-pull con pull-up.

Control de interrupción

Dado que solo uso el puerto serie para recibir interrupciones aquí, no es necesario configurar NVIC aquí; si STM32 tiene otras tareas además de controlar el brazo robótico, es posible que deba configurar NVIC.

Implementación del código STM32CubeIDE

Una vez configurado STM32CubuMx y generado el proyecto, nuestra tarea principal es diseñar el protocolo de comunicación entre la computadora host y el microcontrolador, y completar la función de interrupción de recepción del puerto serie.

Diseño de protocolo de comunicación

Mi diseño inicial es enviar datos una vez a través del puerto serie para controlar el ángulo de un solo servo; por lo tanto, los datos enviados deben incluir el número del servo y el ángulo objetivo del servo (o el valor de comparación convertido desde el ángulo).

Aquí no diseñé el cabezal de comunicación y controlé la velocidad del mecanismo de dirección, porque aquí mi puerto serial solo se usa para transmitir comandos para controlar el mecanismo de dirección, y yo uso un mecanismo de dirección pequeño, su velocidad no es muy rápida, lo cual me puede satisfacer Requisitos, no es necesario controlar su velocidad.

La idea de diseño es la siguiente: la
computadora host envía datos de 16 bits cada vez (2 tipos uint8_t, el puerto serie solo puede enviar puerto serie), el número de servo es 0 ~ 5, el valor de pulso enviado es (200 ~ 1000) -200, y el servo El valor numérico se multiplica por 1000 más el valor de pulso menos 200 para obtener un valor de tipo uint16_t; luego se convierte a hexadecimal y se envía.

Ejemplo: Opere el servo No. 3, el ángulo es de 45 °.

Procesamiento de datos:
3 x 1000 + (45 ° / 180 °) x 800 = 3200;
3200 se convierte a hexadecimal: 0x0C80.

STM32 realiza la operación inversa para obtener los datos originales.

Implementación del código STM32

Dado que el puerto serie envía dos datos de tipo uint8_t, es necesario convertir los dos datos de tipo uint8_t en uno de tipo uint16_t antes de la decodificación.

Cuando se activa la interrupción de recepción de USART2, se configura para recibir dos datos de tipo uint8_t en la interrupción de recepción para facilitar el procesamiento de datos en la función de procesamiento de interrupción de recepción.

uint8_t pulse[2];
HAL_UART_Receive_IT(&huart2, pulse, sizeof(pulse));

El puerto serie acepta el código de función de interrupción de la siguiente manera:



void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    
    
	if(huart->Instance == USART2)
	{
    
    
		uint8_t rec0, rec1;

		// 获取接收到的两个字节的数据
		rec0 = *((huart->pRxBuffPtr) - 2);
		rec1 = *((huart->pRxBuffPtr) - 1);

		uint16_t numPart[2], armControl, arm targetPulse;

		// 通过移位与强制转换得到uint16_t类型数据
		numPart[0] = (uint16_t) rec0;
		numPart[1] = (uint16_t) rec1;
		armControl = ((numPart[0] << 8) | numPart[1]);

		// 逆向解码
		arm = armControl / 1000;  // 舵机编号
		targetPulse = armControl % 1000 + 200;	// 目标比较值

		// 通过switch语句改变指定PWM通道的比较值
		switch(arm)
		{
    
    
			case 1:
				__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, targetPulse);
				break;

			case 2:
				__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, targetPulse);
				break;

			case 3:
				__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, targetPulse);
				break;

			case 4:
				__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, targetPulse);
				break;

			case 5:
				__HAL_TIM_SET_COMPARE(&htim9, TIM_CHANNEL_1, targetPulse);
				break;

			case 6:
				__HAL_TIM_SET_COMPARE(&htim9, TIM_CHANNEL_2, targetPulse);
				break;
		}
	}
}

El canal PWM debe habilitarse antes de ingresar al bucle while;

  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);
  HAL_TIM_PWM_Start(&htim9, TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim9, TIM_CHANNEL_2);

Y habilite la interrupción de recepción del puerto serie en la función USART2_IRQHandler:

void USART2_IRQHandler(void)
{
    
    
  /* USER CODE BEGIN USART2_IRQn 0 */

  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
  HAL_UART_Receive_IT(&huart2, pulse, sizeof(pulse));
  /* USER CODE END USART2_IRQn 1 */
}

prueba

En la prueba, usé la Raspberry Pi con Ubuntu 18.04 instalado, y la herramienta de depuración en serie fue CuteCom; la microcomputadora de un solo chip y el mecanismo de dirección (brazo robótico) funcionaban con una batería de litio de 5 V, y se enviaban manualmente dos bytes de datos cada vez, decimal La conversión a hexadecimal se realiza en una calculadora científica. El movimiento del brazo robótico cumple con las expectativas.

Después de la prueba, enviando 12 bytes de datos al mismo tiempo, el brazo robótico también puede funcionar normalmente.

Cabe señalar aquí que al realizar el cableado, el cable de tierra del mecanismo de dirección debe compartir la misma tierra con el microcontrolador.

Después de eso, el código enviado por el puerto serie de la computadora host se puede escribir en el programa C ++ o Python, y el brazo del robot puede ser controlado por la computadora host.

Supongo que te gusta

Origin blog.csdn.net/weixin_46068920/article/details/108646782
Recomendado
Clasificación