Autor Tema: Tren de Pulsos  (Leído 2612 veces)

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

Desconectado Ruco

  • PIC12
  • **
  • Mensajes: 62
Tren de Pulsos
« en: 23 de Mayo de 2022, 23:02:04 »
Mis hermanos de este tan apreciado foro, les saludo y a la vez les pido de su ayuda en este desarrollo con Pic ccs c.

Me explico...

Tengo un tren de pulsos de un sensor, este tren varia de 1 a 8 pulsos. Dependiendo de la ocasión que se presente (indeterminada).
cada pulso tiene un tiempo de 20ms en alto y 20ms en bajo, es decir, en el caso de que se presenten los 8 pulsos serian 160ms en total del tiempo transcurrido.

Bueno, pues quiero saber cuantos de esos pulsos se presentan en 200ms, los 200ms son por que como comente antes, en el caso de que se presenten lo máximo de 8 pulsos son 160ms.

Para contar los pulsos estoy utilizando el CCP1 del Pic18F de esta manera:

 
Código: C++
  1. #int_ccp1
  2.          void trata_pulsos(void)
  3.          {    
  4.          pulsos++;        
  5.          }

Y para contar los 200ms estoy incrementando el timer0 cada 1 ms asi:
Código: C++
  1. #int_TIMER0              
  2.          void tiempo_200ms(void)      
  3.          {  
  4.          aux++;                  // incrementa cada 1 ms
  5.  
  6.          if(aux==200){                                               // Si pasaron los 200ms actúo.
  7.          }
  8.          set_timer0 (65223);     // para 1 ms
  9.          }


Este es el código que tengo hasta ahora...


Código: C++
  1. int16 pulsos;
  2.          int16 aux;
  3.          
  4.          #int_ccp1
  5.          void trata_pulsos(void)
  6.          {    
  7.          pulsos++;        
  8.          }
  9.                  
  10.          #int_TIMER0              
  11.          void tiempo_200ms(void)      
  12.          {  
  13.          aux++;
  14.          output_toggle(pin_c0);
  15.          if(aux==200){disable_interrupts(INT_TIMER0); disable_interrupts(INT_CCP1);  }
  16.          set_timer0 (65223);    
  17.          }
  18.          
  19.          void main()
  20.          {
  21.          porta=0x00; set_tris_a(0b00000001); portb=0x00; set_tris_b(0b11111111); portc=0x00; set_tris_c(0b10000000); portd=0x00; set_tris_d(0b00000100); porte=0x00; set_tris_e(0b00001000);
  22.          lcd_init();                      
  23.          setup_ccp1(CCP_CAPTURE_RE);  
  24.          enable_interrupts(INT_CCP1);
  25.          setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);  
  26.          disable_interrupts(INT_TIMER0);  
  27.          set_timer0 (65223);  
  28.          enable_interrupts(global);                                                    
  29.    
  30.          while(true)                                  
  31.          {      
  32.          lcd_gotoxy(1,2); printf(lcd_putc,"pulsos = %lu %lu",pulsos,aux);
  33.        
  34.          }
  35.          }

Lo que no se, es como hacer lo comentado... Que a partir de que el ccp1 encuentre un o unos de los pulsos el timer0 empiece a contar el tiempo y a partir de que se concluyan los 200ms deje de contar y me diga cuantos pulsos entraron en ese tiempo.

Espero haberme dado a entender y con ello me puedan ayudar, quizás alguien tenga otra idea para resolver esto.

Coloco una imagen para darme a entender mejor. Saludos a todos mis hermanos.





