Hola colegas, me encuentro haciendo un control PI para un motor de cd y trato de simularlo en el proteus, la cosa es que mi programa lee el Adc por el canal cero e internamente realiza el error que es dado por la retroalimentacion que coloco en el canal 1, esta retro es unitaria, la coloco de esta manera solo para hacerle pruebas, pero el pwm falla mucho y no reacciona como debiera, mi PI arroja una respuesta de 0 a 100% con el antiwindup, esa respuesta la multiplico por 5 de tal forma que me de 500 que corresponde al 100% del pwm, el css no me marca errores, pero en el proteus nada mas no funciona como debiera. No responde bien, aveces si saca pwm y aveces no, de momento se traba. He realizado PID en microcontroladores de freescale y no me genera tantos problemas.
El algoritmo PI lo implemente en otro micro de la famia flexis y funciona bien, solo cambie la resolucion, en aquel micro es de 16 bits y 32 bits, se que aqui debe funcionar perfectamente.
Ojala me puedan ayudar. Ojala puedan detectar el error, pienso que es el proteus o algo asi.
He hecho un programa en donde solo saco el pwm que es leido por el canal cero del AD y ni asi funciona, funciona cuando le mete directamente el valor pwm, por ejemplo cuando le meto 250 saca el 50% pero cuando le coloco que saque en pwm leido por el adc no mas no funciona.
para sacar de 0 a 500 que es del 0 al 100% aplico una formulita:
pwm=(long)2*ADC // siendo que AD varia de 0 a 255 con un AD= 8 bits, pero ¿por uqe no funcona? haaaaaaaaaa
me vuelvo loco ayuda ayuda ayuda porfavor
#include <16F877A.h>
#device adc=8
#fuses XT,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
#use delay(clock=4000000)
//#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#byte PORTB=0x06
#use fast_io(c)
int lectura=0;
int contador=0;
long duty;
float Set_Point, Sensor,Pwm_n,Pwm_aw, Error_n,Error_n_1,Pwm_n_1=0;
float Set_Point_Real,Sensor_Real, Pb1,Pb2, Periodo_Muestreo=0.065,Ti=2.5,Tiempo;
float V1,V2,Ki,Kp=10,Pwm_aws;
int a=0;
#INT_timer0
void timer0(void)
{
set_adc_channel(0);
Set_Point=read_adc();
//delay_ms(100);
portb=Set_Point;
// set_pwm1_duty((long)250);//ciclo util de 0 a 500 que correspode aqui si saca bien el pwm
set_adc_channel(1); // del 0% al 100%
Sensor=read_adc();
//delay_ms(100);
Sensor_Real=100*(Sensor/255);
Set_Point_Real=100*(Set_Point/255);
// set_timer0(0);
Error_n=Set_point_Real-Sensor_Real;
Ki=1/Ti;
Pb1=100/Kp;
Pb2=(Pb1*Set_Point_Real)/100;
Tiempo=Periodo_Muestreo/2;
V1=Periodo_Muestreo/Ti;
V2=1/(1+V1);
Pwm_n=(10/Pb2)*(Error_n+Error_n_1*(Ki*Tiempo-1))+Pwm_n_1;
Error_n_1=Error_n;
Pwm_aw=Pwm_n;
//antiwindup
if (Pwm_aw>100)
{ //Salida PID si es mayor que el 100%.-
Pwm_n=(Pwm_n + V1)*V2;
Pwm_aw=100;
}
if(Pwm_aw<0)
{ //Salida PID si es menor que el 0%
Pwm_n=Pwm_n*V2;
Pwm_aw=0;
}
Pwm_n_1=Pwm_n;
Pwm_aws=(long)5*Pwm_aw;
set_pwm1_duty((long)Pwm_aws);//¿por qué a qui ya no me saca bien el pwm?
//no creo que sea mi PI porque he realizado un programa donde solo saco en pwm lo que le entra por el ADC aplicandole la for
//mula pwm=(long) 2*ADC;
set_timer0(0);
}
void main()
{
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(RA0_RA1_ANALOG_RA3_REF);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,124,1); //se configura a 500Hz
setup_ccp1(CCP_PWM); //PWM
set_tris_b(0x00);
set_tris_c(0x00);
portb=0x00;
enable_interrupts(GLOBAL);
enable_interrupts(INT_timer0);
set_timer0(0);
//el timer queda configurado con 65.6mseg
while(TRUE)
{
}
}
Ojala me puedan ayudar. Gracias