Autor Tema: Problemas con interrupciones ¿Rebotes?  (Leído 3315 veces)

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

Desconectado Tholkiem

  • PIC10
  • *
  • Mensajes: 39
Problemas con interrupciones ¿Rebotes?
« en: 25 de Mayo de 2008, 13:38:09 »
Buenas tardes, el caso es que estoy trasteando con 16f876.

Se trata de un teclado matricial 4x3 que lo controlo por un unico pin, atraves del conversor A/D.  En el pinA0 y controlado por polling en el main.

Un sensor de distacias por ultrasonidos SFR04 con un pin para el envio del pulso y otro para recibir el eco el eco se recibe en la interrupcion #int_ext.

Y varios pulsadores controlados a traves de la interrupcion #int_rb.(B4-B7)
Vease parte del codigo:

Código: [Seleccionar]


 #int_RTCC
 //LO configuramos para que cada 10 ms salte este evento
void RTCC_isr(){

  char i=0;
 

     ++contRTCC;
     if(contRTCC==2){
         //Pasaron 10 ms necesarios para leventar nuestro pulso
       output_high(SRF04_PORT_TRIGGER); // Envío el pulso de disparo
       delay_us(TIME_TRIGGER_uS); // espero el ancho de pulso requerido
       output_low(SRF04_PORT_TRIGGER); // termino el pulso
       
     }
     else  if(contRTCC==5){
       contRTCC=0x00;
       printf("ooh fuera de alcanze\n");
     }
 
 
 

  //Restaura el sistema.
 
  if (flagRestore==TRUE)
  {
      contRestore++;
     
      if (contRestore==(SECONDS_TO_RESTORE*100))
      {
         printf(COMMAND_RESTORE);
         contRestore=0;
         //Encendemos luces y apagamos para que el usuario sepa que se ha restaurado a fabrica..
         for(i=0;i<NUM_LEDS_RESTORE_PARAPADEA;i++)
         {
            output_low(PIN_STATE_MICRO);
            delay_ms(150);
            output_high(PIN_STATE_MICRO);
            delay_ms(150);
         }
         flagRestore=FALSE;
      }
  }

 
   //Ajuste para 10 milis
  set_TIMER0(AJUSTE_FINO_DE_RTCC);
 

}

#INT_RB
Interrupcion_RB()
{
   delay_ms(20);     //Antirebotes
   printf("pulsado puerto b");
   #asm
         movf port_b,0//Si quitamos esta instrucción de relleno no funciona bien la interrupción
   #endasm
   
   //output_toggle(PIN_A0);
}



 
 #int_EXT
void EXT_isr()
{
  static char AntState=0;
  int distance;
  if(input(SRF04_PORT_ECHO)){   
    set_timer1(0);
   // He recibido Flanco de Subida
    ext_int_edge(0,H_TO_L);   // Configuro para capturar siguiente flanco de Bajada
  } else { 
   // He recibido Flanco de Bajada
     echo_delay=get_timer1();
         
     if (echo_delay >= MAX_ECHO_RESPONSE_Ticks)
       distance = DISTANCE_INFINITE;
     else
       distance = CALC_DISTANCE(echo_delay);

         if (distance<10)
         {
            if (AntState==3)
            {
               
               printf("ENTRADA_SEGURA\n");
               output_high(PIN_DATA_PROCESS);
               AntState=255; 
            }
            else if (AntState<3)
            {
         
               AntState++;
            }
         }
         else
         {
            output_low(PIN_DATA_PROCESS);
            AntState=0;
         }

         //Si distancia menor que XX detectada presencia :>>
         set_TIMER0(AJUSTE_FINO_DE_RTCC);
         contRTCC=0x00;
         ext_int_edge(0,L_TO_H);   // Configuro para capturar siguiente flanco de subida   

  }
 
}


void main()
{
  //inicializaciones...
    do{   
        //Chequeo por pooling..   
        testea_teclado();
    }while(TRUE==TRUE);//bucle infinito
 }