« Última modificación: 23 de Mayo de 2022, 23:33:42 por Ruco »

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:Tren de Pulsos
« Respuesta #1 en: 24 de Mayo de 2022, 02:37:43 »
Se me ocurren varias formas  Una de ellas es usando dos timer,

 Uno de ellos (timer0, por ejemplo) para contar los pulsos, incrementado por señal externa, 8 bits es suficiente y configurado para incrementarse en el flanco de subida (según el timming de la imagen que has puesto).  Le asignas un valor inicial de 0xff (255) si es de 8 bits, con la idea de que desborde en cuanto se reciba el primer flanco de subida desde el sensor.

  El otro timer (timer3 por ejemplo) lo conectaría al oscilador y le calcularía el prescaler/postcaler así como el valor inicial necesario para que tarde 320 ms en desbordar.  (Te da igual si tarda algo más o menos por que el sensor tiene un periodo total de 320 ms y te interesa contar todos los pulsos en esos 320 ms.

Entonces el programa funciona así:

    - El sensor envía el primer flanco.  Desborda el timer 0 por que estaba fijado en 0xff
    - entras en la interrupción por desbordamiento del timer 0 y ahí lo que haces es activar otra interrupción , esta vez por desbordamiento del timer3 y fijar al timer3 el valor arriba calculado para que desborde en 320 ms.

    - cuando desborde el timer3 entras a la interrupción por timer3 y aquí lees el timer0
   
    Ya tienes el número de pulsos que ha enviado el sensor en esos 320 ms.  (Tienes que sumarle 1, que es el que incrementó de 255 a 0 y provocó la primera interrupción.

     Vuelves a ponerlo a 0xff y siguiente ciclo.
    Desactivas la interrupción del timer3.
    Vuelta a empezar.

  De mientras, tu programa corre.

  Un saludo.


 
« Última modificación: 24 de Mayo de 2022, 03:12:17 por remi04 »

Desconectado Fer_TACA

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4069
Re:Tren de Pulsos
« Respuesta #2 en: 24 de Mayo de 2022, 02:53:42 »
Si son 8 pulsos que duran 20msg en alto y 20 msg en bajo.
¿El total de la duración de los 8 pulsos, no serían 320msg?

F.
Todos los días se aprende algo nuevo.

Desconectado Ruco

  • PIC12
  • **
  • Mensajes: 62
Re:Tren de Pulsos
« Respuesta #3 en: 24 de Mayo de 2022, 07:06:36 »
Remi04 y FER_TACA. Efectivamente, son 320 ms. Estaba mas dormido que despierto.  ;-)
Efectivamente son para el caso que toque los 8 pulsos 8 x20ms=160 en alto y 160 en bajo. Pero también como comente, estos pulsos son impredecibles como puede ser uno solo, o cinco, o tres, u ocho.

Gracias por las sugerencias, falta ponerlo en código y ver resultados...

Yo había puesto

Código: C++
  1. #int_ccp1
  2.          void trata_pulsos(void)
  3.          {    
  4.          pulsos++;        
  5.          }

Por que así con ccp1 cuento cada pulso y el timer0 ahora lo dejaría a 350 ms. Por que apartir de ese tiempo estaría seguro de que pasaría un máximo de pulsos (para el caso de los 8 pulsos).

« Última modificación: 24 de Mayo de 2022, 07:30:37 por Ruco »

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1937
    • Sicoy
Re:Tren de Pulsos
« Respuesta #4 en: 24 de Mayo de 2022, 10:51:19 »
Mis hermanos de este tan apreciado foro, les saludo y a la vez les pido de su ayuda en este desarrollo con Pic ccs c.

Me explico...

Tengo un tren de pulsos de un sensor, este tren varia de 1 a 8 pulsos. Dependiendo de la ocasión que se presente (indeterminada).
cada pulso tiene un tiempo de 20ms en alto y 20ms en bajo, es decir, en el caso de que se presenten los 8 pulsos serian 160ms en total del tiempo transcurrido.

Bueno, pues quiero saber cuantos de esos pulsos se presentan en 200ms, los 200ms son por que como comente antes, en el caso de que se presenten lo máximo de 8 pulsos son 160ms.

Para contar los pulsos estoy utilizando el CCP1 del Pic18F de esta manera:

 
Código: C++
  1. #int_ccp1
  2.          void trata_pulsos(void)
  3.          {    
  4.          pulsos++;        
  5.          }

Y para contar los 200ms estoy incrementando el timer0 cada 1 ms asi:
Código: C++
  1. #int_TIMER0              
  2.          void tiempo_200ms(void)      
  3.          {  
  4.          aux++;                  // incrementa cada 1 ms
  5.  
  6.          if(aux==200){                                               // Si pasaron los 200ms actúo.
  7.          }
  8.          set_timer0 (65223);     // para 1 ms
  9.          }


Este es el código que tengo hasta ahora...


Código: C++
  1. int16 pulsos;
  2.          int16 aux;
  3.          
  4.          #int_ccp1
  5.          void trata_pulsos(void)
  6.          {    
  7.          pulsos++;        
  8.          }
  9.                  
  10.          #int_TIMER0              
  11.          void tiempo_200ms(void)      
  12.          {  
  13.          aux++;
  14.          output_toggle(pin_c0);
  15.          if(aux==200){disable_interrupts(INT_TIMER0); disable_interrupts(INT_CCP1);  }
  16.          set_timer0 (65223);    
  17.          }
  18.          
  19.          void main()
  20.          {
  21.          porta=0x00; set_tris_a(0b00000001); portb=0x00; set_tris_b(0b11111111); portc=0x00; set_tris_c(0b10000000); portd=0x00; set_tris_d(0b00000100); porte=0x00; set_tris_e(0b00001000);
  22.          lcd_init();                      
  23.          setup_ccp1(CCP_CAPTURE_RE);  
  24.          enable_interrupts(INT_CCP1);
  25.          setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);  
  26.          disable_interrupts(INT_TIMER0);  
  27.          set_timer0 (65223);  
  28.          enable_interrupts(global);                                                    
  29.    
  30.          while(true)                                  
  31.          {      
  32.          lcd_gotoxy(1,2); printf(lcd_putc,"pulsos = %lu %lu",pulsos,aux);
  33.        
  34.          }
  35.          }

