Autor Tema: temporizador  (Leído 3765 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Rufus

  • PIC10
  • *
  • Mensajes: 14
temporizador
« en: 31 de Julio de 2018, 14:44:12 »
Buenas tardes amigos. tengo un problema con mi codigo. estoy realizando un vending despachador de agua y estoy usando en total 4 temporizadores. Timer0 para tiempo de llenado de 10 lts (17 seg.), Timer 1 para tiempo de llenado de 20 lts (37seg.), Timer2 para tiempo de llenado de 5 lts (11 seg.) y el timer3 para tiempo de espera del hopper.
#int_timer0     //T2
void timer0_RTCC()
{
time++; /// aumenta la tiempo cada .5 seg
set_timer0(3036);
clear_interrupt(int_timer0);      // limpio flag
if(time==T2)  //si la vuelta da 34, en segundos seria 17,
{
output_low(pin_c1);  //apaga electrovalvula
valvula_off2=1;
}                     
}

#int_timer1     //T1
void timer1_isr()
{
time++; /// aumenta la tiempo cada .5 seg
set_timer1(3036);
clear_interrupt(int_timer1);      // limpio flag
if(time==T1)  //si la vuelta da 74, en segundos seria 37,
{
output_low(pin_c1);  //apaga electrovalvula
valvula_off1=1;
}                     
}

#int_timer2      //T3
void timer2_isr()
{
time++; /// aumenta la tiempo cada .5 seg
set_timer2(250);
//clear_interrupt(int_timer2);      // limpio flag
if(time==T3)  //si la vuelta da 22, en segundos seria 11,
{
output_low(pin_c1);  //apaga electrovalvula
valvula_off3=1;
}                     
}

#int_timer3      //T3
void timer3_isr()
{
time++; /// aumenta la tiempo cada .5 seg
set_timer3(3036);

if(time==tiempo_espera)  //si la vuelta da 22, en segundos seria 11,
{
output_low(pin_c0);  //apaga electrovalvula
espera=1;  bandera para imprimir en el mensaje principal "monedero sin cambio"
}                     
}

configuracion de los temporizadores en la funcion principal.
void main(){
setup_timer_0(RTCC_DIV_8);    //Cargo valor de Timer 0 para medio segundo
set_timer0(3036);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);     //cargo valor del Timer 1 para medio segundo
set_timer1(3036);
setup_timer_2(T2_DIV_BY_16,254,16);    //cargo valor de Timer 2 para 4.064 mili segundo con postcaler de 16 (recordar que el timer ///2 es de 8 bits)
set_timer2(250);                        //4.064 x 250 == 1016 seg. pero 4.064 x 2751 == 11,180 seg. cada 250 es igual a 1seg.
setup_timer_3(T3_INTERNAL|T3_DIV_BY_8);     //cargo valor del Timer 3 para medio segundo Tiempo de encendido del hopper.
set_timer3(3036);
enable_interrupts(global);

}

cuando pago el garrafon pagando precio exacto funciona perfectamente ya sea 37sg garrafon lleno, 17 seg. medio garrafon o cuarto garrafon de 11seg.
pero que pasa si hay que dar cambio.
void entregar_producto3()    //TIMER 2 CON T3
{
   delay_ms(20);
   lcd_putc("\f");
   lcd_gotoxy(1,1);
   lcd_putc("LLENANDO ESPERE");
   output_low(PIN_C0);
   output_high(PIN_C1);   
   enable_interrupts(INT_TIMER2);

while(true){
if (valvula_off3==1){
   valvula_off3=0;
   delay_ms(50);
   entregar_cambio3();
   break;
}
}      entrego producto y me manda a entregar cambio 3(cuarto de garrafon) 5 lts.
}
///////////////////////////////////////////////////////////////////////////
void entregar_cambio3(){
cambio3=pesos-PR3;

 if (cambio3==0){    //producto exacto   manda directo a proceso concluido.
proceso_concluido();


}else{
if (pesos>PR3){
 output_high(pin_c0);
  enable_interrupts(int_timer3);
 
    for(;;){
    if (input(pin_a5)==1){
     delay_ms(200);
            hopper++;     
         if(cambio3==hopper) {
          disable_interrupts(int_timer3);
          espera=0;                                   ///borro bandera de no hay cambio.
          output_low(pin_c0);
          delay_ms(20);
          proceso_concluido();
         break;   
    }
 
    }
     if (espera==1){    esta bandera no la desactivo hazta que la proxima vez que se ingrese las monedas y de cambio se borrara.
          lcd_putc("\f");
          lcd_gotoxy(1,1);
          lcd_putc("DISCULP MONEDERO");
          lcd_gotoxy(3,2);
          lcd_putc("SIN CAMBIO");
          delay_ms(2500);
          proceso_concluido();
          break;

}
    }
}
}
}