void testea_teclado(void)
{
static char TeclaAntigua=0x00;
char Tecla,TeclaChar;

    Tecla = read_adc();
       delay_ms( 50 );
         if ((Tecla) && (Tecla!=TeclaAntigua)) // si no se pulsa nada,
               // o se mantiene pulsada la misma tecla no hacemos nada
               {

                  if (Tecla<150)
                     TeclaChar='#';
                    else if (Tecla<154)
                     TeclaChar='9';
                    else if (Tecla<160)
                     TeclaChar='6';
                    else if (Tecla<165)
                     TeclaChar='3';
                    else if (Tecla<175)
                     TeclaChar='0';
                    else if (Tecla<180)
                     TeclaChar='8';
                    else if (Tecla<188)
                     TeclaChar='5';
                    else if (Tecla<195)
                     TeclaChar='2';
                    else if (Tecla<205)
                     TeclaChar='*';
                    else if (Tecla<211)
                     TeclaChar='7';
                    else if (Tecla<223)
                     TeclaChar='4';
                    else if (Tecla<233)
                     TeclaChar='1';
                   
                  if (TeclaChar=='*')
                   menu_principal(); 
                  else
                   {
                   lcd_putc("\f\fIntroduzca OFS:\n");
                   strcat(strTeclado,TeclaChar);
                   lcd_putc(strTeclado);
                   }
                   
                  printf("Valor analogico = %3u -> Tecla: %c\n\r", Tecla, TeclaChar);
               }
         TeclaAntigua=Tecla;
}


Cuando llamo en el main  a la funcion testea_teclado(). El sensor de distancias deja de responder ya que no le da tiempo a detectar el pulso de eco.  Debe ser debido a los delays que hay para evitar rebotes, si quito los delays se queda la interrupcion b saltando constantemente.

Esperando a la luz que me guie...
uN SalUdo.l



Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Problemas con interrupciones ¿Rebotes?
« Respuesta #1 en: 26 de Mayo de 2008, 08:29:29 »
Si el eco lo recibes por interrupción no entiendo porqué los retardos del teclado le afectan, en teoría no debería haber problemas, salvo que hicieras la lectura del teclado en una interrupción más prioritaria, que no es el caso.

De todas formas, puedes usar un truco para evitarlo.

En el bucle principal de tu programa incrementas constantemente una variable contador (p.e. BucleCont), si la variable llega a su tope máximo ya no se incrementa más permaneciendo con ese valor.
Cada vez que leas el teclado, compruebas si el valor de la variable ha superado un umbral mínimo, equivalente al nº de ciclos del bucle principal que tardan lo mismo que tu filtro antirrebotes. Si lo ha superado puedes leerlo y reinicias la variable a 0. Si no lo había superado no haces nada y vuelves, puesto que puede ser un rebote.

De esta manera, tu PIC en vez de estar metido en un delay, está procesando ciclos del bucle y no se debería atascar nunca.

Desconectado Tholkiem

  • PIC10
  • *
  • Mensajes: 39
Re: Problemas con interrupciones ¿Rebotes?
« Respuesta #2 en: 26 de Mayo de 2008, 13:33:51 »
Nocturno. Muchas gracias por contestar.
Es de admirar que un guru como tu, dedique parte de su tiempo en intentar arrojar luz sobre problemas de gente con mucho menos nivel de conocimientos ,como es mi caso.

Supongo que la rutina de lectura del teclado x un pin a/d. te sonara, pues si mal no recuerdo la cogi de tu page.  :-)
He probado ha hacer lo que me dijiste de la variable en lugar del delay y aun con todo el pic se queda 'un poco' loco.

Yo en esto de la programación de pic's he empezado hace muy poquito, un par de semanitas, por lo que no tengo la certeza de que el diseño de mi circuito este bien montado ya que en proteus me iba todo perfecto y cuando lo intente montar sobre una protoboard fue cuando empezaron mis quebraderos.

Aqui pongo lo que me arroja el puerto serie q lo uso a modo debug:
INICIALIZANDO..
IN_A1_11 -> EL sensor ultrasonido responde, cuando le paso la mano detecta OK (por lo tanto int_ext OK)
pulsado puerto bpulsado puerto b -> Test al puertob OK (int_rb OK)

