Autor Tema: :: pardadeo :: LED ::  (Leído 2171 veces)

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

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
:: pardadeo :: LED ::
« en: 30 de Junio de 2012, 16:50:57 »
Hola

Estoy intentando crear un codigo,
para hacer parpadear de forma simultanea varios led
pero con la diferencia de que cada uno de ellos
lo haga con tiempos diferentes y exactos.

como es posible?

Código: C++
  1. //para los led
  2.  
  3. #DEFINE LED1 PIN_C0
  4. #DEFINE LED2 PIN_C1
  5. #DEFINE LED3 PIN_C2
  6. #DEFINE LED4 PIN_C3
  7.  
  8.  
  9. //para retardos
  10.  
  11. #DEFINE T_ALTO              
  12. #DEFINE T_BAJO
  13.  
  14. int8 a=0
  15.  
  16. while(a=0){
  17. ....
  18.  
  19. aca viene la movida
  20.  
  21. }

como hago para que los retardos de los propios led no retarden al conjunto.

paso uno:

parpadean los cuatro:


paso dos:

les pongo un retardo representativo y que se vea a simple vista:

led1 2x tiempo de led2
led2 2x tiempo de led3
led3 2x tiempo de led4


paso tres :  cuantas veces le pongo par que se vean:

4 veces sera suficiente

ufff...
como hago esto...?





Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: :: pardadeo :: LED ::
« Respuesta #1 en: 30 de Junio de 2012, 17:50:33 »
  Una forma sería basarse en delays, pero en el delay del Led que menos período tenga. Luego, para el led siguiente podrías tener un contador que cuente cuantas veces parpadeo el primer led y, por ejemplo, cada tres parpadeos del primer led, el segundo cambia de estado.

  Con tu ejemplo creo que sería incluso un poco más fácil porque cada led tiene el doble de tiempo del led anterior.

  Te dejo un ejemplo malo, pero funcional... no es código sino pseudocódigo

Código: C
  1. led 1 On
  2. delay 5ms
  3. led1 off
  4. delay5 ms
  5. led 1 on
  6. delay 5 ms
  7. led 1 off
  8. delay 5 ms
  9.  
  10. led 1 y 2 on
  11. delay 5ms
  12. led1 off
  13. delay5 ms
  14. led 1 on
  15. delay 5 ms
  16. led 1 off
  17. delay 5 ms
  18. led 1 y 2 off
  19. delay 5 ms

  Creo que lo ideal sería recurrir al uso a algún Timer para el menor tiempo. Dentro de la interrupción del mismo activas algún flag para indicar que cambio el tiempo mínimo y a su vez incrementas distintos contadores (un contador para cada uno de los otros leds). Según el estado de los contadores activas los flags de los distintos leds. En el ciclo principal del programa podés ir evaluando dichos flags y según su estado encendes o no los leds.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: :: pardadeo :: LED ::
« Respuesta #2 en: 30 de Junio de 2012, 19:47:26 »
Cuando necesitas bases de tiempo diferentes, como en este caso, deberas acudir a uno de los timer por interrupcion, ya que permite usar muchas bases de tiempo a la vez.

Por ejemplo, preparas una interrupcion para que ocurra cada 1 milisegundo.
Dentro de la interrupcion, cada vez que ocurre la misma, tu codigo puede llevar una cuenta en milisegundos, otra cada 10 milisegundos, otra cada 100 milisegundos y otra cada 1 segundo.

Entonces fuera de la interrupcion lo que deberias hacer es mas o menos asi:
(en seudocodigo)

Código: C
  1. Si el valor de MiTimer_en_mseg es mayor a 100
  2.                            entonces enciendo led1, reseteo MiTimer_en_mseg.
  3.  
  4. Si el valor de Mitimer_en_mseg es mayor a 200
  5.                           entonces apago led1, reseteo MiTimer_en_mseg.

Y dentro de la interrupcion, cada vez que ocurre, incrementas en 1 el valor de Mitimer_en_mseg.

Si quieres una base de tiempo de 100 mseg, cada vez que ocurre la interrupcion, incrementas una cuenta auxiliar, y cuando esta llega a 100, incrementas la variable MiTimer_de_100mseg y pones la variable auxiliar en cero.
 :mrgreen:

Esta forma de hacer las cosas permite que tus programas no se detengan a esperar que ocurra alguna temporizacion, y solo sucedan los cambios cuando deben ocurrir.
El micro temporiza para ti.  :mrgreen: :mrgreen:

No te olvides que las instrucciones delay_ms, delay_us, son solo bucles donde se consume el tiempo sin hacer otra cosa, si tu programa debe atender otras tareas, es mejor no utilizarlas.
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: :: pardadeo :: LED ::
« Respuesta #3 en: 01 de Julio de 2012, 06:47:05 »
Hola
La idea era esa,
que los led esperen pero el micro no,
que cuando hayan pasado los milisegundos concretos el led se encienda por interrupcion y cuando
hayan pasado los suyos de encendido otra INT lo apague.


De esta forma es el led el que espera, no el micro.