Lo que no se, es como hacer lo comentado... Que a partir de que el ccp1 encuentre un o unos de los pulsos el timer0 empiece a contar el tiempo y a partir de que se concluyan los 200ms deje de contar y me diga cuantos pulsos entraron en ese tiempo.

Espero haberme dado a entender y con ello me puedan ayudar, quizás alguien tenga otra idea para resolver esto.

Coloco una imagen para darme a entender mejor. Saludos a todos mis hermanos.

Tengo una pregunta y un sugerencia.

Pregunta:

¿Bajo alguna circunstancia la fuente emite los pulsos emite una cantidad de x de pulsos y luego entra a reposo, o siempre está emitiendo los pulsos y no sabes cuando inició y tampoco sabes cuando va a finalizar?

Sugerencia

Respecto a una interrupción para contar cada uno de los pulsos, digamos que es funcional, pero es mejor utilizar un temporizador. Un temporizador cuenta los pulsos del oscilador externo (cristal) o interno del microcontrolador. Pero también puedes definir como fuente de sus pulsos un terminal o pin externo.

¿Qué ventajas tiene hacer esto?

Si usas una interrupción por cada pulso generado, el CPU tiene que atender la interrupción para incrementar una variable y luego retornar a lo que estaba haciendo, lo que
implica un aumento de la latencia de todo el proceso.

Con un temporizador usado como contador, no tienes que atender ninguna interrupción, los registros de dicho temporizador te indican cuantos pulsos han sido contados.

Sólo es una sugerencia, si tu sistema no maneja muchos procesos, con el método que estás usando puede ser suficiente.
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado Ruco

  • PIC12
  • **
  • Mensajes: 62
Re:Tren de Pulsos
« Respuesta #5 en: 24 de Mayo de 2022, 11:14:49 »
DominusDRR

Efectivamente, emite pulsos, entra en reposo otro corto tiempo (supongamos un segundo) y después vuelve enviar pulsos.

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1937
    • Sicoy
Re:Tren de Pulsos
« Respuesta #6 en: 24 de Mayo de 2022, 11:37:57 »
DominusDRR

Efectivamente, emite pulsos, entra en reposo otro corto tiempo (supongamos un segundo) y después vuelve enviar pulsos.

¿Y tienes posibilidad de detectar con el microcontrolador cuando empieza emitir y cuando finaliza los pulsos?

EL inicio de los pulsos se podría detectar con una interrupción por flanco del primer pulso. En ese instante deberías activar un temporizador (otro si utilizas lo que mencioné de un temporizador como contador).

El temporizador máximo debería desbordarse en un poco más de 320ms que sería lo máximo que podrías contar con 8 pulsos.

Sería algo así mas o menos:

Código: C
  1. #int_ccp1
  2. void trata_pulsos(void)
  3. {    
  4.       /*Pongo en cero al temporizador e inicio para que cuente hasta 320 ms*/ // cada vez que llega un pulso [b]resetea[/b] al timer
  5.       bandera = true;
  6.       pulsos++;        
  7. }
  8.  
  9. void main (void)
  10. {
  11.     pulsos = 0;
  12.     bandera = false
  13.    /*** configuraciones iniciales ***/
  14.    while(true) // lazo principal
  15.    {
  16.       if (bandera)
  17.      {
  18.        
  19.          if (¿temporizador se ha desbordado? || 8 == pulsos)
  20.         {
  21.              /*Desactivo temporizador, también se podría deshabilitar la interrupción*/
  22.              lcd_gotoxy(1,2); printf(lcd_putc,"pulsos = %lu %lu",pulsos,aux);
  23.             /*Reinicio todas las variables para repetir el proceso*/
  24.         }
  25.      }
  26.    }
  27. }
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado Ruco

  • PIC12
  • **
  • Mensajes: 62
