Control PID de Barra y Bola con Arduino

Control PID de Barra y Bola con Arduino 18 agosto, 2015 72 Comments Es fácil entender el Control PID estudiando un siste

Views 144 Downloads 5 File size 1MB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Control PID de Barra y Bola con Arduino 18 agosto, 2015 72 Comments Es fácil entender el Control PID estudiando un sistema Barra y Bola y utilizando como Controlador un Arduino. El objetivo es situar la bola en el centro de la barra inclinándola de forma conveniente mediante un lazo cerrado de control. Vídeo Resumen de 5 minutos:

Índice 



Sistema Barra y Bola o Sensado de la posición de la Bola  Acondicionamiento de la señal del sensor  Calibración del sensor o Actuador o Controlador o Alimentación de 5V o Esquema del sistema completo Control PID o Período de medida y reacción o Cálculo de la velocidad de la bola o Primera aproximación: El término Proporcional o Deteniendo la bola: El término Diferencial o Incrementando la precisión: El término Integral

Sistema Barra y Bola Es un sistema clásico en la Ingeniería de Control.   

Mediante un Sensor de distancia, medimos la posición de la bola. Con un Controlador, mediante control PID, calculamos el ángulo en el que deberíamos inclinar la barra para colocar y estabilizar la bola en el centro de la barra. Un Actuador modifica la inclinación de la barra.

Sistema Barra y Bola

Sensado de la posición de la Bola La realizamos mediante el sensor de distancia mediante luz infrarroja y detector PSD: SHARP GP2Y0A21.

Sensor SHARP

Tiene un rango de medida de 6 a 80 cm. Funciona con 5V y su salida es una tensión relacionada con la distancia medida mediante esta curva característica:

Curva Sensor SHARP

Si la Bola se acerca más de 6cm al sensor, la medida es errónea. Limitamos el movimiento de la bola en esa distancia.

Freno

Acondicionamiento de la señal del sensor Para filtrar (paso bajo) la señal del sensor y tener una señal más precisa y repetitiva, conectaremos un condensador electrolítico de 10μF entre la salida del sensor y tierra.

Efecto del condensador de filtrado

Como la tensión máxima que vamos a medir es de 3,1V, configuraremos la referencia de tensión del Arduino a 3,3V mediante la instrucción:

analogReference(EXTERNAL);

y conectaremos el pin AREF con la salida de 3,3V del Arduino:

Conexión de la Referencia Analógica a la salida de 3,3V

De esta forma, los 1024 puntos que nos proporciona el Conversor Analógico Digital de 10 bit del Arduino tendrán un fondo de escala de 3,3V en lugar de los 5V por defecto. Así, incrementamos la resolución de 5mV/ADC a 3mV/ADC.

Calibración del sensor Para relacionar la tensión proporcionada por el sensor con la distancia en centímetros, desplazaremos la bola por la barra tomando nota de la lectura en ADC. En el Software desarrollado para el Arduino, se incluye un modo de funcionamiento en el que transmite continuamente las lecturas del sensor por el puerto serie:

if(0){// Para calibrar sensor de Distancia Serial.print(dist); Serial.print("mm

ADC: ");

Serial.println(measure); }

Con 9 puntos a lo largo de la barra es suficiente. Obtenemos la curva de calibración del sensor.

Calibración del Sensor de distancia

que en el Software queda definida como:

int dcal [] = { // Calibracion de ADC a Distancia -193, -160, -110, -60, 0, 40, 60, 90, 120}; int ADCcal [] = { 177, 189, 231, 273, 372, 483, 558, 742, 970};

y para transformar las lecturas ADC del sensor, almacenadas en la variable measure, en la posición en mm de la variable dist, aplicamos el siguiente algoritmo:

for(int i =0; i= ADCcal[i] && measure< ADCcal[i+1]){ dist = map(measure,ADCcal[i],ADCcal[i+1],dcal[i],dcal[i+1]); }

La variable dist tiene valores negativos y positivos: -193mm en el extremo izquierdo de la barra, 120mm en el derecho y 0 en el centro. Como nuestro objetivo es dejar la bola en el punto central, esta variable dist equivale al error utilizado en la bibliografía de sistemas de control PID.

Actuador Inclinaremos la barra con un Servo HEXTRONIK HX5010 de 6,9 kg.cm de par motor y una biela de fibra de vidrio anclada a un extremo de la barra.

Actuador Servo

Como dice la Wikipedia, controlamos el giro del servo con pulsos de duración variable:

Control de la posición del servo mediante pulsos

En este servo en concreto la posición 0º se obtiene con pulsos de 0,5ms y el giro de 180º con 2,3ms. La biblioteca estándar (incluida en el IDE de Arduino) servo, incluye la instrucción write(angle), siendo angle un integer entre 0 y 180, que nos permite ajustar la posición del servo. Ésta es la instrucción que se usa habitualmente, pero como nosotros queremos la máxima precisión en el giro del servo, utilizaremos writeMicroseconds en su lugar. Su sintaxis es: servo.writeMicroseconds(μS), siendo μS los microsegundos de duración del pulso. Dispondremos de valores entre 500 (posición arriba) y 2300 (posición abajo), teniendo 1800 puntos distintos en lugar de sólo 180 usando la instrucción más básica: write(angle). Durante la puesta en marcha y ajuste, calcularemos la posición de reposo (barra horizontal) con la ayuda de un nivel de burbuja.

Nivel de burbuja

Controlador Utilizaremos un clon de Arduino con microcontrolador ATMEL ATMEGA328-PU equiparable al Arduino UNO o al antiguo Duemilanove original.   

Recibe la medida de la posición de la bola en su entrada analógica A0. Emite pulsos para controlar el servo en su salida digital 12. A través de su conexión USB envía distintos juegos de datos para debug o tramas de la forma:

173,173,-5,-5$ //dist,dist,vel,vel$

que son recibidas por un PC ejecutando una aplicación desarrollada en Processing y que nos permitirá disfrutar de gráficas de la posición y la velocidad de la bola en función del tiempo como ésta:

Gráfica de Processing



Como bonus, enciende un led conectado a la salida 13 cuando la bola está situada a menos de 8mm del centro.

Alimentación de 5V El Arduino recibe los 5V necesarios para su funcionamiento a través de su conexión USB. La potencia de su pin de 5V es insufiente para alimentar el servo, por lo que lo alimentaremos con una fuente de alimentación auxiliar. ¡No olvides conectar la tierra de la fuente de alimentación auxiliar con la tierra GND del Arduino! De lo contrario, las señales de control del servo no tendrán un referencia común y no funcionará.

Esquema del sistema completo

Esquema Control PID de Barra y Bola con Arduino

Conexiones

Conexiones Arduino – Breadboard

Control PID Una vez que tenemos implementado el sistema físico, llega el momento de dar al controlador la inteligencia necesaria para mover la barra de forma tal que consigamos nuestro objetivo: Dejar la bola quieta en el centro de la barra. Software para Arduino: _70_Barra_y_Bola_v5_MicroSegundos

Período de medida y reacción Las secuencias de medida y reacción (los ciclos de programa) no se harán tan rápido como pueda el microcontrolador, sino cada 50ms (valor almacenado en la variable period). Lo hacemos así porque los sistemas de control PID funcionan mejor si los ciclos de medida y reacción siempre tienen la misma duración. El microcontrolador, con reloj de 16MHz, tiene velocidad suficiente para hacer el ciclo de programa en menos de 10ms. Pero con ciclos tan rápidos, la medida de la velocidad de la bola pierde precisión porque las diferencias en la posición de la bola entre ciclos son ínfimas y nosotros calculamos la velocidad de la bola como la diferencia en su posición en 2 ciclos consecutivos de programa.

Si alargamos el periodo a 100ms, la medida de la velocidad es más precisa, pero el servo funciona de una forma perceptiblemente intermitente. Tras las pruebas realizadas, un período de 50ms aporta mediciones aceptables de la velocidad de la bola y un funcionamiento del servo fluido.

Cálculo de la velocidad de la bola En el Software que implementa el control PID en el Arduino calculamos la velocidad como la diferencia entre la posición actual de la bola (variable dist) y la que tenía en el ciclo anterior (variable lastDist). Vamos a mejorar la precisión de está medida mediante un filtro digital de paso bajo (Promediador) que consiste en obtener la media de la últimas 5 velocidades medidas. Las almacenamos en la matriz v[], y las tratamos con el siguiente algoritmo en cada ciclo de programa:

for (int i=0; iRint && abs(dist)