Anoche dandole vueltas, a la idea recuerdo que Redpic, tenia por ahi algo
pero no logro dar con el enlace.

Creo que era un timer de interrupcion por software creado mediante variables.

No doy con el dichoso enlace..

si alguno de ustedes sabe de lo que hablo..y conoce el enlace
le agradecedria con sumo gusto que lo agregase ya que a mi se esconde...

sigo buscado..


Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: :: pardadeo :: LED ::
« Respuesta #4 en: 01 de Julio de 2012, 09:57:40 »
  ¿Y si lo buscas en el sitio de RedPic?
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: :: pardadeo :: LED ::
« Respuesta #5 en: 01 de Julio de 2012, 12:36:02 »
 ¿Y si lo buscas en el sitio de RedPic?

Si esa fue una de las fracasadas busquedas que obtuve
ya que la referencia que yo tenia, era un recuerdo de un articulo que yo lei en este foro
recordaba como era pero no con el titulo adecuado, y por google tampoco lo encontraba

hasta hace poco rato que di con el cuando escribi interrupcion:

Múltiples lapsus largos de tiempo con una sola interrupción.

http://www.todopic.com.ar/foros/index.php?topic=24801.0


vamos con el codigo...

Ojeando de nuevo el pos  entre lineas dice algo de 0.2u seg pero no especifica si es internal o external.

¿eso se refiere al cristal ?

lo pregunto porque en el asistenete me da la opcion de disable, internal o external

¿alguien me puede informar mas ...?


sigo con el data y el codigo


« Última modificación: 02 de Julio de 2012, 09:27:32 por pajaro »

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: :: pardadeo :: LED ::
« Respuesta #6 en: 02 de Julio de 2012, 09:13:57 »
Hola

En el simulador de proteus estoy simulando
un programa sencillo, mediante interrupcion y timer 1
si pulso la entrada se pone a uno y se enciende un led  y el timer empieza a
contar  pasado ese tiempo se apaga el led.

muestro el codigo:

Código: C++
  1. /************************************************
  2. *
  3. * main.c
  4. *
  5. *************************************************/
  6. #include "main.h"
  7.  
  8. // Constantes
  9. const int8 nTimer1_for_1_second=76;
  10.  
  11. // Variables en RAM
  12. int8 nTimer1Overflow; // Contador de Interrupciones
  13. int8 nSECS_for_Event_1; // Contador Segundos para Evento 1
  14. int1 flag_for_Event_1; // Flag para detectar evento 1
  15.  
  16. int8 nTOFS_for_Event_2; // Contador Interrupciones para Evento 2
  17. int1 flag_for_Event_2; // Flag para detectar evento 2
  18.  
  19. #int_TIMER1
  20. void  TIMER1_isr(void)
  21. {
  22.   ////////////////////////////////////////////////////////////////////////////////////////////////
  23.   // Cómputo de segundos completos (13,1072 milisegundos * _nTimer1_for_1_second = 996,1472 milisegundos)
  24.   // Todo lo que se controla dentro de este bloque sólo se computa por segundos completos.
  25.   ////////////////////////////////////////////////////////////////////////////////////////////////
  26.   if(++nTimer1Overflow==nTimer1_for_1_second){
  27.  
  28.      // Control de Evento Número 1
  29.      if(nSECS_for_Event_1!=0){ // si hay algo que contar ...
  30.         if(--nSECS_for_Event_1==0){ // Descuento un segundo y si he terminado ...
  31.           flag_for_Event_1=1; // Activo el flag de notificación del Evento 1.
  32.         }
  33.      }
  34.      // Restauro contador de interrupciones para cómputo de segundos completos
  35.      nTimer1Overflow=0;
  36.   }
  37.   ////////////////////////////////////////////////////////////////////////////////////////////////
  38.   // Cómputo de periodos de tiempo individualizados en NTOFS.
  39.   // Dentro de este bloque se computan periodos de n x 13,1072 ms.
  40.   ////////////////////////////////////////////////////////////////////////////////////////////////
  41.  
  42.   // Control de Evento Número 2
  43.   if(nTOFS_for_Event_2!=0){
  44.      if(--nTOFS_for_Event_2==0){
  45.         flag_for_Event_2=1;
  46.      }
  47.   }
  48.  
  49. }
  50.  
  51.  
  52. void main()
  53. {
  54.  
  55.    setup_adc_ports(NO_ANALOGS|VSS_VDD);
  56.    setup_adc(ADC_CLOCK_DIV_2);
  57.    setup_wdt(WDT_OFF);
  58.    setup_timer_0(RTCC_INTERNAL);
  59.    //setup_timer_1(T1_DISABLED);
  60.    setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
  61.    setup_timer_2(T2_DISABLED,0,1);
  62.    setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
  63.    setup_comparator(NC_NC_NC_NC);
  64.    setup_vref(FALSE);
  65.    
  66.  
  67. //Setup_Oscillator parameter not selected from Intr Oscillator Config tab
  68.  
  69.    // TODO: USER CODE!!
  70.    
  71.   set_tris_b(0x02);
  72.   set_tris_c(0x00);
  73. // Pongo a cero todas las variables
  74.   nTimer1Overflow=0;
  75.   nSECS_for_Event_1=0;
  76.   flag_for_Event_1=0;
  77.   // Habilito las interrupciones
  78.    enable_interrupts(INT_TIMER1);
  79.    enable_interrupts(GLOBAL);
  80.  
  81.   output_low(PIN_B7);
  82.  
  83. // Bucle infinito ...
  84.   do{
  85.  
  86.      /////////////////////////////////////////////////////////////////////////////////////////////
  87.      // Detecto la pulsación del botón (con antirrebote incluido) y pongo en marcha
  88.      // el led y el Disparador de eventos
  89.      /////////////////////////////////////////////////////////////////////////////////////////////
  90.      if(input(PIN_C1)){ // Si pulso el botón ...
  91.         delay_ms(125);
  92.         if(input(PIN_C1)){ // Si 125 ms después sigue pulsado el botón ...
  93.            delay_ms(125);
  94.            if(input(PIN_C1)){ // Si 250 ms después sigue pulsado el botón ...
  95.               output_high(PIN_B7); // Activo lo que deseo activar, o sea mi led
  96.               flag_for_Event_1=0; // Pongo a cero el flag (por si acaso)
  97.               nSECS_for_Event_1=3; // Cargo los segundos que deseo esperar
  98.            }
  99.         }
  100.      }
  101.  
  102.      /////////////////////////////////////////////////////////////////////////////////////////////
  103.      // Detecta fin del lapsus del Evento 1 y
  104.      // desactivo el relé
  105.      /////////////////////////////////////////////////////////////////////////////////////////////
  106.      if(flag_for_Event_1==1){ // Si ha transcurrido el lapsus ...
  107.         flag_for_Event_1 =0; // Desactivo la notificación que he recibido
  108.         output_low(PIN_B7); // y actúo en consecuencia, desactivo el led.
  109.      }
  110.  
  111.   }while(true);
  112.  
  113.  
  114. }