Re:Tren de Pulsos
« Respuesta #7 en: 24 de Mayo de 2022, 17:29:41 »
Gracias. Ahora me intento al código y comento. La idea que dices es algo como lo pensaba.

Saludos sr. DominusDRR

Desconectado Ruco

  • PIC12
  • **
  • Mensajes: 62
Re:Tren de Pulsos
« Respuesta #8 en: 24 de Mayo de 2022, 22:24:04 »

Ahí va tomando forma...  :mrgreen:
Con el mismo pic estoy generando un tren de pulsos cada 20uS. y si esta capturando de manera correcta, ahora solo falta el retesar el contador para cuando llegue un nuevo pulso.

Alguna sugerencia?... O quizás se les ocurra otra manera de lograr lo planteado....

Código: C++
  1. int pulsos;
  2.          int16 aux;
  3.          
  4.          #int_ccp1
  5.          void trata_pulsos(void)
  6.          {    
  7.          enable_interrupts(INT_TIMER0);
  8.          pulsos++;        
  9.          }
  10.                  
  11.          #int_TIMER0              
  12.          void tiempo_1ms(void)      
  13.          {  
  14.          aux++;
  15.          output_toggle(pin_c0);
  16.          if(aux==320){disable_interrupts(INT_TIMER0); disable_interrupts(INT_CCP1);  }
  17.          set_timer0 (65223);    
  18.          }
  19.          
  20.          void main()
  21.          {
  22.          porta=0x00; set_tris_a(0b00000001); portb=0x00; set_tris_b(0b11111111); portc=0x00; set_tris_c(0b10000000); portd=0x00; set_tris_d(0b00000100); porte=0x00; set_tris_e(0b00001000);
  23.          lcd_init();                      
  24.          setup_ccp1(CCP_CAPTURE_RE);  
  25.          enable_interrupts(INT_CCP1);
  26.          setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);  
  27.          disable_interrupts(INT_TIMER0);  
  28.          set_timer0 (65223);  
  29.          enable_interrupts(global);                                                    
  30.    
  31.          while(true)                                  
  32.          {      
  33.          lcd_gotoxy(1,2); printf(lcd_putc,"Pulsos = %i ",pulsos);
  34.          lcd_gotoxy(1,3); printf(lcd_putc,"Tiempo = %lu ms",aux);
  35.          
  36.          if(!input(pin_b4)){
  37.          output_high(pin_b0); delay_ms(20);
  38.          output_low(pin_b0); delay_ms(20);
  39.          }        
  40.          }
  41.          }

Desconectado Ruco

  • PIC12
  • **
  • Mensajes: 62
Re:Tren de Pulsos
« Respuesta #9 en: 27 de Mayo de 2022, 01:27:05 »
Amigos. Alguna manera de resetear el contador y timer para estar preparado y esperar sl siguiente tren de pulsos....

Gracias.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Tren de Pulsos
« Respuesta #10 en: 27 de Mayo de 2022, 19:31:34 »
Al momento de dejar de contar:

Código: C
  1. if(aux==320){disable_interrupts(INT_TIMER0); disable_interrupts(INT_CCP1);  }

Tambien podrias guardar los "pulsos" en otra variable, y reciniciar los pulsos


Código: C
  1. if(aux==320){
  2.         disable_interrupts(INT_TIMER0);
  3.         disable_interrupts(INT_CCP1);
  4.         pulsosguardados= pulsos;
  5.         pulsos = 0;
  6. }

El mayor problema es que estas actualizando el LCD siempre... no importa para nada ver los pulsos a la mitad del tiempo, como si fueras a discernir entre milisegundos... entonces lo mejor es que una ves que termine de contar... proceder a mostrar

Código: C
  1. if(aux==320){
  2.         disable_interrupts(INT_TIMER0);
  3.         disable_interrupts(INT_CCP1);
  4.         pulsosguardados = pulsos;
  5.         pulsos = 0;
  6.         mostrar = 1;
  7. }

