Sunteți pe pagina 1din 19

Control PID

Aplicación a arduino
Control PID
• Es un mecanismo de control
por realimentación (lazo
cerrado) ampliamente usado
en sistemas de control
industrial.
• El algoritmo calcula la
desviación o error entre un
valor medido y un valor
deseado (Set Point) a partir del
cual genera tres parámetros
distintos: el proporcional, el
integral, y el derivativo.
• El control PID es uno de los controladores mas
empleados en la industria
• No es aplicable a sistemas complejos (MIMO)
Ecuación controlador PID
Donde
¿CÓMO IMPLEMENTAR EL
CONTROL PID EN ARDUINO?
Actividad 1: (15 mins)
DESARROLLE EL CÓDIGO PARA REALIZAR EL CONTROL PID
EN UN ARDUINO
Código Básico PID
/* variables de trabajo */
unsigned long lastTime;
double Input, Output, Setpoint;
double errSum, lastErr; double kp, ki, kd;

void Compute() {
/*¿Cuanto tiempo ha pasado desde la ultima vez que fue calculado?*/
unsigned long now = millis();
double timeChange = (double)(now - lastTime);
/*calcula todas las variables de error */
double error = Setpoint - Input; errSum += (error * timeChange);
double dErr = (error - lastErr) / timeChange;
/*calcula la salida del controlador PID */
Output = kp * error + ki * errSum + kd * dErr;
/*recuerda variables para la siguiente vez */
lastErr = error; lastTime = now;}

void SetTunings(double Kp, double Ki, double Kd) {


kp = Kp; ki = Ki; kd = Kd; }
Problemáticas
• Tiempo de muestreo:
– El controlador PID funciona mejor si es evaluado a intervalos regulares, si el algoritmo
conoce ese intervalo, se puede simplificar la matemática interna.
• Saltos derivativos (Derivative Kick)
– Los cambios en la referencia producen saltos en la componente derivativa.
• Mitigación de subida de componente integral (anti-Windup)
– Cuando el Pid piensa que puede enviar cualquier valor de salida, por lo que
• Auto/manual:
– en la mayoría de aplicaciones se desea que en algunos momentos se apague el
controlador PID y se ajuste la salida manualmente.
• Inicialización:
– Cuando el controlador inicia, se requiere que la entrada en operación del controlador
sea sin saltos abruptos.
• Dirección del controlador:
– Los controladores pueden ser directos o Inversos
Tiempo de Muestreo
• El PID básico está diseñado para ser llamado irregularmente.
Esto causa 2 problemas:
– No obtiene un comportamiento consistente del PID, ya que a veces se
llama con frecuencia y otras no.
– Necesitas hacer cálculos matemáticos adicionales derivados e
integrales, ya que ambos dependen del cambio en el tiempo.
• Solución:
– Asegurar que el PID se llama a intervalos regulares.
– Se puede integrar mediante un tiempo de muestreo determinado
mediante el cual el PID escoge si debe computar o esperar.
• Una vez que se sabe que el PID se ejecuta a un intervalo
constante, los cálculos de la integral y la derivada se
simplifican.
Derivative Kick
Wind Up
• Problema:
– El problema ocurre cuando el PID cree que
puede hacer algo que no puede. Por ejemplo,
la salida PWM en un Arduino acepta valores
de 0-255. Por defecto, el PID no lo sabe. Si
cree que 300-400-500 funcionará, intentará
esos valores esperando obtener lo que
necesita.
• Solución
– decirle al PID cuáles son los límites de salida.
Una vez que se alcanza cualquiera de los
límites, el pid deja de sumar (integrando).
Sabe que no hay nada que hacer; Como la
salida no termina, obtenemos una respuesta
inmediata cuando el punto de corte cae en un
rango en el que podemos hacer algo.
Código PID
/*working variables*/
unsigned long lastTime;
double Input, Output, Setpoint;
double ITerm, lastInput;
double kp, ki, kd;
int SampleTime = 1000; //1 sec
double outMin, outMax;
bool inAuto = false;
#define MANUAL 0
#define AUTOMATIC 1
#define DIRECT 0
#define REVERSE 1
int controllerDirection = DIRECT;
void Compute() {
if(!inAuto)
return;
unsigned long now = millis();
int timeChange = (now - lastTime);
if(timeChange>=SampleTime) {
/*Compute all the working error variables*/
double error = Setpoint - Input;
ITerm+= (ki * error);
if(ITerm > outMax)
ITerm= outMax;
else if(ITerm < outMin)
ITerm= outMin; double dInput = (Input - lastInput);
/*Compute PID Output*/
Output = kp * error + ITerm- kd * dInput;
if(Output > outMax) Output = outMax;
else if(Output < outMin)
Output = outMin;
/*Remember some variables for next time*/
lastInput = Input; lastTime = now; } }
void SetTunings(double Kp, double Ki, double Kd) {
if (Kp<0 || Ki<0|| Kd<0)
return;
double SampleTimeInSec = ((double)SampleTime)/1000;
kp = Kp; ki = Ki * SampleTimeInSec;
kd = Kd / SampleTimeInSec;
if(controllerDirection ==REVERSE) {
kp = (0 - kp); ki = (0 - ki);
kd = (0 - kd);
}
}
void SetSampleTime(int NewSampleTime) {
if (NewSampleTime > 0) {
double ratio = (double)NewSampleTime / (double)SampleTime;
ki *= ratio;
kd /= ratio;
SampleTime = (unsigned long)NewSampleTime;
}
}
void SetTunings(double Kp, double Ki, double Kd) {
if (Kp<0 || Ki<0|| Kd<0)
return;
double SampleTimeInSec = ((double)SampleTime)/1000;
kp = Kp; ki = Ki * SampleTimeInSec;
kd = Kd / SampleTimeInSec;
if(controllerDirection ==REVERSE) {
kp = (0 - kp); ki = (0 - ki);
kd = (0 - kd);
}
}
void SetSampleTime(int NewSampleTime) {
if (NewSampleTime > 0) {
double ratio = (double)NewSampleTime / (double)SampleTime;
ki *= ratio;
kd /= ratio;
SampleTime = (unsigned long)NewSampleTime;
}
}
void SetOutputLimits(double Min, double Max) {
if(Min > Max)
return;
outMin = Min;
outMax = Max;
if(Output > outMax)
Output = outMax;
else if(Output < outMin)
Output = outMin;
if(ITerm > outMax)
ITerm= outMax;
else if(ITerm < outMin)
ITerm= outMin;
}
void SetMode(int Mode) {
bool newAuto = (Mode == AUTOMATIC);
if(newAuto == !inAuto) {
/*we just went from manual to auto*/
Initialize();
}
inAuto = newAuto; }
void Initialize() {
lastInput = Input;
ITerm = Output;
if(ITerm > outMax)
ITerm= outMax;
else if(ITerm < outMin)
ITerm= outMin;
}
void SetControllerDirection(int Direction) {
controllerDirection = Direction;
}
Librería PID Arduino
• El código mostrado anteriormente
corresponde a la librería PID de Arduino.

S-ar putea să vă placă și