void pwm_duty (int8 p1, int8 p2) { pwm1_duty_percent = p1; set_pwm1_duty (percent_to_pwm (p1)); pwm2_duty_percent = p2; set_pwm2_duty (percent_to_pwm (p2)); }
void main() { unsigned int8 d; // delay value unsigned int8 i; unsigned int8 obyte=0; int16 spin; // pwm 0->1023 char c; // port D (7:0) SW,DW SZ,DZ SY,DY SX,DX init(); usb_cdc_init(); usb_init(); usb_wait_for_enumeration(); while (TRUE) { // get chars from usb housekeep(); // now process the input and feed output queue if (nqueue(&rxque0) > 0) { c = dequeue(&rxque0); if ((c&0xf0) == 0x90) { // step code obyte &= 0x55; // zero step bits if (c&XMASK) { obyte|= 0x02; } if (c&YMASK) { obyte|= 0x08; } if (c&ZMASK) { obyte|= 0x20; } if (c&WMASK) { obyte|= 0x80; } feed(obyte); } else if ((c&0x80)==0) { // delay code d = ((unsigned int8)c)&0x7f; for (i=1; i<=d; i++) { feed(0x00); // stall } } else if ((c&0xf0) == 0x80) { // dir code obyte &= 0xaa; // zero dir bits if (c&XMASK) { obyte|= 0x01; } if (c&YMASK) { obyte|= 0x04; } if (c&ZMASK) { obyte|= 0x10; } if (c&WMASK) { obyte|= 0x40; } } else if ((c&0xf0) == 0xa0) { if ((c&0x08)) { d = ((unsigned int8)c)&0x07; enable(d); // state } else { d = ((unsigned int8)c)&0x07; set_step(d); // mode } } else if ((c&0xc0) == 0xc0) { // spindle PWM speed spin=c&0x3f; // get the bits spin = spin<<4; set_pwm1_duty(spin); // duty cycle is val/(4*(255+1)) } else { ; // unknown code, silently ignore } } } }
void main() { setup_timer_2(T2_DIV_BY_16,255,1); //4.0 ms overflow, 4.0 ms interrupt setup_ccp1(CCP_PWM); setup_ccp2(CCP_PWM); set_pwm1_duty((int16)200); set_pwm2_duty((int16)200); enable_interrupts(INT_SSP); enable_interrupts(GLOBAL); SET_TRIS_B(0); stop(); //delay_ms(500); while(TRUE) { if(hasCommand) { hasCommand= FALSE; if(buffer[0] == 's'){ show(); } else switch(buffer[1]) { case 1: go_forward(); break; case 2: go_backward(); break; case 3: turn_right(); break; case 4: turn_left(); break; case 5: stop(); break; default : break; } } } }
void Glc_PIDdiscreto(void){ for(;;){ OS_Wait(GlaoGlc==2); //2 //OS_Bsem_Wait(BS_GLAGLC_FREE); output_toggle(PIN_B7); valorY=read_adc(ADC_READ_ONLY); //-- debido al ADC 10bits, la conversion se realiza con 10bits, //-- entonces valorY tiene rango de 0 a 1023 y=(float)valorY; //-- 1023/255=4.012, necesita adaptarse al mismo rango //-- porque el valorR que llega desde el GUI tiene max=255 r=(float)(valorR*4.012); //---------------------------------------------------------------------- //-- Calculo PID por metodo tustin para termino integral //-- y metodo de diferencias hacia atras para termino derivativo //-- Sea e(kT)=e; e(kT-T)=e1 e=r-y; //Sea p(kT)=p; i(kT)=i; i(kT-T)=i1; d(kT)=d p=Kpz*e; //i=i1+Kiz*e; //diferencia hacia atras i=i1+Kiz*(e+e1); //tustin d=Kdz*(e-e1); //diferencia hacia atras //Sea u(kT)=u u=p+i+d; //-- Anti-windup solo al termino integral para evitar que se infle //-- y se haga muy grande si la accion de control se satura, por tanto //-- es necesario impedir que cambie i //if((u>max) | (u<min)) {i=i-Ki*T*e;} //diferencia hacia atras //if((u>max) | (u<min)) i=i-Kiz*(e+e1); //tustin if(u>max)u=max; if(u<min)u=min; //-- realizar la conversion final control=(unsigned int16)u; set_pwm1_duty(control); e1=e; i1=i; OS_Delay(5000); //OS_Bsem_Set(BS_GLAGLC_FREE); OS_Yield(); } }
void Gla(void){ for(;;){ OS_Wait(GlaoGlc==3); //OS_Bsem_Wait(BS_GLAGLC_FREE); output_toggle(PIN_B7); //-- 1023/255=4.012, necesita adaptarse al mismo rango //-- porque el valorR que llega desde el GUI tiene max=255 r=(float)(valorR*4.012); control=(unsigned int16)r; set_pwm1_duty(control); OS_Delay(1000); //OS_Bsem_Set(BS_GLAGLC_FREE); OS_Yield(); } }
//**** Funciones genericas *************************************************** void Inicio(void){ //--- ini: mPaP ----------------------------------------------------------- numPulsosX=numPulsosY=numPulsosZ=numPulsosE=0; periodoPulsosX=periodoPulsosY=periodoPulsosZ=periodoPulsosE=0; //--- ini: PID ------------------------------------------------------------ min=0.0; max=1023 ; //valor Anti-windup i1=0;e1=0;d1=0; Kd=8; Kp=8; Ki=0.02915; T=5; //Tiempo de muestreo tr/6 < T < tr/20 Kpz=Kp; Kiz=Ki*T/2; Kdz=Kd/T; //--- ini: CCP --------------------------------------------------------- //--- Pre=16 PR2=249 Pos=1, PWMF=3kHz,PWMT=300us con Fosc(clock)=48MHz setup_timer_2(T2_DIV_BY_16,249,1); setup_ccp1(ccp_pwm); //Configurar modulo CCP1 en modo PWM set_pwm1_duty(0); //--- ini: ADC --------------------------------------------------------- setup_adc_ports(AN0|VSS_VDD ); setup_adc(ADC_CLOCK_INTERNAL); //setup_adc(ADC_CLOCK_DIV_8); //respetar el Tad>1.6us //Tad=8/Fosc=8/20Mhz=400ns set_adc_channel(0); //Seleccionar Canal(0)=AN0=A0 para ADC //--- ini: TIMER0 for OS_Timer() --------------------------------------- setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); //config Timer0, Pre=1=RTCC_DIV_1 //set_timer0(0xF63B); //carga del Timer0, clock=20MHz, Fout=1kHz=0xF63B set_timer0(0xE88F); //carga del Timer0, clock=48MHz, Fout=1kHz=0xE88F //--- ini: Interrupts -------------------------------------------------- //enable_interrupts(GLOBAL); enable_interrupts(INT_TIMER0); //habilita interrupcion Timer0 //enable_interrupts(INT_TIMER2); //--- ini: USB ------------------------------------------------------------ usb_init(); //inicializamos el USB usb_task(); //habilita periferico usb e interrupciones usb_wait_for_enumeration(); //esperamos hasta que el PicUSB //sea configurado por el host delay_ms(50); }
//Incluye las cabeceras antes descritas void main(){ //Rutina principal output_high(LED); //Enciende el LED indicador lcd_init(); //Rutina de incializacion del LCD lcd_putc("\fListo \n"); //Despliega el mensaje "Listo" en el LCD setup_adc_ports(AN0); //Fija el pin 0 del puerto A como entrada analogica setup_adc (adc_clock_internal); //El tiempo para la conversion AD esta dado por el oscilador //interno set_adc_channel(0); //El puerto AD activo es el 0 enable_interrupts(INT_EXT); //Habilita la interrupcion externa en RB0 ext_int_edge(L_to_H); //Fija la interrupcion por flanco de subida. setup_timer_2(T2_DIV_BY_16,129,16); //El tiempo de oscilacion del timer 2 sirve tanto para la //interrupcion por timer2 como para el PWM. setup_ccp1(CCP_PWM); //Da de alta el modulo CCP1 como PWM //y lo inicializa en duty cycle 0 set_pwm1_duty(0); setup_ccp2(CCP_PWM); //Da de alta el modulo CCP2 como PWM //y lo inicializa en duty cycle 0 set_pwm2_duty(0); enable_interrupts(GLOBAL); //Habilita las interrupciones globales output_low(LED); //Apaga el led antes encendido. while(TRUE){ //Esta rutina espera a la interrupcion y parpadea el LED //indicador output_low(LED); delay_ms(100); output_high(LED); delay_ms(100); } }
void UpdatePWM() { if (!STATUS.pid_lock || STATUS.error) ypwm = PWM_MIN; else { STATUS.saturated = false; if (ypwm & 0x8000){ /* first determine proper direction */ if (ypwm == 0x8000){ ypwm = PWM_MIN; STATUS.saturated = true; } else ypwm = -ypwm; REV_DIR; } else FWD_DIR; if (ypwm >= PWM_MAX){ ypwm = PWM_MAX; STATUS.saturated = true; } } set_pwm1_duty(ypwm); }
void main() { setup_timer_0 (RTCC_INTERNAL|RTCC_DIV_256); setup_timer_1 (T1_INTERNAL|T1_DIV_BY_8); setup_timer_2(T2_DIV_BY_16,155,1); setup_ccp1(CCP_PWM); set_pwm1_duty(0); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); enable_interrupts (int_TIMER1); enable_interrupts (GLOBAL); config (); while (true) { if (ReceberComando ()==1) { output_toggle (led) ; verificaComando (cmd[2]); } } }
void init() { unsigned int16 i; blink(); init_queue(&rxque0); init_queue(&txque0); set_step(1); // 0=full, 1=1/2, 5=1/4, 4=1/8, 7=1/16 enable(1); //setup_counters(T0_INTERNAL, T0_DIV_1 | T0_8_BIT); setup_counters(T0_INTERNAL, T0_DIV_2 | T0_8_BIT); set_timer0(0); enable_interrupts(INT_RTCC); enable_interrupts(INT_RDA); enable_interrupts(GLOBAL); output_bit(CTS,0); // ready to receive from usb output_bit(STROBE,1); // parallel port strobe // input(PIN_C3); // ESTOP input(PIN_C4); // ALIM input(PIN_C0); // XLIM input(PIN_C1); // YLIM // input(PIN_C2); // ZLIM output_bit(PIN_C2,0); // changed from ZLIM to PWM OUTPUT setup_ccp1(CCP_PWM); setup_timer_2(T2_DIV_BY_16, 255, 1); // mode, period, postscale set_timer2(0); set_pwm1_duty(0); // duty cycle is val/(4*(255+1)) }
void main() { setup_adc_ports(NO_ANALOGS); setup_adc(ADC_CLOCK_DIV_2); setup_psp(PSP_DISABLED); setup_spi(SPI_SS_DISABLED); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DIV_BY_16,155,1); setup_ccp1(CCP_PWM); setup_ccp2(CCP_PWM); set_pwm1_duty(312); // Inicia el Ciclo de Trabajo PWM1 en 50%. set_pwm2_duty(312); // Inicia el Ciclo de Trabajo PWM2 en 50%. setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); set_tris_a(0b11100000); // set_tris_c(0b10000000); //Pone RC7 como input y RC6 como output (y de 5 a 0 también) set_tris_b(0b00000000); // Habilita como salidas los pines B0, B1,...,B7 set_tris_e(0b010); // ************************ CONFIGURACIÓN PWM1 y PWM2: ************************ int32 brillo=0; int32 exposicion=500; //Tiempo de exposición de la cámara en [ms] int32 der_steps=0; int32 izq_steps=0; int32 led=0; int32 motor=0; int32 direccion=0; int32 pasos=0; int32 velocidad=0; char leido_pantalla[5]; output_low(PIN_B0); output_low(PIN_B1); output_low(PIN_B2); output_low(PIN_B3); output_low(PIN_B4); output_high(PIN_B6); // Siempre en 5V para conectar pull up 10kOhm de RA4 para SLEEP MOTOR 3 (altura) set_pwm1_duty(0); // Mantiene Ciclos en 0 para reducir consumo al iniciar. set_pwm2_duty(0); //*************** INICIO *************** while(true) { char seleccionar=0; output_low(PIN_A2); output_low(PIN_A3); output_low(PIN_A4); printf("Set parameters: e=exposicion(%Ld), v=velocidad(%Ld)\n\r",exposicion,velocidad); printf(" b=brillo(%Ld), d=direccion(%Ld), p=pasos(%Ld)\n\r",brillo,direccion,pasos); printf(" l=led(%Ld), m=motores(%Ld) \n\r",led,motor); seleccionar=getc(); switch(seleccionar) { case 'v': printf("Ingrese Velocidad en [ms] y [ENTER]\n\r"); fgets(leido_pantalla); velocidad=atoi32(leido_pantalla); break; case 'e': printf("Ingrese tiempo de exposicion en [ms] y [ENTER]\n\r"); fgets(leido_pantalla); exposicion=atoi32(leido_pantalla); break; case 'b': printf("Ingrese Ciclo de Trabajo para PWM1 (0-100) (brillo) y [ENTER]:\n\r"); fgets(leido_pantalla); brillo=atoi(leido_pantalla); set_pwm1_duty(brillo*20000000/(100*2000*16)); set_pwm2_duty(brillo*20000000/(100*2000*16)); break; case 'l': printf("Ingrese Led a encender: 0 a 7 y [ENTER]\n\r"); fgets(leido_pantalla); led=atoi32(leido_pantalla); break; case 'd': printf("Ingrese direccion 1=Derecha, 0=Izquierda y [ENTER]\n\r"); fgets(leido_pantalla); direccion = atoi32(leido_pantalla); break; case 'p': printf("Ingrese el numero de pasos a utlizar y [ENTER]\n\r"); fgets(leido_pantalla); pasos = atoi32(leido_pantalla); break; case 'm': printf("Ingrese el numero de motor a utlizar: 1,2 o 3 y [ENTER]\n\r"); fgets(leido_pantalla); motor = atoi32(leido_pantalla); break; case '1': led_on(led); break; case '2': led_off(); break; case '3': motor_move(motor,pasos,direccion); break; case '4': led_on_off(led,exposicion); break; case '5': int32 pasos_restantes; int32 steps; int dir; dir = direccion; steps = pasos; pasos_restantes = pasos; motor_on(motor); while(pasos_restantes > 0){ printf("pasos_restantes: %Ld\n\r",pasos_restantes); delay_us(200); steps = motores4(pasos_restantes,dir,velocidad); pasos_restantes = pasos_restantes - steps; if (pasos_restantes <=0) break; delay_us(200); dir = (dir == 0)?1:0; motores2(2000,dir); } break; case '6': int32 pasos_restantes2; int32 steps2; int dir2; dir2 = direccion; steps2 = pasos; pasos_restantes2 = pasos; motor_on(motor); while(true){ printf("pasos restantes: %Ld\n\r",pasos_restantes2); delay_us(200); steps2 = motores4(pasos_restantes2,dir2,velocidad); delay_us(200); dir2 = (dir2 == 0)?1:0; motores2(2000,dir2); pasos_restantes2 = pasos_restantes2 - steps2; if (pasos_restantes2 <=0) pasos_restantes2 = pasos; } break; case '7': int32 steps3; motor_on(motor); steps3 = motores4(pasos,direccion,velocidad); if (steps3 - pasos < 0){ direccion = (direccion == 0)?1:0; motores2(2000,direccion); delay_us(200); motores3(2147483640,direccion); direccion = (direccion == 0)?1:0; motores2(2000,direccion); } break; case '8': printf("Setup Calibracion Quick\n\r"); motor_on(motor); motores3(2147483640,DERECHA); delay_us(200); motores2(2000,IZQUIERDA); delay_us(200); izq_steps = motores3(2147483640,IZQUIERDA); delay_us(200); motores2(2000,DERECHA); delay_us(200); der_steps = motores3(2147483640,DERECHA); printf("izq_steps ->%Ld<- \n\r",izq_steps); printf("der_steps ->%Ld<- \n\r",der_steps); while(true){ motores2(izq_steps,IZQUIERDA); delay_us(200); motores2(der_steps,DERECHA); delay_us(200); } case '9': printf("Setup Velocidad ...\n\r"); output_high(PIN_A4); motores2(2000,IZQUIERDA); delay_us(200); izq_steps = motores3(2147483640,IZQUIERDA); delay_us(200); motores2(2000,DERECHA); delay_us(200); der_steps = motores3(2147483640,DERECHA); printf("izq_steps ->%Ld<- \n\r",izq_steps); printf("der_steps ->%Ld<- \n\r",der_steps); motores4(izq_steps,IZQUIERDA,velocidad); delay_us(200); motores4(der_steps,DERECHA,200); delay_us(200); break; } } } //FIN MAIN
main() { char selection; byte value; printf("\r\nFrequency:\r\n"); printf(" 1) 19.5 khz\r\n"); printf(" 2) 4.9 khz\r\n"); printf(" 3) 1.2 khz\r\n"); do { selection=getc(); } while((selection<'1')||(selection>'3')); setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM // The cycle time will be (1/clock)*4*t2div*(period+1) // In this program clock=10000000 and period=127 (below) // For the three possible selections the cycle time is: // (1/10000000)*4*1*128 = 51.2 us or 19.5 khz // (1/10000000)*4*4*128 = 204.8 us or 4.9 khz // (1/10000000)*4*16*128= 819.2 us or 1.2 khz switch(selection) { case '1' : setup_timer_2(T2_DIV_BY_1, 127, 1); break; case '2' : setup_timer_2(T2_DIV_BY_4, 127, 1); break; case '3' : setup_timer_2(T2_DIV_BY_16, 127, 1); break; } setup_port_a(ALL_ANALOG); setup_adc(adc_clock_internal); set_adc_channel( 0 ); printf("%c\r\n",selection); while( TRUE ) { value=read_adc(); printf("%2X\r",value); set_pwm1_duty(value); // This sets the time the pulse is // high each cycle. We use the A/D // input to make a easy demo. // the high time will be: // if value is LONG INT: // value*(1/clock)*t2div // if value is INT: // value*4*(1/clock)*t2div // for example a value of 30 and t2div // of 1 the high time is 12us // WARNING: A value to high or low will // prevent the output from // changing. } }
void main() { TRISC=0; // Variables para controlador int16 valor; float control; //valor del PWM float a1,b1,c1; //constantes del PID float ref; //temperatura a alcanzar float rT,eT,iT,dT,yT,uT,iT0,eT0,iT_1,eT_1; //variables de ecuaciones float max,min; //límites máximo y mínimo de control. float T ,Kp1, Ti1,Td1; setup_adc_ports(RA0_ANALOG);//entrada del LM35 setup_adc(ADC_CLOCK_INTERNAL); setup_COUNTERS(RTCC_internal.rtcc_div_1); set_adc_channel(0); setup_timer_2(t2_div_by_4,500,1); //periodo de la señal PWM a 1ms setup_ccp1(ccp_pwm); //Módulo CCP a modo PWM setup_adc(ADC_CLOCK_INTERNAL); //reloj convertidor AD interno set_adc_channel(0); setup_timer_0(rtcc_ext_l_to_h|RTCC_DIV_2); //Configuración TMR0 setup_timer_1(T1_internal|T1_DIV_BY_8); //Configuración TMR1 float Temp; int c; char k; char Kp[6]; char Ki[6]; char Kd[6]; char Sp[6]; int v; port_b_pullups(true), lcd_init(); kbd_init(); inicio: for (v=0;v<=5;v++){ Kp[v]=0; Ki[v]=0; Kd[v]=0; Sp[v]=0; } lcd_gotoxy(1,1); lcd_putc("\f"); lcd_putc("Kp:"); lcd_gotoxy(9,1); lcd_putc("Ki:"); lcd_gotoxy(1,2); lcd_putc("Kd:"); lcd_gotoxy(9,2); lcd_putc("Sp:"); while(true){ K_p: lcd_gotoxy(4,1); lcd_send_byte(0,0x0f); c=0; k=0; while(c<=4){ k=kbd_getc(); if(k!=0){ if(k!='A' && k!='*' && k!='C'){ if(k=='B'){ printf(lcd_putc,"."); Kp[c]=k; lcd_gotoxy(4+c,1); } else printf(lcd_putc,"%c",k); Kp[c]=k; lcd_gotoxy(4+c,1); } if(k=='A'){ c++; Kp[c]=-92; lcd_gotoxy(4+c,1); } } if(k=='D'){ int j=0; for(;;){ Kp[j]=0; if(j==5) break; j++; } c=0; lcd_gotoxy(1,1); lcd_putc("Kp: "); lcd_gotoxy(4+c,1); } if(k=='*'){ Kp[c+1]=-92; goto K_i; } } //FUERA DEL WHILE lcd_gotoxy(4+c-1,1); lcd_send_byte(0,0x0f); k=0; for(;;){ k=kbd_getc(); if(k!=0){ if(k=='*'){ break; } } } K_i: lcd_gotoxy(12,1); lcd_send_byte(0,0x0f); c=0; k=0; ///KI while(c<=4){ k=kbd_getc(); if(k!=0){ if(k!='A' && k!='*'){ if(k=='B'){ printf(lcd_putc,"."); Ki[c]=k; lcd_gotoxy(12+c,1); } else printf(lcd_putc,"%c",k); Ki[c]=k; lcd_gotoxy(12+c,1); } if(k=='A'){ c++; Ki[c]=-92; lcd_gotoxy(12+c,1); } } if(k=='D'){ int j=0; for(;;){ Ki[j]=0; if(j==5) break; j++; } c=0; lcd_gotoxy(9,1); lcd_putc("Ki: "); lcd_gotoxy(12+c,1); } if(k=='*'){ Ki[c+1]=-92; goto K_d; } } ///FIN KI ///FUERA DEL WHILE lcd_gotoxy(12+c-1,1); lcd_send_byte(0,0x0f); k=0; for(;;){ k=kbd_getc(); if(k!=0){ if(k=='*'){ break; } } } K_d: lcd_gotoxy(4,2); lcd_send_byte(0,0x0f); c=0; k=0; while(c<=4){ k=kbd_getc(); if(k!=0){ if(k!='A' && k!='*'){ if(k=='B'){ printf(lcd_putc,"."); Kd[c]=k; lcd_gotoxy(4+c,2); } else printf(lcd_putc,"%c",k); Kd[c]=k; lcd_gotoxy(4+c,2); } if(k=='A'){ c++; Kd[c]=-92; lcd_gotoxy(4+c,2); } } if(k=='D'){ int j=0; for(;;){ Kd[j]=0; if(j==5) break; j++; } c=0; lcd_gotoxy(1,2); lcd_putc("Kd: "); lcd_gotoxy(4+c,2); } if(k=='*'){ Kd[c+1]=-92; goto S_p; } } //FUERA WHILE lcd_gotoxy(4+c-1,2); lcd_send_byte(0,0x0f); k=0; for(;;){ k=kbd_getc(); if(k!=0){ if(k=='*'){ break; } } } ///SP S_p: lcd_gotoxy(12,2); lcd_send_byte(0,0x0f); c=0; k=0; while(c<=4){ k=kbd_getc(); if(k!=0){ if(k!='A' && k!='*'){ if(k=='B'){ printf(lcd_putc,"."); Sp[c]=k; lcd_gotoxy(12+c,2); } else printf(lcd_putc,"%c",k); Sp[c]=k; lcd_gotoxy(12+c,2); } if(k=='A'){ c++; Sp[c]=-92; lcd_gotoxy(12+c,2); } } if(k=='D'){ int j=0; for(;;){ Sp[j]=0; if(j==5) break; j++; } c=0; lcd_gotoxy(9,4); lcd_putc("Sp: "); lcd_gotoxy(12+c,2); } if(k=='*'){ Sp[c+1]=-92; goto PID; } } lcd_gotoxy(12+c-1,2); lcd_send_byte(0,0x0f); k=0; for(;;){ k=kbd_getc(); if(k!=0){ if(k=='*'){ break; } } } PID: printf(lcd_putc, "\f"); // Borra la pantalla lcd_gotoxy(4, 1); printf(lcd_putc, "procesando.. "); delay_ms(600); float result; a1 = conv(Kp); b1 = conv(Ki);c1 = conv(Kd);ref = conv(Sp); // strtod(cc,NULL); lcd_init(); iT0=0.0; eT0=0.0; min=0.0; //inicialización variables uT = 0.0; max=1023; while(True){ Temp=(float)read_adc(); yT=Temp*5.0/1024.0; rT=ref; eT=rT-yT; //Cálculo error lcd_gotoxy(1,2); printf(lcd_putc,"error:%f",eT); iT=b1*eT+iT0; //Cálculo del término integral dT=c1*(eT-eT0); //Cálculo del término derivativo uT=iT+a1*eT+dT; //Cálculo de la salida PID lcd_gotoxy(1,1); printf(lcd_putc,"Out:%f",uT); if (uT>max) { //Salida PID si es mayor que el MAX uT=max;} else { if (uT<min){ //Salida PID si es menor que el MIN uT=min;} } control=uT; //Transferencia de salida PID a señal PWM lcd_gotoxy(10,1); printf(lcd_putc,"Sp:%f",ref); set_pwm1_duty(control); iT0=iT; //Guardar variables eT0=eT; delay_ms(20); } } }
//Interrupcion por TIMER2 //Donde el ciclo de trabajo de los PWM se ajusta en relacion a la //temperatura actual y deseada void TIMER2_isr(void){ delay_us(20); //Espera el tiempo suficiente para el fin de conversion AD val=read_adc(); // El valor obtenido se guarda t=val*.5; // El sensor usado mantiene esta relacion funcional lcd_gotoxy(6,2); //Despliega el valor de la temperatura leido como valor OUT printf(lcd_putc,"OUT"); lcd_gotoxy(6,1); printf(lcd_putc,"%.2f",t); if (t<vn) { //Si la temperatura es menor a la deseada se definen "pasos" //proporcionales a la diferencia de temperaturas. STEPU=(vn-t); STEP2U=(vn-t); if (ds<MAX-STEPU){ //Aumentan el valor ds (duty cycle) en la electrobomba y //despliegan el aumento en el LCD ds=ds+STEPU; lcd_gotoxy(4,2); printf(lcd_putc,">"); lcd_gotoxy(10,2); printf(lcd_putc," +");} else if (ds2<MAX-STEP2U) { //Aumentan el valor de ds (duty cycle 2) en el calentador //y despliegan el aumento en el LCD ds2=ds2+STEP2U; set_pwm2_duty(ds2); lcd_gotoxy(10,2); printf(lcd_putc,"HT"); lcd_gotoxy(14,2); res=ds2; res=(res/MAX)*10; printf(lcd_putc,"%f",res); } else { lcd_gotoxy(10,2); //Si se da el caso que ningun valor puede ser aumentado //mas pues han llegado al limite, se despliega OL //(OVERLOAD) printf(lcd_putc,"OL"); } } else if (t>vn){ //Al contrario, si la temperatura es superior a la requerida //por el usuario, se reduce el ciclo de trabajo en pasos //proporcionales a la diferencia de temperaturas. if (ds>STEPD) { STEPD=(t-vn); ds=ds-STEPD; lcd_gotoxy(4,2); printf(lcd_putc,"<"); lcd_gotoxy(10,2); printf(lcd_putc," -");}} else if (t==vn){ lcd_gotoxy(4,2); printf(lcd_putc,"="); if (ds2>2) { ds2=ds2-1; set_pwm2_duty(ds2); lcd_gotoxy(10,2); printf(lcd_putc,"CD"); lcd_gotoxy(14,2); res=ds2; res=(res/MAX)*10; printf(lcd_putc,"%f",res);} else{ //Al alcanzar la temperatura deseada el controlador //despliega "i" de idle lcd_gotoxy(10,2); set_pwm2_duty(0); printf(lcd_putc," i"); lcd_gotoxy(14,2); printf(lcd_putc," ");} } set_pwm1_duty(ds); lcd_gotoxy(14,1); res=ds; res=(res/MAX)*10; printf(lcd_putc,"%f",res); }
void main() { //Configuraciones del PIC------------------------------------------------------- //Configuración de puertos... set_tris_A(0x0B); set_tris_B(0xFF); set_tris_C(0x80); set_tris_D(0x00); lcd_init(); dht_init(); //Parámetros del ADC... setup_adc(ADC_CLOCK_INTERNAL); //Reloj interno para conversiones setup_adc_ports(AN0_AN1_AN3); //Puertos usados como entradas //Parámetros para el PWM... setup_ccp1(CCP_PWM); //Módulo PWM activado setup_timer_2(T2_DIV_BY_4,249,1); //Onda de 4KHz //Parámetros de Timer0... setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16); //4ms para desbordamiento //Interrupciones... enable_interrupts(INT_RB); //Interrupción puerto B enable_interrupts(INT_RTCC); //Interrupción Timer0 enable_interrupts(INT_RDA); //Interrupción RS-232 enable_interrupts(GLOBAL); //Análisis de la bandera... set_pwm1_duty(0); lcd_init(); if(read_eeprom(0x00) == 0) { //LM35-------------------------------------------------------------------------- bitRes1=read_eeprom(0x01); cadEnv1=read_eeprom(0x02); offSens1=(float)read_eeprom(0x03)/10.0; if(read_eeprom(0x04)==0) offSens1*=-1.0; //------------------------------------------------------------------------------ //RHT03------------------------------------------------------------------------- cadEnv2=read_eeprom(0x06); offSens2=(float)read_eeprom(0x07)/10.0; if(read_eeprom(0x08)==0) offSens2*=-1.0; //------------------------------------------------------------------------------ //LDR--------------------------------------------------------------------------- bitRes3=read_eeprom(0x0A); cadEnv3=read_eeprom(0x0B); offSens3=(float)read_eeprom(0x0C)/10.0; if(read_eeprom(0x0D)==0) offSens3*=-1.0; //------------------------------------------------------------------------------ //PWM--------------------------------------------------------------------------- pwmSens=read_eeprom(0x0F); threshold[0]=read_eeprom(0x10); threshold[1]=read_eeprom(0x11); threshold[2]=read_eeprom(0x12); threshold[3]=read_eeprom(0x13); //------------------------------------------------------------------------------ } //------------------------------------------------------------------------------ while(true){ //Al presionar aceptar o cancelar se limpia el display.------------------------- if(cls){ cls=false; lcd_init(); } //Lectura de los sensores------------------------------------------------------- if(readSens){ readSens=false; ReadSensData(); } //Muestra las lecturas o configuraciones en el display-------------------------- if(!enterConfig && !displayConfigs) ShowDisplay(); else if(displayConfigs && !enterConfig) ShowConfigs(); if(enterConfig){ if(selector==1) ConfigLM35(); else if(selector==2) ConfigRHT03(); else if(selector==3) ConfigLDR(); else if(selector==4) ConfigPWM(); } if(save==true){ save=false; SaveC(); } //Control del ventilador-------------------------------------------------------- FanRPM(); //Lectura del búfer------------------------------------------------------------- if(read){ ReadBuffer(); ExecCmd(); SaveC(); } //Envío a la PC----------------------------------------------------------------- if(sendData){ sendData=false; if(segs1==cadEnv1){ MakeNSendFrame(1); segs1=0; } if(segs2==cadEnv2){ MakeNSendFrame(2); segs2=0; } if(segs3==cadEnv3){ MakeNSendFrame(3); segs3=0; } }//End if sendData }//End while }