Código: C
  1. while(true)                                  
  2.          {      
  3.          if (mostrar) {
  4.                 lcd_gotoxy(1,2); printf(lcd_putc,"Pulsos = %i ",pulsos);
  5.                 //lcd_gotoxy(1,3); printf(lcd_putc,"Tiempo = %lu ms",aux);  // Esta linea no tendria sentido...
  6.                mostrar = 0;
  7.                //Acá activo las interrupciones para que cuente de nuevo.
  8.         }
  9.          
  10.          if(!input(pin_b4)){
  11.          output_high(pin_b0); delay_ms(20);
  12.          output_low(pin_b0); delay_ms(20);
  13.          }

Obviamente el codigo puede tener errores, no me puse a reformular todo el codigo, solo apenas para que "resetee" el contador,

Desconectado Ruco

  • PIC12
  • **
  • Mensajes: 62
Re:Tren de Pulsos
« Respuesta #11 en: 28 de Mayo de 2022, 10:09:23 »
KILLERJC

E colocado las variable dichas en el código pulsosguardados como indico usted y e adicionado otras lineas para que me muestre 4 pulsos (por que le coloque un retardo de 40ms)...

Código: C++
  1. if(!input(pin_b5)){
  2.          output_high(pin_b0); delay_ms(40);
  3.          output_low(pin_b0); delay_ms(40);
  4.          }

Bien pues si presiono el pin_b5, efectivamente me muestra los 4 pulsos en pantalla y si ahora presiono pin_b4 me sigue sin actualizar, es decir, solo se visualiza el pin que se presione primero sin actualizar el pulsos.

Código: C++
  1. int pulsos,pulsosguardados;
  2.          int16 aux;
  3.          int1 mostrar;
  4.          
  5.          #int_ccp1
  6.          void trata_pulsos(void)
  7.          {    
  8.          enable_interrupts(INT_TIMER0);
  9.          pulsos++;        
  10.          }
  11.                  
  12.          #int_TIMER0              
  13.          void tiempo_1ms(void)      
  14.          {  
  15.          aux++;
  16.          output_toggle(pin_c0);
  17.          if(aux==320){
  18.          disable_interrupts(INT_TIMER0);
  19.          disable_interrupts(INT_CCP1);  
  20.          pulsosguardados=pulsos;
  21.          pulsos=0;
  22.          mostrar=1;
  23.          }
  24.          set_timer0 (65223);    
  25.          }
  26.          
  27.          void main()
  28.          {
  29.          porta=0x00; set_tris_a(0b00000001); portb=0x00; set_tris_b(0b11111111); portc=0x00; set_tris_c(0b10000000); portd=0x00; set_tris_d(0b00000100); porte=0x00; set_tris_e(0b00001000);
  30.          lcd_init();                      
  31.          setup_ccp1(CCP_CAPTURE_RE);  
  32.          enable_interrupts(INT_CCP1);
  33.          setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);  
  34.          disable_interrupts(INT_TIMER0);  
  35.          set_timer0 (65223);  
  36.          enable_interrupts(global);                                                    
  37.    
  38.          while(true)                                  
  39.          {      
  40.          if(mostrar)
  41.          {
  42.          lcd_gotoxy(1,2); printf(lcd_putc,"Pulsos = %i ",pulsosguardados);
  43.         // lcd_gotoxy(1,3); printf(lcd_putc,"Tiempo = %lu ms",aux);
  44.          mostrar=0;
  45.          enable_interrupts(INT_TIMER0);
  46.          enable_interrupts(INT_CCP1);
  47.          }
  48.          if(!input(pin_b4)){
  49.          output_high(pin_b0); delay_ms(20);
  50.          output_low(pin_b0); delay_ms(20);
  51.          }        
  52.  
  53.          if(!input(pin_b5)){
  54.          output_high(pin_b0); delay_ms(40);
  55.          output_low(pin_b0); delay_ms(40);
  56.          }  
  57.  
  58.          }
  59.          }

Saludos. Espero me puedan ayudar

Desconectado Ruco

  • PIC12
  • **
  • Mensajes: 62
Re:Tren de Pulsos
« Respuesta #12 en: 28 de Mayo de 2022, 15:29:50 »
Creo que también falta mandar a 0 la variable auxiliar.

 aux=0;

Desconectado Ruco

  • PIC12
  • **
  • Mensajes: 62
Re:Tren de Pulsos
« Respuesta #13 en: 29 de Mayo de 2022, 11:04:59 »
Un duda más.. e visto que en algunos diagramas al pic, en especifico cuando se trabaja con e modulo ccp, se le pone una resistencia de 10k o 4.7k en paralalo a la entrada ccp y gnd.  Esto que sentido tiene?.

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1937
    • Sicoy
Re:Tren de Pulsos
« Respuesta #14 en: 29 de Mayo de 2022, 12:58:38 »
Un duda más.. e visto que en algunos diagramas al pic, en especifico cuando se trabaja con e modulo ccp, se le pone una resistencia de 10k o 4.7k en paralalo a la entrada ccp y gnd.  Esto que sentido tiene?.

Es una forma de eliminar ruido que podría generar pulsos "falsos", en un ambiente industrial es preferible usar un amplificador diferencial más un filtro pasabanda para eliminar ruido no deseado.
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32


 

anything