jueves, 3 de marzo de 2016

Control, PID, de velocidad con ATmega



Este post será dedicado al control de velocidad de un pequeño motor DC usando el algoritmo PID.
El esquema general a desarrollar se muestra a continuación (Figura 1).

Figura 1.
pid1

El algoritmo será implementado en un ATmega32. Este microcontrolador recibirá, por el puerto serie, órdenes desde una interfaz gráfica hecha en visual c# (Figura 2).

El programa en la PC permitirá enviar hacia el controlador(ATmega32) el SetPoint(SP), Kp(Ganancia proporcional), Ti(Tiempo integrativo en seg) y OUT cuando se seleccione modo manual. También permitirá graficar PV, SP y OUT. PV, SP y OUT son escalados de 0 a 100.

Figura 2.
PID


DEL SOFTWARE (en el controlador mega32).

Del uC usaremos:

  • Los pines PD0 y PD1 (INT0 e INT1) para leer las salidas(A y B) del encoder tal como en un post anterior.
  • El UART para recibir, mediante interrupción, SP,Kp,Ti y OUT(en modo manual) y para enviar PV y OUT(en modo automático).
  • El Timer1 para generar una interrupción cada 100ms que permitirá ejecutar el algoritmo de control y hacer el envío de datos a la PC.
  • El Timer2 para generar una señal PWM equivalente a la salida (OUT) del controlador. La salida será por el pin PD7/OC2.

El programa funcionará a una frecuencia de 7.3728MHz y el UART a 115200bps tal como se muestra en la figura 3.

Figura 3.
image


Se usaran las uniones de la figura 4. TRAMA_t es para la recepción y envío de datos hacia/desde la PC y States_t para el manejo de los estados del encoder.

Figura 4.
image
Las variables a usar son:

Figura 5.
image



count para contar los pulsos del encoder.
e[2] para almacenar el error actual (SP – PV) y el error pasado.
u[2] para almacenar la salida actual del algoritmo (OUT) y la salida pasada.
Se define algunas constantes como:

Figura 6.
image


PV_MAX y PV_MIN : Son los valores máximos y mínimos de PV medidos cuando OUT es llevado de 0 a 100%. Los usaremos para escalar el PV medido a un PV de 0-100% antes de ingresar al algoritmo de control.    
OUT_MAX y OUT_MIN : Valores máximos y mínimos en porcentaje de la salida del controlador. Nos servirá para acotar la salida del algoritmo de control. 
     
Es decir que el algoritmo PI tendrá como entradas (SP y PV) en escala de 0 a 100 y la salida (OUT) también será de 0 a 100. PV es llevado de 0-100 antes de entrar al PI. OUT sale del PI escalado de 0-100 y debe ser escalado de 0-255 antes de ponerlo en la salida PWM.
Los includes a usar son:

Figura 7.
image


Hay dos funciones que usaremos par leer y escribir en el uart, sus prototipos están en la figura 8. Estos prototipos deben ir antes del main.

Figura 8.
image


En la figura 9 se muestra el main. Aquí se configura el uart activando la transmisión, recepción e interrupción por recepción. También se configuran las entradas para el encoder, el Timer1 para que genere interrupciones cada 100ms y la salida PWM por el PINC0 usando el TIMER2.
Luego de la configuración se activa el bit de interrupción global y se espera en un bucle infinito.

Figura 9.
image


En la figura 10 se muestran las funciones para leer y escribir datos por el uart.

Figura 10.
image


En la figura 11 se muestra la interrupción por recepción del uart. Los datos son recibidos/transmitidos, de acuerdo a la estructura TRAMA_t, con una cabecera (0xAB), un cuerpo con valores y parámetros correspondientes al control y un chequeo de integridad, que no es otra cosa que la suma de todos los bytes anteriores.

Aquí se crea una variable local (dtt) del tipo TRAMA_t para almacenar los datos recibidos. La variable sum permite chequear la integridad de los datos recibidos.
Si el chequeo de integridad es correcto, los datos de la variable local dtt son copiados a la variable global dt.

Figura 11.
image


En la figura 12 se muestra las interrupciones de los pines PD2 y PD3. Aquí se leen las entradas del encoder como ya se explico en un post anterior. En retardo, _delay_ms(20), se debe a que el encoder que estoy usando genera algunos rebotes cuando cambia de estado, caso contrario, este retardo no sería necesario. El valor de las cuentas es almacenado en count.

Figura 12.
image


Antes de pasar al código del algoritmo de control… un poco de matemática:

image

Tengo que asumir que todos ya conocen la ecuación 1. Trabajaremos con esta ecuación para llegar a una forma discreta aproximada de la misma, la cual implementaremos en nuestro uC.

Primero, derivamos la ecuación 1 y tenemos:

image

Ahora haremos las siguientes aproximaciones (ec3, ec4 y ec5):

image

image

image

Reemplazando 3, 4 y 5 en 2.

image

Operando 6 tenemos:

image

En 7 vemos una ecuación del PID discreto para un T (Tiempo de muestreo) lo suficientemente pequeño.

En nuestro caso, para el control del motor, es suficiente con un PI, así que solamente usaremos la ecuación 8.

image

Dejando 8 en función de T y Kp tenemos:

image

La ecuación 9 será la ecuación a implementar. Kp (Constante proporcional), Ti (Tiempo integrativo en seg) y SP (Set point)son enviados desde la interfaz gráfica en la PC.

En la figura 13 se muestra la interrupción del timer 1. Esta interrupción ocurre cada 100ms, y es aquí donde se ejecuta nuestro algoritmo, por lo tanto T=0.1seg.

Figura 13.
image


* sum almacena de suma de los bytes antes de enviarlos al PC.
* Kp y Ti son los valores reales de estos parámetros, ya que desde la PC vienen multiplicados por 100. En las lineas 87 y 88 son calculados.
* 85.- se escala PV para que a la entrada del PI todo este en la escala de 0 a 100. En PV_MAX es obtenido poniendo el OUT al máximo en lazo abierto. Luego count es llegado a 0 para iniciar una nueva cuenta.
* 90.- se pregunta si estamos en modo automático para poder ejecutar el algoritmo.
* 92.-Se calcula el error actual. El SP es una valor de 0 a 100. La multiplicación por 1.0 es para convertir de uint16_t a double.
* 93.- Se calcula la salida u[0] del controlador. El 0.1 es el tiempo de muestreo T=0.1seg.
* 95-98.- Se guardan los valores de error y de la salida del PI, y también se limita la salida del PI al OUT_MAX que en este caso es 100.
* 99.- dt.OUT es el valor que será enviado a la PC.
* 100.- Se escala la salida u[0], que esta de 0 a 100, a un valor adecuado. En nuestro caso, el PWM generado por OCR2=[0 hasta 120] no genera movimiento en el motor. Este valor no debe paso 255 ya que OCR2 es un registro de 8 bits.
* 104.- Se hace el mismo escalamiento, pero usando el valor enviado desde la PC en modo manual.
* 107-113.- Finalmente, se envían los datos con su chequeo de integridad, hacia el PC para ser graficados.

El software, en la PC, permite cambiar el SP, Kp, Ti, y OUT mediante los slide de la figura 14.

Figura 14.
image

El programa también permite seleccionar entre automático y manual.

Figura 15.
image


Descargas:




1 comentario: