Вы находитесь на странице: 1из 7

We choose the Moon

Ingeniería aplicada incluso a cosas a las que probablemente no debería


aplicarse.

 Acerca de
 Bio
 El equipo

“Engineers like to solve


problems. If there are no
problems handily available,
they will create their own
problems.”
~ Scott Adams
Arduino + Matlab/Simulink: controlador
PID
Jorge García Tíscar
Jueves, 21 de julio de 2011

Nuestro principal proyecto con Arduino! En este caso, empleando el sistema de


comunicación serie, vamos a programar un controlador PID (un controlador que actúa
proporcionalmente al valor del error, al de su derivada, y al de su integral) en Simulink, el
programa de dibujar esquemas más caro de la historia. El objetivo es controlar la posición
de un sistema muy simple (podría ser llamado “helicóptero de un grado de libertad” por
alguien extremadamente idealista y “balancín a hélice” por alguien que lo fuera menos) y
gradualmente ir complicado el sistema.

Como se observa, se trata de un brazo articulado con un motor en un extremo, unido a una
hélice que proporciona más o menos sustentación en función del voltaje suministrado al
motor. En la articulación del eje hay un potenciómetro solidario a él, que devuelve un
voltaje entre 0V y 5V, en función del ángulo . El esquema del sistema de control es
el siguiente:

De esta manera tenemos definida la variable de salida (posición del eje: voltaje
transmitido por el potenciómetro) y la variable de control (sustentación de la hélice:
voltaje proporcionado al motor). Nos falta pues un bucle de control (que programaremos
en Simulink), una variable de entrada y una interfaz física.
Interfaz física: Arduino + circuito de potencia PWM

Tal y como se explica en una entrada


anterior, el Arduino es incapaz por sí mismo de aportar el amperaje que necesita el motor,
por lo que emplearemos un circuito de potencia consistente en un transistor MOSFET.

El microcontrolador enviará a la puerta del transistor una señal PWM, y por tanto esta
misma señal PWM pero de potencia será la que reciba el motor. La representación de este
montaje será la siguente:

Esta es toda la parte física del problema: la planta que vamos a controlar, la variable de
salida (ángulo del eje), la variable de control (potencia al motor) y el montaje que hemos
realizado con el Arduino. A continuación la parte de código, tanto de Arduino como de
Simulink/Matlab.

Arduino: lectura y escritura de variables físicas

En primer lugar, el código del Arduino debe ser capaz de (1) leer del potenciómetro,
(2) enviarlo como dato a través del puerto serie, (3) recibir el dato de potencia necesaria al
motor y (4) escribir dicho dato en la salida analógica como señal PWM. Hay que tener en
cuenta que el conversor devuelve un valor entre 0 y 1024, que mapeamos a 0 y 255 para
poder enviarlo como un solo bit unsigned.

int out = 0;
1
byte in = 0;
2
byte pinOut = 10;
3

4
void setup() {
5 // inicializar puerto serie

6 Serial.begin(9600);

7 // preparar output

8 pinMode(pinOut, OUTPUT);

9 }

10
void loop() {
11
// leer del pin A0 como
12
out = analogRead(A0);
13
// escalar para obtener formato uint8
14
out = map(out, 0, 1023, 0, 255);
15
// enviar en base 10 en ASCII
16 Serial.write(out);

17 // leer del serie si hay datos

18 if(Serial.available()){

19 in = Serial.read();

// escribir en el pin 10
20
analogWrite(pinOut, in);
21
}
22
// esperar para estabilizar el conversor
23
delay(20);
24}

25

26

27

Simulink: referencia y bucle de control

Por otra parte, nuestro programa de Simulink debe recibir este dato de a través del
puerto serie, compararlo con una referencia que controlaremos nosotros con un slider
en la propia interfaz gráfica de Simulink, y, mediante un controlador PID, determinar la
señal de control (potencia al motor) necesaria. Después debe enviarla a través del puerto
serie en formato uint8, unsigned integer de 8 bits, que toma valores entre 0 y 255, ideales
para la función analogWrite() de Arduino (click para ampliar):

Dentro del bloque PID, se pueden editar los parámetros P, I y D, siendo los últimos que
hemos empleado P = 0.26 , I = 0.9, D = 0.04 y una discretización de 10 ms. Otro dato a
tener en cuenta es que la transmisión serie se hace en formato uint8, pero las operaciones se
hacen en formato double, de ahí los conversores. Las ganancias son de valor 5/1024 para
pasar la señal a voltios reales.

A continuación, un vídeo de todo el sistema en funcionamiento (esta es una de las primeras


pruebas, con otros parámetros del PID sin optimizar todavía):

Matlab: postproceso de los datos recogidos

Si nos fijamos en el programa de Simulink anterior, se puede observar que no sólo se


presentan en el visor las tres señales, sino que además se guardan en el espacio de trabajo
de Matlab. Esto nos permite, a posteriori, procesar los resultados del proceso de control
como queramos: identificación de sistemas, exportación a Excel… en este caso, nos
contentamos con emplear la genial función externa savefigure() para obtener un gráfico
vectorial PDF:

%% Preparar la figura
1
f = figure('Name','Captura');
2 axis([0 length(ref_out) 0 5.1])

3 grid on
xlabel('Medida (-)')
4
ylabel('Voltaje (V)')
5
title('Captura de voltaje en tiempo real con Arduino')
6
hold all
7

8
%% Tratamiento
9
pos_out = pos_out(:);
10pid_out = pid_out(:);

11x = linspace(0,length(ref_out),length(ref_out));

12

13%% Limpiar figura y dibujar

14cla

15plot(x,pid_out,'Color',[0.6,0.6,0.6],'LineWidth',2)
plot(x,ref_out,x,pos_out,'LineWidth',2)
16
legend('Control','Referencia','Posición','Location','Best');
17

18
%% Salvar el gráfico
19
savefigure('resultado','s',[4.5 3],'po','-dpdf')
20

21

22

Ejecutando este código tras haber realizado una prueba del sistema, hemos obtenido el
siguiente gráfico, que a pesar de ser originalmente un gráfico vectorial PDF, hemos
rasterizado como PNG para poder representarlo aquí:
Se observa en
este caso que el motor requiere mucho menos voltaje (en gris) debido a que se trata de uno
más potente que el inicial y que el sistema presenta todavía una sobreoscilación (overshoot)
en la señal de salida (en rojo) cuando la señal de referencia (en verde) presenta una subida
escalón, cosa que esperamos corregir en futuras versiones. El siguiente desarrollo
programado es realizar un control con dos grados de libertad en lugar de uno… not because
it’s easy, but because it’s hard!

Вам также может понравиться