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

|

Instituto Tecnológico De Puebla


Depto. IEEE

MICROSOFT CONTROL I
Práctica 23-02-18
“PID ARDUINO”

Alumnos:
 Karen Iliana Bertado Teutli.
 Grecia Amairani Romero Landa.
 Osvaldo Machorro De Gante.
 Angel David Castillo Castro.

Profesor: José Rafael Mendoza Vázquez


Primavera 2018
PID ARDUINO
Objetivo: Realizar un control PID con las librerías de arduino para allar los
parámetros Kp, Ki y KD.
Material y equipo:
 Protoboard
 Motor con encoder
 Puente H
 Arduino Mega
 Jumpers

Desarrollo teórico.

Para la realización de la siguiente practica debemos recordar lo que es un control


PID que se definirá a continuación.

Se dice que un control es de tipo proporcional-integral-derivativo cuando la salida


del controlador v(t ) es proporcional al error e(t ), sumado a una cantidad
proporcional a la integral del error e(t ) más una cantidad proporcional a la
derivada del error e(t ):

por lo que en el dominio s le corresponde la expresión:


Un factor proporcional KpTd que actúa junto con un par de ceros (distintos,
repetidos o complejos, cuya posición es ajustable en el plano s) y un polo en el
origen. La representación en bloque de la ecuación (8.16) se muestra en la fi
gura 8.8a; la fi gura 8.8b es la representación en el plano s del control PID.

Figura 8.8a Representación en bloques del control PID. Dicha confi guración no
es válida para su uso en Simulink, ya que du/dt no representa un cero (véase el
apéndice A2).

Figura 8.8b Representación en el plano s del control PID; hay un polo en el


origen. Los ceros pueden ser reales distintos (1), reales repetidos (2) o complejos
(3).

Figura 8.8c Control proporcional-integralderivativo, el jumper 1 activa la parte


proporcional, el jumper 2 activa la parte integral, y el jumper 3 activa la parte
derivativa
Características

Control proporcional-integral

• El amortiguamiento se reduce.

• El máximo pico de sobreimpulso se incrementa.

• Decrece el tiempo de elevación.

• Se mejoran los márgenes de ganancia y fase.

• El tipo de sistema se incrementa en una unidad.

• El error de estado estable mejora por el incremento del tipo de sistema.

Control proporcional-derivativo

• El amortiguamiento se incrementa.

• El máximo pico de sobreimpulso se reduce.

• El tiempo de elevación experimenta pequeños cambios.

• Se mejoran el margen de ganancia y el margen de fase.

• El error de estado estable presenta pequeños cambios.

• El tipo de sistema permanece igual.


Control proporcional-integral-derivativo • Este tipo de controlador contiene las
mejores características del control proporcional derivativo y del control
proporcional-integral

Desarrollo práctico.
Vamos a utilizar un control PID; y que además se puede integrar facilmente con
una librería en Arduino creada por Brett Beaugerard. PID Library

Funciones

Creación del programa en arduino

//CONTROL l

//Pines para el puente h

const int motor1 = 6;//GIRA A LA DERECHA

const int motor2 = 7;//GIRA A LA IZQUIERDA


//Pines para el encoder y variables usadas en la función Encoder()

int encoderPinA = 14;//Q1

int encoderPinB = 15;//Q2

int encoderPos = 0;//Variable que guarda los conteos

int encoderPinALast = LOW;//Variable para guardar el valor anterior de n

int n = LOW;//Variable para guardar lo que mande el encoder como HIGH o LOW

int val;//Guarda valor dado por el usuario

int grados = 0;//Posición del encoder en grados

//Variables usadas por la funcion PID_pos() y PID_neg()

unsigned long lastTime;//Guarda valor anterior

double errSum, lastErr, _pid;//Variables para guardar el error y el valor de la


función del PID

//Constantes kp, ki y kd para el PID

double kp = 1;

double ki = 0.0002;

double kd = .1;

long signalPWM;//Variable para guardar la señal de PWM


#define valorGrados (360.0/160.0)//Constante para la conversión de las cuentas
del encoder a grados

#define TRUNCATE(value, mi, ma) min(max(value, mi), ma)//Encargada de la


conversión del valor del PID a PWM

