Temporizador cuadruple

Se encuentra desarrollado para manejar 4 tiempos independientes de 1 minuto hasta 200 minutos, pudiendo manejar una salida aislada de potencia electrónica o contacto seco. 
En este post las salidas poseen una resistencia con un LED, ya que quedara a elección del desarrollador que interfaz utilizara.
El circuito funciona con 5V regulados (es preferente utilizar un 7805 o similar) o bien 3 pilas con un final de 4,5V.
El programa no utiliza ningún timer, lo que lo hace mas sencillo de comprender para aquellos que recién se inician.
El flow de este programa es muy sencillo y secuencial, básicamente se setea cada temporizador y luego se presiona Ok para que comiencen, posee una parada de emergencia con el botón stop.
La secuencia seria: "ingresar valor de temporizador 1" aqui se presina el boton Up o Dowm para los minutos, luego si se presiona Ok, pasara al siguiente temporizador, otra vez Up o Dowm y Ok, luego con el temporizador 3 y luego el 4, una vez seteados los cuatro valores se presiona Ok para que se inicien y comenzaran las cuentas regresivas, si por algún motivo se debe parar de emergencia solo se debe apretar el botón de Stop.
La secuencia para cargar cada valor de temporizacion se realiza con un SwitchCase, donde se incrementara una variable que seleccionara cada Case a medida que se presione el Ok, excepto cuando se esten ejecutando los temporizadores ya que ahí solamente se podrá salir por la parada de emergencia o al finalizar el ultimo temporizador, para ello se utiliza un flag que sera verdadero o falso y habilitara o no el pulsador Ok. 
El bucle de 1 minuto se realiza con dos lazos for concentricos, y notase que dentro del mismo se sitúa la lectura del botón de parada de emergencia, esto es así porque si se situaria fuera del mismo, se leería este botón cada 1 minuto, de esta forma se lee cada 100ms. Cada botón cuenta con una segunda lectura del mismo luego de unos mili-segundos para garantizar el anti-repique. La función decremento del tiempo (botón Down) posee una validación para cuando llegue a 0 y no pase a valores negativos.


#include <16F883.h>
#FUSES NOWDT
#FUSES INTRC_IO
#FUSES MCLR
#use delay(int=4000000)
#include <LCD.C>
void main(){
   INICIO:
   lcd_init();
   lcd_gotoxy(1,1);
   printf(lcd_putc,"  PRESIONE OK    ");
   lcd_gotoxy(1,2);        
   printf(lcd_putc,"PARA CONFIGURAR  ");   
   int1 run=1;
   int8 funcion=0, 
        tTimer1=0, 
        tTimer2=0, 
        tTimer3=0, 
        tTimer4=0,
        tMinutos=0,
        i=0, j=0;
   while(TRUE){
      if(input(PIN_C2)==1&&run){
         delay_ms(100);
         if(input(PIN_C2)==1&&run){
            funcion++;
            delay_ms(200);
            if(funcion>6)
               funcion=1;
         }    
      }
      switch(funcion){
      case 1:
         if(input(PIN_C0)==1){
            delay_ms(100);
            if(input(PIN_C0)==1){
               tTimer1++;
               delay_ms(100);
            }
         }
         if(input(PIN_C1)==1){
            delay_ms(100);
            if(input(PIN_C1)==1){
               if(tTimer1>0)
                  tTimer1--;
               delay_ms(100);
            }
         }
         lcd_gotoxy(1,1);
         printf(lcd_putc,"   TIEMPO DE    ");
         lcd_gotoxy(1,2);        
         printf(lcd_putc,"Timer 1: %2u min  ",tTimer1);
         break;
      case 2:
         if(input(PIN_C0)==1){
            delay_ms(100);
            if(input(PIN_C0)==1){
               tTimer2++;
               delay_ms(100);
            }
         }
         if(input(PIN_C1)==1){
            delay_ms(100);
            if(input(PIN_C1)==1){
               if(tTimer2>0)
                  tTimer2--;
               delay_ms(100);
            }
         }         
         lcd_gotoxy(1,1);
         printf(lcd_putc,"   TIEMPO DE    ");         
         lcd_gotoxy(1,2); 
         printf(lcd_putc,"Timer 2: %2u min  ",tTimer2);
         break;
      case 3:
         if(input(PIN_C0)==1){
            delay_ms(100);
            if(input(PIN_C0)==1){
               tTimer3++;
               delay_ms(100);
            }
         }
         if(input(PIN_C1)==1){
            delay_ms(100);
            if(input(PIN_C1)==1){
               if(tTimer3>0)
                  tTimer3--;
               delay_ms(100);
            }
         }           
         lcd_gotoxy(1,1);
         printf(lcd_putc,"   TIEMPO DE    ");         
         lcd_gotoxy(1,2);        
         printf(lcd_putc,"Timer 3: %2u min  ",tTimer3);
         break;
      case 4:
         if(input(PIN_C0)==1){
            delay_ms(100);
            if(input(PIN_C0)==1){
               tTimer4++;
               delay_ms(100);
            }
         }
         if(input(PIN_C1)==1){
            delay_ms(100);
            if(input(PIN_C1)==1){
               if(tTimer4>0)
                  tTimer4--;
               delay_ms(100);
            }
         }          
         lcd_gotoxy(1,1);
         printf(lcd_putc,"   TIEMPO DE    ");        
         lcd_gotoxy(1,2);        
         printf(lcd_putc,"Timer 4: %2u min  ",tTimer4);
         break;
      case 5:
         lcd_gotoxy(1,1);  
         printf(lcd_putc,"  PRESIONE OK    ");
         lcd_gotoxy(1,2);        
         printf(lcd_putc," PARA COMENZAR   ");
         break;
      case 6:
         if(tTimer1<tMinutos+1)
            output_low(PIN_C4);
         else
            output_high(PIN_C4);
         if(tTimer2<tMinutos+1)
            output_low(PIN_C5);
         else
            output_high(PIN_C5);            
         if(tTimer3<tMinutos+1)
            output_low(PIN_C6);
         else
            output_high(PIN_C6);            
         if(tTimer4<tMinutos+1)
            output_low(PIN_C7);
         else
            output_high(PIN_C7);  
         if(input_state(PIN_C4)==0&&
            input_state(PIN_C5)==0&&
            input_state(PIN_C6)==0&&
            input_state(PIN_C7)==0)
            goto INICIO;            
         for(i=0;i<4;i++){
            for(j=0;j<114;j++){
               delay_ms(100);
               if(input(PIN_C3)==1){
                  delay_ms(100);
                  if(input(PIN_C3)==1){
                     output_low(PIN_C4);
                     output_low(PIN_C5);
                     output_low(PIN_C6);
                     output_low(PIN_C7);
                     run=1;
                     goto INICIO;
                     delay_ms(100);
                  }
               }
               run=0;
               lcd_gotoxy(1,1);  
               printf(lcd_putc," PRESIONE STOP   ");
               lcd_gotoxy(1,2);        
               printf(lcd_putc," PARA CANCELAR   ");
            }
         }
         tMinutos++;          
         break;         
      }
   }
}

2 comentarios:

  1. ¡Hola Sebas! al simular en proteus me aparece lo sig:[PIC 16 MEMORY] PC=0x0231 OSCTUNE register is not modelled...¿Como lo puedo solucionar,alguna idea?...Gracias

    ResponderBorrar
    Respuestas
    1. Hola, es raro eso, la verdad. lo he simulado de vuelta para probar esto, pero no he podido reproducirlo.
      Saludos.

      Borrar