Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Juan_elec

#1
olas a todos que tal me parece muy interesante este foro ya que puedes compartir muxas ideas y cosas mas weno io queria contar y preguntar a la vez es que io hice una tarea en mi univ de un controlador de velocidad de un motor dc la velocidad es vista en un lcd y mi velocidad de referencia la escojo con un potenciometro ,mediante el pic16f876A corrijo el error  ante  una perturbacion en el eje mediante un pid programado en el pic weno el trabjo si me flipa pero mi problem es que mi valor de refencia que me aparece en el lcd de mi trabajo no es igual ami valor de salida de mi lcd mm y no se si seran los parametros de mi motor que esten mal o sera mis valores kp ki kd habe si alguien me dice alguito de como corregir esto pls mayor inf les puedo pasar mi simulacion en proteus si entienden mi idea gracias ahi les va el programa de formacion del pid.

#include <16F876A.h>
#device adc=10
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES PUT                      //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG             
     //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection

#use delay(clock=20000000)
#include <lcd.c>
#define  factor   3000/1023
#define  f2       0.23
#use fast_io(a)
#use fast_io(c)
#use fast_io(b)

float rpm,vel_m;
int   cont_t0;
int16 vel,vref,duty,aux;
signed long duty_c,uk_int;
float uk,uk_1,ek,ek_1,ek_2,f_vref;
int Kp,Ki,Kd;

void set_pwm1_dc(unsigned long duty_pwm);

#int_TIMER0
void TIMER0_isr()
{
   set_timer0(61);      // para contar 10 ms
   cont_t0++;
   if(cont_t0==10)
   {
      cont_t0=0;
      vel=get_timer1();   // contamos cuanros pulsos pasaron
      vel=vel*6;        // son 100 pulsos por revolucion
                        // asi obtenemos en revoluciones cada 100 milisegundos
                        // vel = #p/deci * 1rev/100p * 10 deci/1 seg * 60 seg/min
                        // vel esta en rpm
      lcd_gotoxy(9,2);
      printf(lcd_putc,"Vm=%Lu",vel);
      set_timer1(0);
   }
}

void main()
{
   set_tris_a(0xff);
   
   setup_adc(ADC_CLOCK_DIV_8);
   
   setup_adc_ports(AN0);
   set_adc_channel(0);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
   setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
   setup_timer_2(T2_DIV_BY_4,0XFF,4);
   setup_ccp1(CCP_PWM);
   set_pwm1_duty(0);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   set_timer0(61);
   set_timer1(0);
   clear_interrupt(INT_TIMER0);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
   
   set_tris_c(0b11111011);
   set_tris_b(0);
   output_b(0);
   lcd_init();
   set_pwm1_dc(700);
   lcd_putc("   CONTROL PID\n");
   delay_ms(1000);
   output_b(0);
   
   uk=0;
   uk_1=0;
   ek=0;
   ek_1=0;
   ek_2=0;
   
   Kp=10;
   Ki=10;
   Kd=5;
   for(;;)
   {
      aux=read_adc();
      if(aux!=vref)
      {
         vref=aux;
         f_vref=vref;
         rpm=vref*factor;
         lcd_gotoxy(1,2);
         printf(lcd_putc,"Vr=%4.0f",rpm);     
      }
      vel_m=vel;
      ek=rpm-vel_m;
     
      uk=Kd*ek_2+(Kp+2*Kd)*ek_1+(Kp+Ki+Kd)*ek-uk_1;   // controlador pid
      ek_1=ek;
      ek_2=ek_1;
      uk_1=uk;
      uk_int=uk;
      duty_c=uk_int*f2;
      if(duty_c>1023)
         duty_c=1023;
      else if(duty_c<=0)
         duty_c=0;
      duty=duty_c;
      set_pwm1_dc(duty);       
   }
   
}

void set_pwm1_dc(unsigned long duty_pwm)
{
#byte   CCP1CON=0x17
#byte   CCPR1L=0x15

   bit_clear(CCP1CON,4);
   bit_clear(CCP1CON,5);
   if(bit_test(duty_pwm,0))
         bit_set(CCP1CON,4);
   if(bit_test(duty_pwm,1))
         bit_set(CCP1CON,5);
   duty_pwm>>=2;                 //rota dos veces
   duty_pwm&=0x00FF;             // dejamos solo un byte
   CCPR1L=duty_pwm;     
}

graxias ojala me puedan ayuda xD