void setup(){

Serial.begin (9600);//Inicializa el puerto serial 0

//Pines del encoder declarados como entradas

pinMode(encoderPinA,INPUT);

pinMode(encoderPinB,INPUT);

//Pines hacia el puente h declarados como salidas

pinMode(motor1, OUTPUT);

pinMode(motor2, OUTPUT);

//Pin del led para el serial declarado como salida

pinMode(led, OUTPUT);

//Encienda el led cuando el serial esta activado

digitalWrite(led, HIGH);

void loop(){

Encoder();//Manda a llamar la función encargada de los conteos del encoder

correrPID();//Manda a llamar la función encargada del PID


if(grados > val){//Si el valor de grados es mayor al dado por el usuario se
regresa al valor deseado

analogWrite(motor2, 4);

} else

if(grados < val){//Si el valor de grados es menor al dado por el usuario se


regresa al valor deseado

analogWrite(motor1, 4);

} else

if(grados == val){//Cuando el valor de grados sea igual al dado por el usuario


se apaga el motor

analogWrite(motor1, 0);

analogWrite(motor2, 0);

int lectura_BT_serial(){

if(Serial.available() > 0){

/*Variable que guarda el primer valor entero que

recibe del puerto serie de la PC

*/

val = Serial.readString().toInt();

//val = Serial.parseInt();
Serial.print("\t");

Serial.print(val);//Manda el valor de "val" al puerto serie

Serial.print("\n");

return val;//Retorna el valor de val para futuros calculos

/////////////////CONTEO DEL ENCODER/////////////////

void Encoder(){

n = digitalRead(encoderPinA);//Guarda un HIGH o LOW dependiendo de que


mande el encoder

if ((encoderPinALast == LOW) && (n == HIGH)) {//Decisión para empezar a


contar

if (digitalRead(encoderPinB) == LOW) {

encoderPos--;//Conteo de pulsos negativos o hacia la izquierda

} else {

encoderPos++;//Conteo de puslso positivos o hacia la derecha

grados = valorGrados*encoderPos;//Conversión de la posición del encoder en


grados

Serial.print("\n");

Serial.print(grados);//Manda la posión del encoder, en grados, al puerto serie

encoderPinALast = n;//Gurada el valor de n para el proximo conteo

}
/////////////////GENERACIÓN DE LA SEÑAL PWM CUANDO val ES
POSITIVO/////////////////

void PID_pos(){

//Cuanto tiempo paso desde el ultimo calculo

unsigned long now = millis();

double timeChange = (double)(now - lastTime);

//Calculo de las variables de error

double error = val - grados;

errSum += (error*timeChange);

double derr = (error - lastErr)/timeChange;

//Calculo de la función de salida PID

_pid = (kp*error)+(ki*errSum)+(kd*derr);

_pid = _pid/1000;

/*Conversión del valor generado por la función PID a un

valor entre 0 - 255 que es el valor de PWM reconocible

por el Arduino

*/

signalPWM = TRUNCATE(_pid,0,255);

//Guardado de valores de constantes para el siguiente calculo

lastErr = error;

lastTime = now;
}

/////////////////GENERACIÓN DE LA SEÑAL PWM CUANDO val ES


NEGATIVO/////////////////

void PID_neg(){

//Cuanto tiempo paso desde el ultimo calculo

unsigned long now = millis();

double timeChange = (double)(now - lastTime);

//Calculo de las variables de error

double error = val - grados;

errSum += (error*timeChange);

double derr = (error - lastErr)/timeChange;

//Calculo de la función de salida PID

_pid = (-kp*error)+(-ki*errSum)+(-kd*derr);

_pid = _pid/1000;

/*Conversión del valor generado por la función PID a un

valor entre 0 - 255 que es el valor de PWM reconocible

por el Arduino

*/

signalPWM = TRUNCATE(_pid,0,255);

//Guardado de valores de constantes para el siguiente calculo


lastErr = error;

lastTime = now;

/////////////////A USAR PID POSITIVO O NEGATIVO/////////////////

void correrPID(){

if(val > 0){//Operación para ver si el valor de "val" es positivo

PID_pos();

analogWrite(motor1, signalPWM);

analogWrite(motor2, 0);

} else if(val < 0){//Operación para ver si el valor de "val" es positivo

PID_neg();

analogWrite(motor1, 0);

analogWrite(motor2, signalPWM);

}
Resultados

Recomendaciones.
 Se recomienda utilizar un transportador para ver los grados en el que gira
el motor
 Colocar una flecha para que se aprecien los movimientos.
Conclusiones
Esta práctica fue un poco difícil de obtener debido al código extenso y por los
cual, teníamos que sacar los cálculos de Kp, Ki y Kd, ya que fue lo que nos
originó varios problemas para la implementación del código, finalmente Ki lo
cambiamos a 0.0002 para que perfeccionara los giros del motor y para así
mismos no se saliera del rango requerido.
Referencias bibliográficas.
file:///C:/Users/88555/Downloads/introduccion%20a%20los%20sistemas%
20de%20control.pdf

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