Código: C++
  1. /************************************************
  2. *
  3. * main.h
  4. *
  5. *************************************************/
  6.  
  7. #include <18F2550.h>
  8. #device adc=8
  9.  
  10. #FUSES NOWDT                    //No Watch Dog Timer
  11. #FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
  12. #FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
  13. #FUSES NOPROTECT                //Code not protected from reading
  14. #FUSES NOBROWNOUT               //No brownout reset
  15. #FUSES BORV20                   //Brownout reset at 2.0V
  16. #FUSES NOPUT                    //No Power Up Timer
  17. #FUSES NOCPD                    //No EE protection
  18. #FUSES STVREN                   //Stack full/underflow will cause reset
  19. #FUSES NODEBUG                  //No Debug mode for ICD
  20. #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  21. #FUSES NOWRT                    //Program memory not write protected
  22. #FUSES NOWRTD                   //Data EEPROM not write protected
  23. #FUSES IESO                     //Internal External Switch Over mode enabled
  24. #FUSES FCMEN                    //Fail-safe clock monitor enabled
  25. #FUSES NOPBADEN                 //PORTB pins are configured as digital I/O on RESET
  26. #FUSES NOWRTC                   //configuration not registers write protected
  27. #FUSES NOWRTB                   //Boot block not write protected
  28. #FUSES NOEBTR                   //Memory not protected from table reads
  29. #FUSES NOEBTRB                  //Boot block not protected from table reads
  30. #FUSES NOCPB                    //No Boot Block code protection
  31. #FUSES MCLR                     //Master Clear pin enabled
  32. #FUSES LPT1OSC                  //Timer1 configured for low-power operation
  33. #FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
  34. #FUSES PLL12                    //Divide By 12(48MHz oscillator input)
  35. #FUSES CPUDIV4                  //System Clock by 4
  36. #FUSES USBDIV                   //USB clock source comes from PLL divide by 2
  37. #FUSES VREGEN                   //USB voltage regulator enabled
  38.  
  39. #use delay(clock=20000000)
  40. #define I2C_SDA   PIN_B0
  41. #define I2C_SCL   PIN_B1
  42.  
  43. #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
  44. #use i2c(Master,Slow,sda=PIN_B0,scl=PIN_B1,force_hw)
  45.  
  46. //#include "milib.c"

Pero no se apaga el led.

en el depurado parece como si el timer no contar porque nunca entra, parece apagado

necesito mas ojos , ven algun error..


sigo investigando con el codigo..



Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: :: pardadeo :: LED ::
« Respuesta #7 en: 02 de Julio de 2012, 09:39:10 »
  Veo que lo tenés configurado como external, para ello debe ingresar la señal de clock para el timer por un pin del pic... prueba de configurarlo como interno a ver que pasa.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: :: pardadeo :: LED ::
« Respuesta #8 en: 02 de Julio de 2012, 11:45:02 »
  Veo que lo tienes configurado como external, para ello debe ingresar la señal de clock para el timer por un pin del pic... prueba de configurarlo como interno a ver que pasa.

AngelGris

Estabas en lo cierto al configurar el timer como INTERNAL
 en vez de external funciona, pasito a pasito... avanzamos..