Apartir de aqui cuando presiono cualquier tecla del teclado matricial:
(Detecta varias veces algo en el puerto b) siendo que no hay nada y luego un par de lineas mas abajo detecta la tecla pulsada OK. Despues ese ooh fuera del alcanze quiere decir que el sensor SFR04 ya no recibe el eco.. el programa queda fuera de control ya que no reponde a los pulsadores del puerto b, ni a ninguna tecla del teclado matricial.
Pero un apunte que me parece importante, cuando ya se queda fuera de control al darle a algunos pulsadores del puertob el pic hace cortocircuito. ya que me lo indica un led .¿?
Vease..
½ÁÕÉѽÿpulsado puerto bpulsado puerto bo
                                        É«canze
                                               pulsado puertopulsado puerto b®Ö
                                                                               ÕÉѽÿÍå
        Õpulsado puerto bpulsado puerto bpulsado puerto bpulsado puerto bpulsado puerto booh fuera de alcanze
                             pulsado puerto bpulsado puerto bpulsado puerto bpulsado puerto bpulsado puerto booh fuera de alcanze
                                                 pulsado puerto bpulsado puerto bValor analogico = 202 -> Teclooh fuera de alcanze
                                                  a:   0
ooh fuera de alcanze
                    ooh fuera de alcanze
                                        ooh fuera de alcanze
                                                            ooh fuera de alcanze
                                                                               ooh fuera de alcanze
etc etc etc... hasta el infinito.

Puede ser que sea cosa del conexionado, hay puertos en b que los tengo como entradas, pero no tengo nada conectado..¿¿??
Lo cierto es que me faltan bastantes conocimientos de electrónica.

Salu2.


« Última modificación: 26 de Mayo de 2008, 13:36:14 por Tholkiem »

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Problemas con interrupciones ¿Rebotes?
« Respuesta #3 en: 26 de Mayo de 2008, 14:01:20 »
De gurú, nada. Y escribir en el foro es mi deporte favorito :D

Sigue revisando conexiones y practicando. Es la mejor forma de aprender. No sabría decirte qué tienes que revisar en tu programa, pero sí te recomiendo que dividas el gran problema en muchos problemas pequeñitos, aislando y depurando cada proceso hasta llegar a engarzarlo todo para que funcione en bloque.

Suerte.

Desconectado Tholkiem

  • PIC10
  • *
  • Mensajes: 39
Re: Problemas con interrupciones ¿Rebotes?
« Respuesta #4 en: 26 de Mayo de 2008, 16:42:13 »
Bueno, aplicando el famoso divide y venceras de los romanos... ya he corregido el problema :-/
Era que lerdo de mi modifique la lib lcd.c para que usuara el puerto b.El caso que haciendo pruebas del funcionamiento de las interrupciones comente las llamadas a las rutinas que usaban el lcd para probar la int_rb, pero no me habia coscado en que me faltaba una llamada put_lcd en la funcion testea_teclado. ...   Si es que.. ya te dije que soy mas nuevo k el kas de menta .. (k esta x invertar) jejeje...

Ahora ya va todo perfecto.


Estoy pensando en usar la fuente de alimentacion que diseñaste. para alimentar un sistema compuesto entre una pcb que estoy diseñando con lcd+pic+sensores y un router inhalambrico que lo empleara para enviar datos atraves de red wifi. comunicacion serie con el pic.
Pero me da un poco de respeto emplear la fuente ya que en el articulo adviertes que se te quedo frito un usb. Servira para mi proposito dicha fuente. En principio la alimentacion seria de 220V input - 5v output 2 A. Seria suficientemente estable y podria tener la chica suficiente para alimentar todo lo que te he dicho¿?

Salu2 y muchas gracias.

« Última modificación: 26 de Mayo de 2008, 16:44:55 por Tholkiem »

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Problemas con interrupciones ¿Rebotes?
« Respuesta #5 en: 26 de Mayo de 2008, 17:38:33 »
Para 2A ni lo intentes, lo mejor es que pongas un trafo, y bien gordito.