en la parte de color rojo tengo el problema por que se desfasa el tiempo de llenado y el tiempo de espera del hopper. donde se activa y espera si hay cruces de monedas se desactiva el timer3, sino pues entra a la condiicon de la bandera activa (espera=1).
 uso cristal de 4M. pic 18f4550.
Nota.-  esto me lo hace en el simulador no lo he realizado en protoboard. omiti Timer0 y timer1. para no colocar todo.
espero y me puedan ayudar.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:temporizador
« Respuesta #1 en: 31 de Julio de 2018, 16:39:01 »
No se si estas pegando pedazos de codigo, pero por lo que veo el main le fatla su loop infinito. entregar_producto3 nunca se llama menos el otro pedaso de codigo, etc.

No entiendo porque te estas complicando la vida con 3 timers cuando solo necesitas 1 solo ( Timer 1 ), y que al seleccionarse la cantidad solo cargue 11,17 o 37 segundos. Y el timer mientras sea distinto de 0 este activa la salida.

Código: C
  1. #int_timer1     //T1
  2. void timer1_isr()
  3. {
  4.    clear_interrupt(int_timer1);      // limpio flag
  5.    set_timer1(3036);
  6.    if(time != 0)
  7.    {
  8.       time--;
  9.       output_high(PIN_C1);
  10.    }
  11.    else
  12.    {
  13.       output_low(PIN_C1);
  14.    }
  15. }

Y tu codigo algo mas simple como:

Código: [Seleccionar]
Si llenar 10 litros:
  si-> time += T2;
else Si llenar 20 litros:
  si-> time += T1;
else Si llenar 5 litros:
  si-> time += T0;


Como ves ni siquiera tenes que parar el timer, una ves que llego a 0 deja de salir.

Se que lo que te digo no esta ayudandote a resolver tu problema, el problema es que con lo que mostras no es posible determinarlo ya que no hay ninguna relacion entre los codigos que pones ( llamadas a funciones, etc ), pero seguramente simplifique la forma de hacer tu codigo.
« Última modificación: 31 de Julio de 2018, 16:41:45 por KILLERJC »

Desconectado Rufus

  • PIC10
  • *
  • Mensajes: 14
Re:temporizador
« Respuesta #2 en: 31 de Julio de 2018, 22:49:07 »
Gracias killer por tu respuesta. el main lo simplifique solo para que observes como declare los timers. y use 3 timers para llenado xq asi se me ocurrio para poder modificar valores en un menu de configuraciones donde modifico tiempos de llenado y precio de producto. pero acepto las sugerencias.
me dices que use un solo timer en este caso timer1 es correcto? y con el compare T1, T2 y T3?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:temporizador
« Respuesta #3 en: 31 de Julio de 2018, 23:37:04 »
Citar
me dices que use un solo timer en este caso timer1 es correcto? y con el compare T1, T2 y T3?

Exacto,, supone esto.. digamos que el Timer 1 tiene una interrupcion cada 1 segundo. Vamos a hacer un codigo simple para que puedas probar en simulacion:

Código: C
  1. volatile unsigned int time = 0;
  2.  
  3. #int_timer1
  4. void timer1_isr()
  5. {
  6.    clear_interrupt(int_timer1);      // limpio flag
  7.    set_timer1(3036);
  8.    if(time != 0)
  9.    {
  10.       time--;
  11.       output_high(PIN_C1);
  12.    }
  13.    else
  14.    {
  15.       output_low(PIN_C1);
  16.    }
  17. }
  18.  
  19. void main()
  20. {
  21.   // Configuro entradas/saildas
  22.   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);     //cargo valor del Timer 1 para medio segundo
  23.   set_timer1(3036);
  24.   enable_interrupts(int_timer1);
  25.   enable_interrupts(global);
  26.  
  27.   while
  28.   {
  29.     if ( time == 0)
  30.     {
  31.        if(PIN_A0) time = 1;
  32.        if(PIN_A1) time = 2;
  33.        if(PIN_A2) time = 3;
  34.     }
  35.   }
  36. }

