TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Thulsa Doom en 07 de Abril de 2011, 18:24:58
-
Hola a todos, estoy intentando implementar un algoritmo PID que tengo en un libro pero no me funciona bien, veo que tiene mucho sobreimpulso y la verdad es que no sé como corregirlo, en el libro dice que cambiando el tiempo de muestreo de 100ms a 1 ms pero ni así.
El algoritmo es este:
void main(void){
int16 valor;
int16 control;
float a,b,c;
float temp_limit;
float rT,eT,iT,dT,yT,uT,iT0,eT0,iT_1,eT_1;
float max,min;
//-------------------------------------------------------
min=0.0;
max=1000.0;
iT_1=0.0;
eT_1=0.0;
a=0.1243;
b=0.0042;
c=0.6215;
temp_limit=100.0;
//----------------------------------------------------------
valor=read_adc();
yT=valor*5000.0/1024.0;
rT=temp_limit;
eT=rT-yT;
iT=b*eT+iT0;
dT=c*(eT-eT0);
uT=iT+a*eT+dT;
if(uT>max){
uT=max;
}
else{
if(uT<min){
uT=min;
}
control=uT;
set_pwm1_duty(control);
iT0=iT;
eT0=eT;
delay_ms(1);
}
}
Hay una cosa que n o entiendo, en el programa hay dos variables que están a 0 pero que nunca se utilizan y no sé en realidad para que sirven, se trata de
iT_1=0.0;
eT_1=0.0;
Y si me pueden recomendar lectura sobre PID que sea en un lenguaje comprensible para novatos lo agradecería, gracias a todos
-
Y donde está el control? :shock: O sea, no veo que tomes muestras cada 100ms o 1ms...
Saludos!
-
Si hay mucho sobre impulso sera que el derivativo predomina, ademas el programa lo veo muy simple.
-
Y donde está el control? :shock: O sea, no veo que tomes muestras cada 100ms o 1ms...
Saludos!
Hola, pido disculpas porque no he explicado que esto es un fragmento del programa total, solo he puesto el PID, el control esta en en la variable valor, esa variable se carga con el dato de un max6675, y comprobado y funciona,
si es muy simple , por eso no entiendo por que hay tanto sobre impulso, estoy hablando de unos 40ºC de diferencia a la temperatura que se supone que tiene que ajustar, y si conoces otro algoritmo que sea mejor y me puedas recomendar te lo agradecería.
lo que sigo sin entender que hacen la variable iT_1 y eT_1 que estan inicializadas pero no veo que participen en las operaciones.
saludos a todos y gracias por la ayuda
-
Podrías analizar nuevamente el sistema y re-calcular las constantes del PID, puede que otra selección de valores tenga mejores resultados. Con MATLAB y sisotool puedes jugar bastante con esto.
Saludos!
-
Vale, entendido, es como dices, he comprobado que es un problema de hallar la recta de máxima pendiente de las resistencias que tengo en el horno y hacer el calculo, como no tengo interface para hacerlo en MATLAB lo intentaré hacer de manera manual con un voltímetro, un cronómetro y le aplicaré una señal escalón, no es lo ideal pero creo que me servirá como referencia.
otra cosa, si alguien conoce un algoritmo mejor, si quiere y puede compartirlo lo agradecería
saludos y gracias
-
Hola, creo que ya se cual es el problema, resulta que el programa que presento lo he modificado, en el programa original se utiliza un termopar en un componente llamado OVEN que tiene el proteus y al valor de ese mismo termopar se le hace un escalado al dato o valor para transformarlo en milivoltios.
El que utilizo yo lo he modificado para utilizar un max6675.
El max6675 toma el dato de la temperatura del termopar lo transforma a digital y lo envía al pic en una cadena de 12bits, lo que hice yo para poder ver la temperatura en un display es:
Como 12bits es equivalente a 4095 y el max6675 lo máximo que lee es 1023,75, ese valor de 4095 lo dividí por 4 y me dio el valor de 1023,75 (no sé si esta es la operación correcta para leer la temperatura).
Entonces en el programa sustituí
valor=read_adc();
yT=valor*5000.0/1024.0;por
yT=temperatura;Donde temperatura es el valor del max6675 ya dividido por 4.
Creo que el fallo de que no me funciona bien es ese que creo que tengo que escalar la medida del max6675 a milivoltios y la verdad es que no sé cómo hacerlo.
¿Que creéis vosotros?, ¿alguien me puede echar una mano con esto?, gracias.
el original es este:
void main(void){
int16 valor;
int16 control;
float a,b,c;
float temp_limit;
float rT,eT,iT,dT,yT,uT,iT0,eT0;
float max,min;
//-------------------------------------------------------
min=0.0;
max=1000.0;
iT0=0.0;
eT0=0.0;
a=0.1243;
b=0.0062;
c=0.6215;
temp_limit=1200.0; //set point 120ºC
TRISC = 0;
//----------------------------------------------------------
setup_timer_2(T2_DIV_BY_4,249,1);
setup_ccp1(CCP_PWM);
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
//---------------------------------------------------------------
while(TRUE){
valor=read_adc();
yT=valor*5000.0/1024.0;
rT=temp_limit;
eT=rT-yT;
iT=b*eT+iT0;
dT=c*(eT-eT0);
uT=iT+a*eT+dT;
//******Anti-Windup***************
if(uT>max){
uT=max;
}
else{
if(uT<min){
uT=min;
}
}
control=uT;
set_pwm1_duty(control);
iT0=iT;
eT0=eT;
delay_ms(100);
}
}
sacado de este pdf:
http://www.edutecne.utn.edu.ar/microcontrol_congr/industria/MTODOB~1.PDF