Si observas el "cambiar" el tiempo es únicamente cargarle otro valor distinto a time.

Desconectado Rufus

  • PIC10
  • *
  • Mensajes: 14
Re:temporizador
« Respuesta #4 en: 01 de Agosto de 2018, 13:17:21 »
killer. buen dia.
ya lo modifique pero tengo q activar la bandera para que pueda enviarme a la siguiente funcion. sino entraria al contador al mismo tiempo me enviaria a desplegar el mensaje de gracias pro su compra y aun seguiria llenando y contando el timer.

#int_timer1        //timer principal.
void timer1_isr()
{
clear_interrupt(int_timer1);      // limpio flag
set_timer1(3036);
if(time != 0)  //si la vuelta da 74, en segundos seria 37,
{
time--;
output_high(pin_c1);  //enciende electrovalvula por que time es diferente a 0
}
else
{
output_low(pin_c1);    //cuando time1 sea igual a cero apaga electrovalvula
tiempo_carga=1;
}
}
//////////////////////////////////////////
proceso_concluido                                   //ejemplo no es el codigo rela de esta funcion.
lcd_putc("gracias por su compras"
/////////////////////////////////////////

void entregar_producto1()     //TIMER 1 CON T1
{
   time=T1;
   lcd_putc("\f");
   lcd_gotoxy(1,1);
   lcd_putc("LLENANDO ESPERE");
   enable_interrupts(INT_TIMER1);
   
   while(true){
   if(tiempo_carga==1){
   proceso_concluido();
   break;
   }
    }
}


« Última modificación: 01 de Agosto de 2018, 17:47:10 por Rufus »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:temporizador
« Respuesta #5 en: 02 de Agosto de 2018, 11:13:50 »
Mi codigo es un monstruo deforme que lo hice bastante rapido y salio eso. Seguramente tenga muchos errores y no funione correctamente, ya que tampoco lo probe. Pero te va a dar una idea mas seguramente.


Código: C
  1. ///////varibale///////
  2. int pesos;
  3. int T1=75;     //timer 20
  4. int T2=35;     //timer 10
  5. int T3=22;   //timer 5
  6.  
  7. /////banderas////////
  8. enum pasos_t {INICIO, MONTO, DESCARGA, VUELTO};
  9.  
  10. ///timer1////
  11. #int_timer1        //timer principal.
  12. void timer1_isr()
  13. {
  14.   clear_interrupt(int_timer1);        // limpio flag
  15.   set_timer1(3036);
  16.   if(time !=0)                        //si la vuelta da 74, en segundos seria 37,
  17.   {
  18.     time--;
  19.     output_high(pin_c1);              //enciende electrovalvula por que time es diferente a 0
  20.     if(time == 0) tiempo_carga = 1;   //bandera para que al termino de timer me envie a la funcion de proceso_concluido.
  21.   }
  22.   else
  23.   {
  24.     output_low(pin_c1);                 //cuando time1 sea igual a cero apaga electrovalvula
  25.   }
  26. }
  27.  
  28. ////inicio de programa//// (aqui meincorporo para restablecer mis nuevas cargas.
  29. void inicio_programa(void)
  30. {
  31.   pesos=0;   ///se guardan los pulsos de moneda
  32.   delay_ms(100);
  33.   lcd_putc("\f");
  34.   lcd_gotoxy(1,1);
  35.   lcd_putc("PLANTA AGUA ZERO");        
  36.   lcd_gotoxy(2,2);
  37.   lcd_putc("Deposite Monto");
  38. }
  39.  
  40. ///////proceso concluido//////
  41. void proceso_concluido(void)
  42. {
  43.   tiempo_carga=0;
  44.   lcd_putc("\f");
  45.   delay_ms(100);
  46.   lcd_gotoxy(4,1);
  47.   lcd_putc("LISTO...");          //imprime mensaje
  48.   lcd_gotoxy(1,2);
  49.   lcd_putc("RETIRAR ENVASE");
  50.   delay_ms(2500);
  51.   lcd_putc("\f");
  52.   delay_ms(100);
  53.   lcd_gotoxy(4,1);
  54.   lcd_putc("GRACIAS");          //imprime mensaje
  55.   lcd_gotoxy(1,2);
  56.   lcd_putc("POR SU COMPRA");
  57.   delay_ms(2500);
  58. }
  59.  
  60. void main (void)
  61. {
  62.  
  63.   enum pasos_t pasos = INICIO;
  64.   time = 0;
  65.   tiempo_carga = 0;
  66.  
  67.   set_tris_a(0xff);
  68.   set_tris_c(0x00);
  69.   set_tris_b(0xff);
  70.   output_low(PIN_C1);                         //electrovaula de llenado
  71.   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);     //cargo valor del Timer 1 para medios egundo
  72.   set_timer1(3036);
  73.   clear_interrupt(int_timer1);                // limpio flag
  74.   enable_interrupts(INT_TIMER1);
  75.   enable_interrupts(global);
  76.  
  77.   lcd_init();
  78.   lcd_gotoxy(2,1);
  79.   lcd_putc("PURIFICADORA");
  80.   lcd_gotoxy(3,2);
  81.   lcd_putc("PLANTA ZERO");
  82.   delay_ms(3000);
  83.  
  84.   while (true){
  85.     switch(pasos)
  86.     {
  87.  
  88.       case INICIO:
  89.         inicio_programa();
  90.         pasos = MONTO;
  91.         break;
  92.  
  93.       case MONTO:
  94.         if(input(PIN_B2))
  95.         {
  96.           pesos++;
  97.           lcd_putc("\f");
  98.           lcd_gotoxy(1,1);
  99.           lcd_putc("Cant. Ingresada");
  100.           lcd_gotoxy(2,2);
  101.           printf(lcd_putc,"$:%u",pesos);
  102.         }
  103.         // Se presiono algun boton seleccionando la cantidad?
  104.         if(input(PIN_A1))               //20 L
  105.         {
  106.           // Hay suficiente plata para 20L
  107.           if(pesos >= PR1)
  108.           {
  109.             time = T1;
  110.             pasos = DESCARGA;
  111.             pesos -= PR1;
  112.             lcd_gotoxy(1,1);
  113.             lcd_putc("Descargando");
  114.           }
  115.           else
  116.           {
  117.             mensaje_dinero_insuficiente();
  118.           }
  119.         } else if(input(PIN_A2))               //10 L
  120.         {
  121.           // Hay suficiente plata para 10L
  122.           if(pesos >= PR2)
  123.           {
  124.             time = T2;
  125.             pasos = DESCARGA;
  126.             pesos -= PR2;
  127.             lcd_gotoxy(1,1);
  128.             lcd_putc("Descargando");
  129.           }
  130.           else
  131.           {
  132.             mensaje_dinero_insuficiente();
  133.           }
  134.         } else if(input(PIN_A3))               //5 L
  135.         {
  136.           // Hay suficiente plata para 10L
  137.           if(pesos >= PR3)
  138.           {
  139.             time = T3;
  140.             pasos = DESCARGA;
  141.             pesos -= PR3;
  142.             lcd_gotoxy(1,1);
  143.             lcd_putc("Descargando");            
  144.           }
  145.           else
  146.           {
  147.             mensaje_dinero_insuficiente();
  148.           }
  149.           break;
  150.  
  151.       case DESCARGA:
  152.         // Necesito revisar si siguen poniendo monedas si o si
  153.         if(PIN_B2)
  154.         {
  155.           pesos++;
  156.           delay_ms(10);
  157.         }
  158.         if(tiempo_carga == 1)
  159.         {
  160.           tiempo_carga = 0;
  161.           proceso_concluido();
  162.           pasos = VUELTO;
  163.         }
  164.  
  165.       case VUELTO:
  166.         lcd_gotoxy(1,1);
  167.         lcd_putc("Su vuelto es de");
  168.         lcd_gotoxy(2,2);
  169.         printf(lcd_putc,"$:%u",pesos);
  170.         devolver_plata();
  171.         delay_ms(2000);
  172.         pasos = INICIO;
  173.         break;
  174.  
  175.       default:
  176.         pasos = INICIO;
  177.         break;
  178.     }
  179.   }
  180. }

Desconectado Rufus

  • PIC10
  • *
  • Mensajes: 14
Re:temporizador
« Respuesta #6 en: 24 de Agosto de 2018, 23:21:34 »
amigo killer, gracias y disculpe que hazta ahora te responda, el proyecto ya trabaja como me dijiste con un solo temporizador. el detalle que tengo ahorita es que no logro guardar la modificacion de los precios y tiempos de llenado.

ejemplo.-
precio 20 lts=7
precio 10 lts=5
precio 5 lts=3 pesos
tiempo de llenado 20 lts=36 seg.
tiempo de llenado 10 lts=18 seg.
tiempo de llenado 5lts=11 seg.

estos valores entran por default pero en un menu. modifico los precios y los tiempos de llenado, al momento los modifica trabajo con ellos al apagar el equipo o reiniciarlo no se guardan en la memoria eeprom externa y requiero nuevamente modificar los valores.

variables
int direccion1,direccion2,direccion3;       //direcciones para guardar en la eeprom precios.
int dir_time1,dir_time2,dir_time3;           // direcciones para guardar en la eeprom tiempo de llenaod
int PR1=7;    //precio garrafon de 20
int PR2=4;   //precio garrafon de 10
int PR3=3;   //precio garrafon de 5
int T1=36;     //tiempo de llenado en seg. de garrafon de 20 lts
int T2=18;     //tiempo para el de 10lts
int T3=11;     //tiempo para el de 5 lts.

el menu esta hecho con un switch.

void precio_20()   //funcion para modificar el precio de garrafon de 20 lts.
{
delay_ms(20);
lcd_putc("\f");
lcd_gotoxy(1,1);
printf(lcd_putc,"Precio 20 Lts.");

 while(true){     
     
      if(input(pin_a2)==1)
         {
            delay_ms(100);
            PR1++;     
         if(PR1==15)
          {
          PR1=0;
         }
           }
         
     else if (input(pin_a3)==1)
         {
            delay_ms(100);         
            PR1--;       
           if(PR1==0)   
           {
             PR1=15;         
         }
           }
           
       lcd_gotoxy(2,2);
      printf(lcd_putc,"$:%u\r",PR1);
     
      if(input(pin_a1)==1){
      write_ext_eeprom(direccion1,PR1);        //para precio de 10 uso (direccion2,PR2) y de tal forma con el de 5lts.
      lcd_putc("\f");
      lcd_gotoxy(1,1);
      printf(lcd_putc,"Guardando");
      delay_ms(500);
     break;
      }
 }
}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:temporizador
« Respuesta #7 en: 26 de Agosto de 2018, 08:57:16 »
Citar
al momento los modifica trabajo con ellos al apagar el equipo o reiniciarlo no se guardan en la memoria eeprom exte

Cual es la memoria externa?

Citar
write_ext_eeprom

No enceuntro referencia a esa funcion en el datasheet de CCS. Lo unico que encuentro es un SPI hecho por software con el mismo nombre.

Pero aca va unos pasos a verificar:

- Verificar que las salidas a la EEPROM cambien acorde y al protocolo correcto.
- Tratar de leer/escribir la EEPROM con algun otro dispositivo.

Desconectado Rufus

  • PIC10
  • *
  • Mensajes: 14
Re:temporizador
« Respuesta #8 en: 28 de Agosto de 2018, 15:02:08 »
LA MEMORIA ES LA 24LC04.
utilizo para escribir write_ext_eeprom(0,valor);
y para leer en la memoria eeprom inicializo   init_ext_eeprom();
 dentro del void main.
PR1=read_ext_eeprom(0);
PR2=read_ext_eeprom(1);
PR3=read_ext_eeprom(2);
T1=read_ext_eeprom(3);
T2=read_ext_eeprom(4);
T3=read_ext_eeprom(5);

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:temporizador
« Respuesta #9 en: 28 de Agosto de 2018, 23:54:04 »
Definiste correctamente el I2C ?

Tenes puesto las pull-ups correspondientes?

Y las pruebas son con simulador o en real ?


 

anything