TODOPIC

Microcontroladores PIC => Lenguaje Basic para microcontroladores PIC => Mensaje iniciado por: okapi en 03 de Septiembre de 2022, 00:54:40

Título: Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 03 de Septiembre de 2022, 00:54:40
Qué tal amigos.
Esperando que se encuentren lo mejor posible!
Solicito de su inmensa ayuda.
El asunto es que en Picbasic Pro  he logrado generar  unos pulsos  por medio de la interrupción,  por desbordamiento del timer en el PIC 16F628A.
He conseguido contar los pulsos llamados Ticks, para hacer segundos y luego decenas de segundos.
Pero a la hora de querer hacer unos retardos, no sé cómo implementarlos, concretamente no encuentro la manera de  hacer que un LED permanezca encendido unos segundos después de soltado el pulsador,  en otras palabras quiero implementar un monoestable Off Delay y otro On Delay  basados en los segundos generados con el Timer del PIC.
Cualquier orientación que me puedan brindar será muy bienvenida.
Saludos!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: Robert76 en 03 de Septiembre de 2022, 09:33:51
Hola, pues teniendo la base de tiempos disponible, ya tienes el 50% hecho.
Entonces si quieres hacer un retardo a la desconexión, pues en el momento que se produce el evento, enciendes un LED, ahi debes disparar el contador por interrupción, para que cuándo desborde apagues el LED.
En caso de necesitar un retardo a la conexión, debes disparar el contador y (apagar el LED, si es que en condición inicial estaba encendido) al iniciar el evento y luego cuándo desborde, enciendes el LED.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 03 de Septiembre de 2022, 14:22:26
Hola, pues teniendo la base de tiempos disponible, ya tienes el 50% hecho.
Entonces si quieres hacer un retardo a la desconexión, pues en el momento que se produce el evento, enciendes un LED, ahi debes disparar el contador por interrupción, para que cuándo desborde apagues el LED.
En caso de necesitar un retardo a la conexión, debes disparar el contador y (apagar el LED, si es que en condición inicial estaba encendido) al iniciar el evento y luego cuándo desborde, enciendes el LED.
Robert76, gracias por responder.
Soy muy novato y un poco cabeza dura en el tema de programar microcontroladores.
Bueno te cuento que he avanzado hasta el punto que cuando han transcurrido, digamos dos segundos, entonces se activa una bandera que indica esta situación, pero de ahí no logro avanzar.
La imagen adjunta ilustra lo que voy a describir.
Tengo dos variables varbit, A y B, si estas estas dos se cumplen el led está encendido, pero cuando una de las dos no está presente el led se apaga, pero después de unos segundos.
Mi codigo está así:

A Var Bit
B Var Bit
LED Var Bit

Inicio:
IF A=0 & B=0 THEN LED=1
Bandera de dos segundos=1
ELSE
LED=0
ENDIF
GOTO Inicio
END

Pero el led no se queda encendido por 2 segundos.
No se dónde y en que términos de código iría la bandera que indica que el  led debe permanecer encendido por dos segundos.
Esto me está volviendo loco.
Algún ejemplo para guiarme por favor.
Ayuda por favor!
Saludos!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 03 de Septiembre de 2022, 16:17:06
El asunto es que en Picbasic Pro  he logrado generar  unos pulsos  por medio de la interrupción,  por desbordamiento del timer en el PIC 16F628A.
He conseguido contar los pulsos llamados Ticks, para hacer segundos y luego decenas de segundos.

Este 'logro' deberías compartir su código para intentar añadirlo al otro pseudocódigo de los pulsadores e intentar que comprendas como hacer lo que deseas
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 03 de Septiembre de 2022, 16:45:19
Hola, pues teniendo la base de tiempos disponible, ya tienes el 50% hecho.
Entonces si quieres hacer un retardo a la desconexión, pues en el momento que se produce el evento, enciendes un LED, ahi debes disparar el contador por interrupción, para que cuándo desborde apagues el LED.
En caso de necesitar un retardo a la conexión, debes disparar el contador y (apagar el LED, si es que en condición inicial estaba encendido) al iniciar el evento y luego cuándo desborde, enciendes el LED.
Robert76, gracias por responder.
Soy muy novato y un poco cabeza dura en el tema de programar microcontroladores.
Bueno te cuento que he avanzado hasta el punto que cuando han transcurrido, digamos dos segundos, entonces se activa una bandera que indica esta situación, pero de ahí no logro avanzar.
La imagen adjunta ilustra lo que voy a describir.
Tengo dos variables varbit, A y B, si estas estas dos se cumplen el led está encendido, pero cuando una de las dos no está presente el led se apaga, pero después de unos segundos.
Mi codigo está así:

A Var Bit
B Var Bit
LED Var Bit

Inicio:
IF A=0 & B=0 THEN LED=1
Bandera de dos segundos=1
ELSE
LED=0
ENDIF
GOTO Inicio
END

Pero el led no se queda encendido por 2 segundos.
No se dónde y en que términos de código iría la bandera que indica que el  led debe permanecer encendido por dos segundos.
Esto me está volviendo loco.
Algún ejemplo para guiarme por favor.
Ayuda por favor!
Saludos!

Yo lo haría en estados de maquina, más o menos un pseudocódigo seria así: (Disculpa que no lo escriba en Basic, ya que no recuerdo como era, pero la idea es lo importante)

Código: C
  1. estado = 0;
  2. LED = 0;
  3. while (1) //lazo principal dentro de main
  4. {
  5.      switch(estado)
  6.      {
  7.             case 0: //el primer caso, se debe esperar a que A y B estén en cero para iniciar el proceso
  8.             {
  9.                   IF A=0 & B=0
  10.                   {
  11.                        estado = 1;
  12.                   }
  13.                   break;
  14.              }
  15.             case 1: // en el segundo estado se espera que A y B estén en 1 lógico para activar LED
  16.             {
  17.                   IF A=1 & B=1
  18.                   {
  19.                        estado = 2;
  20.                        LED = 1;
  21.                   }
  22.                   break;
  23.              }
  24.              case 3:// Aquí se espera  que A ó B cambien a cero lógico para activar el retardo
  25.             {
  26.                    IF A=0 || B=0
  27.                   {
  28.                        delay(); // aquí se queda el programa en un reatrdo determiando
  29.                        estado = 4;
  30.                    }
  31.                   break;
  32.              }
  33.              default: //equivale a case 4
  34.              {
  35.                    LED = 0;
  36.                    estado = 1; //regreso al estado 1
  37.               }
  38.      }
  39. }

Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 03 de Septiembre de 2022, 17:29:36
DominusDRR,

Gracias por tu respuesta.
Me recomiendas que utilice  select case.
Pero, lo que no me queda claro y es lo más relevante, es cómo y donde utilizar la bandera que indica que han transcurrido los dos segundos.



Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: Robert76 en 03 de Septiembre de 2022, 17:39:15
La bandera que te indica que transcurrió el tiempo, debe estar en la rutina que es llamada cuando desborde el contador.
Ahí está el secreto.
Mejor publica el código COMPLETO. Sino estaremos especulando lo que estás haciendo.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 03 de Septiembre de 2022, 18:14:46
DominusDRR,

Gracias por tu respuesta.
Me recomiendas que utilice  select case.
Pero, lo que no me queda claro y es lo más relevante, es cómo y donde utilizar la bandera que indica que han transcurrido los dos segundos.

Comparte el código que genera retardos como dice don Robert76 y de esa manera se puede explicar como utilizarlo.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: dogflu66 en 04 de Septiembre de 2022, 07:33:06
Hola; a ver si esto te puede orientar:

'Este programa de ejemplo necesita un timer y usar interrupciones.
'Función para hacer parpadear un led.
ConfigPin RB0 = output
Symbol ledverde = RB0
main:

   ledverde = _dutyms0(100, 500)

goto main
end

'Controla el estado de un bit en mSeg.
'Devuelve Bit.
Function _dutyms0(_Delay_On As Long, _Delay_Off As Long) As Bit
   If _bt0call = 1 Then
      Toggle _dutyms0
      If _dutyms0 = 0 Then
         Call _bt0call(_btsetup, _Delay_Off) 'Tiempo a Off, carga CONTADOR
      Else
         Call _bt0call(_btsetup, _Delay_On) 'Tiempo a On, carga CONTADOR
      Endif
   Endif
End Function

Esta función permite el parpadeo de un led, se le suministra el tiempo a on y el tiempo a off en mSeg.
_dutyms0 es una variable de 1bit y devuelve el estado de la función.

_bt0call es una variable de un bit que se asocia a la variable contador que se suele estar en las interrupciones, si contador es mayor a 0 entonces _bt0call = 0 y si es igual a 0 _bt0call = 1.
Call _bt0call(_btsetup, _delay_off) lo que hace es recargar el valor del contador que se decrementa (en el caso del ejemplo) con el valor _delay_off o _delay_on en mSeg. e iguala _bt0call = 0.
La función Call _bt0call(_btsetup, _delay) la cambias por tu código.

No he puesto más código porque no es el mismo lenguaje, solo tienes que adaptar la idea de la función a tu código.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 08 de Septiembre de 2022, 15:04:51
Agradecimientos a todos los que respondieron, por su tiempo y paciencia.
La animación adjunta ilustra con precisión lo que necesito hacer.
Ojalá alguien pudiera dar una luz sobre este tema en Picbasic Pro, ya que el resto de lenguajes los desconozco totalmente.
Gracias
Saludos!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: Robert76 en 08 de Septiembre de 2022, 15:08:26
Se entiende a la perfección lo que buscas.
Pero sube el código que estás usando, sino cuesta avanzar.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 08 de Septiembre de 2022, 16:49:32
Agradecimientos a todos los que respondieron, por su tiempo y paciencia.
La animación adjunta ilustra con precisión lo que necesito hacer.
Ojalá alguien pudiera dar una luz sobre este tema en Picbasic Pro, ya que el resto de lenguajes los desconozco totalmente.
Gracias
Saludos!

Si tomas el ejemplo de dogflu66, ya tendrías tu temporizador ONOFF.

Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 08 de Septiembre de 2022, 18:02:40
Se entiende a la perfección lo que buscas.
Pero sube el código que estás usando, sino cuesta avanzar.

Buenas tardes.
Aquí está:
 
SW1 Var Bit
SW2 Var Bit
LED1 Var Bit

Inicio:

IF SW1=0  THEN HIGH LED1    ;Al presionar SW1 se enciende el LED


IF SW2=0  THEN LOW LED       ;Al presionar SW2 se apaga, pero necesito que lo haga luego de 2
                                              ;segundos. No puedo usar PAUSE ni PAUSEUS, porque se el
                                              ;programa se queda trabado y no podrá realizar otras acciones.
GOTO Inicio
END

Saludos!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 08 de Septiembre de 2022, 18:04:37
Se entiende a la perfección lo que buscas.
Pero sube el código que estás usando, sino cuesta avanzar.

Buenas tardes.
Aquí está:
 
SW1 Var Bit
SW2 Var Bit
LED1 Var Bit

Inicio:

IF SW1=0  THEN HIGH LED1    ;Al presionar SW1 se enciende el LED


IF SW2=0  THEN LOW LED       ;Al presionar SW2 se apaga, pero necesito que lo haga luego de 2
                                              ;segundos. No puedo usar PAUSE ni PAUSEUS, porque se el
                                              ;programa se queda trabado y no podrá realizar otras acciones.
GOTO Inicio
END

Saludos!

Hombre, lo que te piden es el código que has logrado generar retardos.

Citar
]He conseguido contar los pulsos llamados Ticks, para hacer segundos y luego decenas de segundos.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 08 de Septiembre de 2022, 18:05:53
Agradecimientos a todos los que respondieron, por su tiempo y paciencia.
La animación adjunta ilustra con precisión lo que necesito hacer.
Ojalá alguien pudiera dar una luz sobre este tema en Picbasic Pro, ya que el resto de lenguajes los desconozco totalmente.
Gracias
Saludos!

Si tomas el ejemplo de dogflu66, ya tendrías tu temporizador ONOFF.

Lo que sucede es que no entiendo ese lenguaje de programación.
Por favor, puedes decirme qué lenguaje es ? porque Picbasic Pro no es, verdad?
Saludos!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 08 de Septiembre de 2022, 18:07:55
Agradecimientos a todos los que respondieron, por su tiempo y paciencia.
La animación adjunta ilustra con precisión lo que necesito hacer.
Ojalá alguien pudiera dar una luz sobre este tema en Picbasic Pro, ya que el resto de lenguajes los desconozco totalmente.
Gracias
Saludos!

Si tomas el ejemplo de dogflu66, ya tendrías tu temporizador ONOFF.

Lo que sucede es que no entiendo ese lenguaje de programación.
Por favor, puedes decirme qué lenguaje es ? porque Picbasic Pro no es, verdad?
Saludos!

No tomes ese ejemplo si no te sirve y comparte el que dices que has logrado ¿O tal vez no lograste?
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 08 de Septiembre de 2022, 19:07:34
Se entiende a la perfección lo que buscas.
Pero sube el código que estás usando, sino cuesta avanzar.

Buenas tardes.
Aquí está:
 
SW1 Var Bit
SW2 Var Bit
LED1 Var Bit

Inicio:

IF SW1=0  THEN HIGH LED1    ;Al presionar SW1 se enciende el LED


IF SW2=0  THEN LOW LED       ;Al presionar SW2 se apaga, pero necesito que lo haga luego de 2
                                              ;segundos. No puedo usar PAUSE ni PAUSEUS, porque se el
                                              ;programa se queda trabado y no podrá realizar otras acciones.
GOTO Inicio
END

Saludos!

Hombre, lo que te piden es el código que has logrado generar retardos.

Citar
]He conseguido contar los pulsos llamados Ticks, para hacer segundos y luego decenas de segundos.
Bueno, en este momento no me encuentro en casa, pero resumiendo vuelvo a comentar que con el uso de uno de los timers del PIC y por desbordamiento de este, he conseguido pulsos de 100 milisegundos y a partir de estos pude conseguir el retardo de un segundo, en ese momento, la bandera se pone en "1" indicando que ha transcurrido un segundo.
Creo que hasta aquí está claro el asunto del retardo de un segundo.
Lo que no puedo lograr, es donde encajar este retardo para que el led quede prendido un segundo después de haber sido desactivado.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 08 de Septiembre de 2022, 19:13:14
Se entiende a la perfección lo que buscas.
Pero sube el código que estás usando, sino cuesta avanzar.

Buenas tardes.
Aquí está:
 
SW1 Var Bit
SW2 Var Bit
LED1 Var Bit

Inicio:

IF SW1=0  THEN HIGH LED1    ;Al presionar SW1 se enciende el LED


IF SW2=0  THEN LOW LED       ;Al presionar SW2 se apaga, pero necesito que lo haga luego de 2
                                              ;segundos. No puedo usar PAUSE ni PAUSEUS, porque se el
                                              ;programa se queda trabado y no podrá realizar otras acciones.
GOTO Inicio
END

Saludos!

Hombre, lo que te piden es el código que has logrado generar retardos.

Citar
]He conseguido contar los pulsos llamados Ticks, para hacer segundos y luego decenas de segundos.
Bueno, en este momento no me encuentro en casa, pero resumiendo vuelvo a comentar que con el uso de uno de los timers del PIC y por desbordamiento de este, he conseguido pulsos de 100 milisegundos y a partir de estos pude conseguir el retardo de un segundo, en ese momento, la bandera se pone en "1" indicando que ha transcurrido un segundo.
Creo que hasta aquí está claro el asunto del retardo de un segundo.
Lo que no puedo lograr, es donde encajar este retardo para que el led quede prendido un segundo después de haber sido desactivado.

Por eso te piden ese código para encajarlo con otro más sencillo.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: Robert76 en 08 de Septiembre de 2022, 19:47:44
Reitero y me sumo a la petición de Dominus.
Por favor si eres tan amable de subir el código que comentas aquí: :?
"  que con el uso de uno de los timers del PIC y por desbordamiento de este, he conseguido pulsos de 100 milisegundos y a partir de estos pude conseguir el retardo de un segundo, en ese momento, la bandera se pone en "1" indicando que ha transcurrido un segundo. 

Luego veremos cómo activar/desactivar la salida que deseas!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 08 de Septiembre de 2022, 21:04:28
Reitero y me sumo a la petición de Dominus.
Por favor si eres tan amable de subir el código que comentas aquí: :?
"  que con el uso de uno de los timers del PIC y por desbordamiento de este, he conseguido pulsos de 100 milisegundos y a partir de estos pude conseguir el retardo de un segundo, en ese momento, la bandera se pone en "1" indicando que ha transcurrido un segundo. 

Luego veremos cómo activar/desactivar la salida que deseas!

Ok.

Aquí está el código:

Encabezado, etc. etc.


On Interrupt Goto interpt

Pulsos VAR BYTE
Segundos VAR BYTE
Bandera_seg VAR BIT

SW1 Var Bit
SW2 Var Bit
LED1 Var Bit



Main:

;En esta parte necesito hacer el retardo

IF SW1=0  THEN HIGH LED1    ;Al presionar SW1 se enciende el LED


IF SW2=0  THEN LOW LED1     ;Al presionar SW2 se apaga, pero necesito que lo haga

luego de  2 sgs
                                                 

Goto Main

 
interpt:

Disable

If PIR1.0 = 1 Then         
Pulsos=Pulsos+1   
If Pulsos = 10 Then   
Segundos = Segundos + 1   ; Incrementar los Segundos
Pulsos = 0      
EndIf
If Segundos = 2 Then
Segundos = 0      
Bandera_seg = 1    ;Tiempo completado.
EndIf         
EndIf

resume
enable

END
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 08 de Septiembre de 2022, 22:41:56
Reitero y me sumo a la petición de Dominus.
Por favor si eres tan amable de subir el código que comentas aquí: :?
"  que con el uso de uno de los timers del PIC y por desbordamiento de este, he conseguido pulsos de 100 milisegundos y a partir de estos pude conseguir el retardo de un segundo, en ese momento, la bandera se pone en "1" indicando que ha transcurrido un segundo. 

Luego veremos cómo activar/desactivar la salida que deseas!

Ok.

Aquí está el código:

Encabezado, etc. etc.


On Interrupt Goto interpt

Pulsos VAR BYTE
Segundos VAR BYTE
Bandera_seg VAR BIT

SW1 Var Bit
SW2 Var Bit
LED1 Var Bit



Main:

;En esta parte necesito hacer el retardo

IF SW1=0  THEN HIGH LED1    ;Al presionar SW1 se enciende el LED


IF SW2=0  THEN LOW LED1     ;Al presionar SW2 se apaga, pero necesito que lo haga

luego de  2 sgs
                                                 

Goto Main

 
interpt:

Disable

If PIR1.0 = 1 Then         
Pulsos=Pulsos+1   
If Pulsos = 10 Then   
Segundos = Segundos + 1   ; Incrementar los Segundos
Pulsos = 0      
EndIf
If Segundos = 2 Then
Segundos = 0      
Bandera_seg = 1    ;Tiempo completado.
EndIf         
EndIf

resume
enable

END


No soy experto en basic, pero voy a intentarlo, si alguien conoce mejor el código, que me corrija cualquier cosa errónea por favor.

El código que has compartido, se está asumiendo que la interrupción genera correctamente el tiempo que deseas.


Código: QBasic/QuickBASIC
  1. Main:
  2.  
  3. PIR1.0 = 0; Apago la interrupción del temporizador
  4. Pulsos = 0
  5. Bandera_seg = 0
  6. Segundos = 0; inicializo las variables
  7. LOW LED1 ; led apagado
  8. Lazo:
  9. IF SW1 = 0 THEN; espero a que presionen SW1
  10.     HIGH LED1;
  11.     WHILE  SW2=1 EndWhile ; espero hasta que SW2 sea presionado
  12.     PIR1.0 = 1; Activo la interrupción y el temporizador empieza a funcionar
  13.     WHILE  Bandera_seg = 0 END WHILE ; espera que bandera pase a 1 lógico
  14.     LOW LED1 ; apago el led
  15.     GOTO Main; reinicio el proceso
  16. EndIf
  17. GOTO Lazo
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: Eduardo2 en 09 de Septiembre de 2022, 01:05:56
Mientras el programa haga solo eso y no metas tareas que no puedan suspenderse durante el retardo, usá la instrucción PAUSE y a otra cosa.

Código: Text
  1. ;En esta parte necesito hacer el retardo
  2. IF SW1=0  THEN HIGH LED1    ;Al presionar SW1 se enciende el LED
  3.  
  4. IF SW2=0  THEN
  5.     PAUSE 2000    
  6.     LOW LED1
  7. ENDIF
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: dogflu66 en 09 de Septiembre de 2022, 07:03:32
El lenguaje que uso es el Basic del Pic Simulator IDE (PSI).
Estoy revisando tu código y el Basic PSI es prácticamente igual al que estas usando.
Lo que si estoy viendo es que estas usando concepto erróneos, no entiendo el motivo de contar segundos, cuando lo
normal es contar mSeg., simplemente haces una pausa de tantos miles de mSeg.
Y lo que se suele hacer, como te indique en la respuesta anterior, es simplemente cargar un contador con los mSeg. o multiplos de estos.
que quieres contar e ir decrementando, cuando el contador es igual a cero ya paso el tiempo que quieres, haces lo
que tengas que hacer y vuelves a cargar el contador con el siguiente tiempo.


Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: dogflu66 en 09 de Septiembre de 2022, 07:50:12
Aquí tienes un ejemplo; cambia lo que necesites e ignora las declaraciones no compatibles, pero el código es muy parecido al de tu lenguaje.

Código: QBasic/QuickBASIC
  1. 'Pic16F628A, oscilador interno 4Mhz
  2. 'Configuración de fuses
  3. #define CONFIG = 0x3f50
  4. Define CLOCK_FREQUENCY = 4  'Oscilador a 4Mhz
  5. 'Include "_FuncionesPic16F628A.bas"
  6. 'Include "_FunctionesTmrBase.bas"
  7. 'Call _setup_oscillator(_osc_4Mhz)
  8. PCON.OSCF = 1  'Oscilador interno 4Mhz
  9. 'Inicializa Timer1 para generar una interrupción cada 1mSeg.
  10. 'Call _setup_timer1(_tmr1_internal, _tmr1_div1)  'Configura TMR1 para 4Mhz
  11. T1CON = 0  'Asigna oscilador interno para el tmr1
  12. T1CON.T1CKPS1 = 0  'Asigna el divisor
  13. T1CON.T1CKPS0 = 0
  14. 'Call _set_timer1(0xfc17)  'Carga contador TMr1 para contar 1mSeg.
  15. T1CON.TMR1ON = 0  'Para el contador del TMR1
  16. TMR1H = 0xfc  'Recarga el byte alto
  17. TMR1L = 0x17  'Recarga el byte bajo
  18. T1CON.TMR1ON = 1  'Activa el contador del TMR1
  19. PIR1.TMR1IF = 0  'Flash dosborde a cero
  20. 'Call _timer1(_on)  'Pone en marcha el Tmr1
  21. T1CON.TMR1ON = 1  'Activa el contador del TMR1
  22. 'Call _enable_interrupts(_int_timer1)  'Permite las interrupciones por desborde Tmr1
  23. PIE1.TMR1IE = 1  'Permite la interrup. TIMER1
  24. 'Call _enable_interrupts(_global)  'Permte las interrupciones globales
  25. INTCON.PEIE = 1  'Bit habilita interrupciones perifericos
  26. Enable  'INTCON.GIE habilita las interrupciones
  27. '************************************************************
  28. AllDigital
  29. DIM pulsos AS Byte
  30. DIM segundos AS Byte
  31. DIM bandera_seg AS Bit
  32.  
  33. DIM sw1 AS Bit
  34. DIM sw2 AS Bit
  35. DIM led1 AS Bit
  36. 'Contadores para generar las bases de tiempos.
  37. DIM _contador1 AS LONG
  38. DIM _contador2 AS LONG
  39. _contador1 = 0
  40. _contador2 = 0
  41.  
  42. Main:
  43.  
  44.         ';en esta parte necesito hacer el retardo
  45.  
  46.         IF sw1 = 0 AND _contador1 = 0 THEN
  47.                 High led1  ';al presionar sw1 se enciende el led
  48.                 _contador1 = 1100  'Carga contador con 1Seg.
  49.         Endif
  50.  
  51.         IF sw2 = 0 AND _contador2 = 0 THEN
  52.                 Low led1  ';al presionar sw2 se apaga, pero necesito que lo haga
  53.                 _contador2 = 2000  'Carga contador con 2Seg.
  54.         Endif
  55.  
  56. GOTO Main
  57. END                                              
  58. '****************************
  59. ON Interrupt
  60.         Save SYSTEM  'Guarda calculos intermedios y otros del sistema
  61.         'Detecta interrupción Timer1
  62.         IF PIR1.TMR1IF = 1 THEN
  63.                 'Call _set_timer1(0xfc17)  'Recarga registros TMR1 para desborde 1mSeg. y borra PIR1.TMR1IF
  64.                 T1CON.TMR1ON = 0  'Para el contador del TMR1
  65.                 TMR1H = 0xfc  'Recarga el contador byte alto
  66.                 TMR1L = 0x17  'Recarga el contador byte bajo
  67.                 T1CON.TMR1ON = 1  'Activa el contador del TMR1
  68.                 PIR1.TMR1IF = 0  'Flash dosborde a cero
  69.                 IF _contador1 > 0 THEN _contador1 = _contador1 - 1  '_contador BT
  70.                 IF _contador2 > 0 THEN _contador2 = _contador2 - 1  '_contador BT
  71.         Endif
  72. RESUME                                            
  73. '******************************
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 09 de Septiembre de 2022, 12:07:04
Mientras el programa haga solo eso y no metas tareas que no puedan suspenderse durante el retardo, usá la instrucción PAUSE y a otra cosa.

Código: Text
  1. ;En esta parte necesito hacer el retardo
  2. IF SW1=0  THEN HIGH LED1    ;Al presionar SW1 se enciende el LED
  3.  
  4. IF SW2=0  THEN
  5.     PAUSE 2000    
  6.     LOW LED1
  7. ENDIF
Eduardo2, gracias por tu intención de ayudar, pero si te fijas en el post #12, en él menciono que no puedo usar PAUSE ni PAUSEUS, porque se el programa se queda trabado y no podrá realizar otras acciones.
Saludos!
                                             
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 09 de Septiembre de 2022, 12:15:06
Aquí tienes un ejemplo; cambia lo que necesites e ignora las declaraciones no compatibles, pero el código es muy parecido al de tu lenguaje.

Código: QBasic/QuickBASIC
  1. 'Pic16F628A, oscilador interno 4Mhz
  2. 'Configuración de fuses
  3. #define CONFIG = 0x3f50
  4. Define CLOCK_FREQUENCY = 4  'Oscilador a 4Mhz
  5. 'Include "_FuncionesPic16F628A.bas"
  6. 'Include "_FunctionesTmrBase.bas"
  7. 'Call _setup_oscillator(_osc_4Mhz)
  8. PCON.OSCF = 1  'Oscilador interno 4Mhz
  9. 'Inicializa Timer1 para generar una interrupción cada 1mSeg.
  10. 'Call _setup_timer1(_tmr1_internal, _tmr1_div1)  'Configura TMR1 para 4Mhz
  11. T1CON = 0  'Asigna oscilador interno para el tmr1
  12. T1CON.T1CKPS1 = 0  'Asigna el divisor
  13. T1CON.T1CKPS0 = 0
  14. 'Call _set_timer1(0xfc17)  'Carga contador TMr1 para contar 1mSeg.
  15. T1CON.TMR1ON = 0  'Para el contador del TMR1
  16. TMR1H = 0xfc  'Recarga el byte alto
  17. TMR1L = 0x17  'Recarga el byte bajo
  18. T1CON.TMR1ON = 1  'Activa el contador del TMR1
  19. PIR1.TMR1IF = 0  'Flash dosborde a cero
  20. 'Call _timer1(_on)  'Pone en marcha el Tmr1
  21. T1CON.TMR1ON = 1  'Activa el contador del TMR1
  22. 'Call _enable_interrupts(_int_timer1)  'Permite las interrupciones por desborde Tmr1
  23. PIE1.TMR1IE = 1  'Permite la interrup. TIMER1
  24. 'Call _enable_interrupts(_global)  'Permte las interrupciones globales
  25. INTCON.PEIE = 1  'Bit habilita interrupciones perifericos
  26. Enable  'INTCON.GIE habilita las interrupciones
  27. '************************************************************
  28. AllDigital
  29. DIM pulsos AS Byte
  30. DIM segundos AS Byte
  31. DIM bandera_seg AS Bit
  32.  
  33. DIM sw1 AS Bit
  34. DIM sw2 AS Bit
  35. DIM led1 AS Bit
  36. 'Contadores para generar las bases de tiempos.
  37. DIM _contador1 AS LONG
  38. DIM _contador2 AS LONG
  39. _contador1 = 0
  40. _contador2 = 0
  41.  
  42. Main:
  43.  
  44.         ';en esta parte necesito hacer el retardo
  45.  
  46.         IF sw1 = 0 AND _contador1 = 0 THEN
  47.                 High led1  ';al presionar sw1 se enciende el led
  48.                 _contador1 = 1100  'Carga contador con 1Seg.
  49.         Endif
  50.  
  51.         IF sw2 = 0 AND _contador2 = 0 THEN
  52.                 Low led1  ';al presionar sw2 se apaga, pero necesito que lo haga
  53.                 _contador2 = 2000  'Carga contador con 2Seg.
  54.         Endif
  55.  
  56. GOTO Main
  57. END                                              
  58. '****************************
  59. ON Interrupt
  60.         Save SYSTEM  'Guarda calculos intermedios y otros del sistema
  61.         'Detecta interrupción Timer1
  62.         IF PIR1.TMR1IF = 1 THEN
  63.                 'Call _set_timer1(0xfc17)  'Recarga registros TMR1 para desborde 1mSeg. y borra PIR1.TMR1IF
  64.                 T1CON.TMR1ON = 0  'Para el contador del TMR1
  65.                 TMR1H = 0xfc  'Recarga el contador byte alto
  66.                 TMR1L = 0x17  'Recarga el contador byte bajo
  67.                 T1CON.TMR1ON = 1  'Activa el contador del TMR1
  68.                 PIR1.TMR1IF = 0  'Flash dosborde a cero
  69.                 IF _contador1 > 0 THEN _contador1 = _contador1 - 1  '_contador BT
  70.                 IF _contador2 > 0 THEN _contador2 = _contador2 - 1  '_contador BT
  71.         Endif
  72. RESUME                                            
  73. '******************************
dogflu66 Muchas gracias por tu generosidad al compartir ese código, así como por tu tiempo y paciencia.
Voy a probar lo que me sugieres y cualquier novedad te comento.
Eres muy amable.
Cordial saludo!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 09 de Septiembre de 2022, 12:19:15

No soy experto en basic, pero voy a intentarlo, si alguien conoce mejor el código, que me corrija cualquier cosa errónea por favor.

El código que has compartido, se está asumiendo que la interrupción genera correctamente el tiempo que deseas.


Código: QBasic/QuickBASIC
  1. Main:
  2.  
  3. PIR1.0 = 0; Apago la interrupción del temporizador
  4. Pulsos = 0
  5. Bandera_seg = 0
  6. Segundos = 0; inicializo las variables
  7. LOW LED1 ; led apagado
  8. Lazo:
  9. IF SW1 = 0 THEN; espero a que presionen SW1
  10.     HIGH LED1;
  11.     WHILE  SW2=1 EndWhile ; espero hasta que SW2 sea presionado
  12.     PIR1.0 = 1; Activo la interrupción y el temporizador empieza a funcionar
  13.     WHILE  Bandera_seg = 0 END WHILE ; espera que bandera pase a 1 lógico
  14.     LOW LED1 ; apago el led
  15.     GOTO Main; reinicio el proceso
  16. EndIf
  17. GOTO Lazo
[/quote]
DominusDRR Agradezco mucho tu ayuda desinteresada.
También voy a probar tu código y si tengo alguna inquietud, te estaré comunicando.
Cordialmente,
Okapi
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 09 de Septiembre de 2022, 12:58:01

No soy experto en basic, pero voy a intentarlo, si alguien conoce mejor el código, que me corrija cualquier cosa errónea por favor.

El código que has compartido, se está asumiendo que la interrupción genera correctamente el tiempo que deseas.


Código: QBasic/QuickBASIC
  1. Main:
  2.  
  3. PIR1.0 = 0; Apago la interrupción del temporizador
  4. Pulsos = 0
  5. Bandera_seg = 0
  6. Segundos = 0; inicializo las variables
  7. LOW LED1 ; led apagado
  8. Lazo:
  9. IF SW1 = 0 THEN; espero a que presionen SW1
  10.     HIGH LED1;
  11.     WHILE  SW2=1 EndWhile ; espero hasta que SW2 sea presionado
  12.     PIR1.0 = 1; Activo la interrupción y el temporizador empieza a funcionar
  13.     WHILE  Bandera_seg = 0 END WHILE ; espera que bandera pase a 1 lógico
  14.     LOW LED1 ; apago el led
  15.     GOTO Main; reinicio el proceso
  16. EndIf
  17. GOTO Lazo
DominusDRR Agradezco mucho tu ayuda desinteresada.
También voy a probar tu código y si tengo alguna inquietud, te estaré comunicando.
Cordialmente,
Okapi
[/quote]

Este también te va a dar problemas porque se queda en lazos infinitos esperando el pulsador o la bandera. (Instrucciones While)

Deberías pensar en multitareas con procesos cooperativoss, y para tu caso no es necesario utilizar interrupciones, solamente un temporizador siempre activo para obtener su valor y generar retardos.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: dogflu66 en 09 de Septiembre de 2022, 15:13:09
 

No soy experto en basic, pero voy a intentarlo, si alguien conoce mejor el código, que me corrija cualquier cosa errónea por favor.

El código que has compartido, se está asumiendo que la interrupción genera correctamente el tiempo que deseas.


Código: QBasic/QuickBASIC
  1. Main:
  2.  
  3. PIR1.0 = 0; Apago la interrupción del temporizador
  4. Pulsos = 0
  5. Bandera_seg = 0
  6. Segundos = 0; inicializo las variables
  7. LOW LED1 ; led apagado
  8. Lazo:
  9. IF SW1 = 0 THEN; espero a que presionen SW1
  10.     HIGH LED1;
  11.     WHILE  SW2=1 EndWhile ; espero hasta que SW2 sea presionado
  12.     PIR1.0 = 1; Activo la interrupción y el temporizador empieza a funcionar
  13.     WHILE  Bandera_seg = 0 END WHILE ; espera que bandera pase a 1 lógico
  14.     LOW LED1 ; apago el led
  15.     GOTO Main; reinicio el proceso
  16. EndIf
  17. GOTO Lazo
DominusDRR Agradezco mucho tu ayuda desinteresada.
También voy a probar tu código y si tengo alguna inquietud, te estaré comunicando.
Cordialmente,
Okapi
[/quote]

No tengo una tarjeta ahora mismo para probarlo, pero el módulo de simulación que tiene el compilador indica que si.
Para ser más correctos, se puede ver que un ciclo para el pin RB0 es de 2040uSeg. que dividido entre dos es igual a 1020uSeg. que más o menos son 1mSeg.
Por supuesto se puede ajustar para que sea más exacto pero en general no es necesario.

 
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 09 de Septiembre de 2022, 19:09:07

Este también te va a dar problemas porque se queda en lazos infinitos esperando el pulsador o la bandera. (Instrucciones While)

Deberías pensar en multitareas con procesos cooperativoss, y para tu caso no es necesario utilizar interrupciones, solamente un temporizador siempre activo para obtener su valor y generar retardos.

Si, amigo eso también pensé, al ver los While.
Por favor podrías ser más especifico con lo del temporizador siempre activo?
De ser posible un pequeño ejemplo que me guíe sería muy gentil de tu parte.
Saludos!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 09 de Septiembre de 2022, 19:49:46
Estimado amigo Dogflu66.
He probado el código que tan gentilmente me proporcionaste, lo he revisado minuciosamente pero
por alguna razón no me funciona.
Puse un LED de testigo en la rutina de interrupción para ver si los contadores están decrementando y llegando a cero y si lo hacen, es decir funcionan.
El problema parece estar en la parte del bucle Inicio:
Sw1 enciende el LED, como un switch normal, sin retardo y lo mismo sucede con SW2 que lo apaga sin retardo.
Es como si en esa parte los contadores siempre estuvieran en cero.
Qué podrá ser?
Por si ayuda, adjunto imagen del código
Saludos!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 09 de Septiembre de 2022, 20:23:22

Este también te va a dar problemas porque se queda en lazos infinitos esperando el pulsador o la bandera. (Instrucciones While)

Deberías pensar en multitareas con procesos cooperativoss, y para tu caso no es necesario utilizar interrupciones, solamente un temporizador siempre activo para obtener su valor y generar retardos.

Si, amigo eso también pensé, al ver los While.
Por favor podrías ser más especifico con lo del temporizador siempre activo?
De ser posible un pequeño ejemplo que me guíe sería muy gentil de tu parte.
Saludos!

Con el microcontrolador que tienes y con un temporizador de 16 bits, con su máximo post escalamiento de 8 (asumiendo que el cristal es de 4MHz) me parece que máximo podrías conseguir 0.5 segundos de tiempo.

Por lo tanto necesitarías una variable auxiliar de 16 bits y con el código de don dogflu66, se podría hacer la siguiente parte solamente es para “aumentar” la capacidad del temporizador.

Código: QBasic/QuickBASIC
  1. DIM VariableAuxiliar AS UShort
  2.  
  3. .....
  4.  
  5. ON Interrupt
  6.         Save SYSTEM  'Guarda calculos intermedios y otros del sistema
  7.         'Detecta interrupción Timer1
  8.         IF PIR1.TMR1IF = 1 THEN
  9.                 PIR1.TMR1IF = 0  'Flash dosborde a cero
  10.                 VariableAuxiliar = VariableAuxiliar + 1;
  11.         Endif
  12. RESUME

Con esto tienes una variable (sin signo) que puede contar hasta 65.5 segundos

El siguiente paso es comprender la forma errónea de realizar un retardo, como tu mismo lo indicantes se apropia del CPU del microcontrolador y no puedes hacer otros procesos, salvo que sólo sea el único proceso.


(https://pbs.twimg.com/media/FcP_7hFXwAQO0zS?format=jpg&name=medium)

Para evitar un apropiamiento del CPU se puede recurrir a una variable que captura el valor del temporizador (o en este caso, la variable auxiliar) y determinar si se ha determinado que ha transcurrido un tiempo determinado.

(https://pbs.twimg.com/media/FcQALE2WAAAJmrq?format=png&name=900x900)

Un ejemplo para activar y apagar un led sería más o menos así:

Código: QBasic/QuickBASIC
  1. DIM VariableAuxiliar AS UShort
  2. DIM Retardo Ad Ushort
  3.  
  4. Main:
  5.                 Low led1  ‘ apago el led
  6.                 Retardo = VariableAuxiliar
  7. Lazo:
  8.                IF ((VariableAuxiliar - Retardo) > 2000) THEN
  9.                              TOGGLE led1
  10.                              Retardo = VariableAuxiliar’ Vuelvo a capturar un nuevo valor para otro retardo
  11.                 Endif
  12. GOTO Lazo

Como puedes ver, sólo se verifica si el IF se cumple, caso contrario podría pasar a realizar otro proceso.

Si comprendes esto, se podría intentar hacer tu proyecto de esta manera.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 09 de Septiembre de 2022, 22:45:48


Con el microcontrolador que tienes y con un temporizador de 16 bits, con su máximo post escalamiento de 8 (asumiendo que el cristal es de 4MHz) me parece que máximo podrías conseguir 0.5 segundos de tiempo.

Por lo tanto necesitarías una variable auxiliar de 16 bits y con el código de don dogflu66, se podría hacer la siguiente parte solamente es para “aumentar” la capacidad del temporizador.

Código: QBasic/QuickBASIC
  1. DIM VariableAuxiliar AS UShort
  2.  
  3. .....
  4.  
  5. ON Interrupt
  6.         Save SYSTEM  'Guarda calculos intermedios y otros del sistema
  7.         'Detecta interrupción Timer1
  8.         IF PIR1.TMR1IF = 1 THEN
  9.                 PIR1.TMR1IF = 0  'Flash dosborde a cero
  10.                 VariableAuxiliar = VariableAuxiliar + 1;
  11.         Endif
  12. RESUME

Con esto tienes una variable (sin signo) que puede contar hasta 65.5 segundos

El siguiente paso es comprender la forma errónea de realizar un retardo, como tu mismo lo indicantes se apropia del CPU del microcontrolador y no puedes hacer otros procesos, salvo que sólo sea el único proceso.


(https://pbs.twimg.com/media/FcP_7hFXwAQO0zS?format=jpg&name=medium)

Para evitar un apropiamiento del CPU se puede recurrir a una variable que captura el valor del temporizador (o en este caso, la variable auxiliar) y determinar si se ha determinado que ha transcurrido un tiempo determinado.

(https://pbs.twimg.com/media/FcQALE2WAAAJmrq?format=png&name=900x900)

Un ejemplo para activar y apagar un led sería más o menos así:

Código: QBasic/QuickBASIC
  1. DIM VariableAuxiliar AS UShort
  2. DIM Retardo Ad Ushort
  3.  
  4. Main:
  5.                 Low led1  ‘ apago el led
  6.                 Retardo = VariableAuxiliar
  7. Lazo:
  8.                IF ((VariableAuxiliar - Retardo) > 2000) THEN
  9.                              TOGGLE led1
  10.                              Retardo = VariableAuxiliar’ Vuelvo a capturar un nuevo valor para otro retardo
  11.                 Endif
  12. GOTO Lazo

Como puedes ver, sólo se verifica si el IF se cumple, caso contrario podría pasar a realizar otro proceso.

Si comprendes esto, se podría intentar hacer tu proyecto de esta manera.

DominusDRR
Muchas gracias por tus explicaciones, son mu ilustrativas y valoro mucho tu ayuda desinteresada.
Si te fijas en el post #19 de la página dos, ahí publique un código donde utilizo variables auxiliares para, partiendo de los desbordes, generar segundos.
Reitero, mi problema no está en conseguir los retardos, eso ya lo he logrado.
Mi inconveniente está en que no soy capaz de colocarlos en el sitio que corresponden, no sé cómo hacerlo.
Quizás sea sencillo, pero para un inexperto como yo, no lo es.
Adjunto una imagen para ilustrar lo dicho.
Gracias nuevamente
 
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 09 de Septiembre de 2022, 23:14:56
Si tu dices que te funciona bien el código que has realizado, como dice don  dogflu66, debes realizar un conteo mas preciso, digamos milisegundos, pero aceptemos tu código y utilicemos décimas de segundo, entonces tu código de la interrupción quedaría así:

Código: QBasic/QuickBASIC
  1. ON Interrupt
  2. IF PIR1.0 = 1 THEN        
  3.     Pulsos=Pulsos+1  
  4. EndIf


Pulsos se incrementan cada 0.1 segundos (por eso cuando es igual a 10 en tu anterior código, asumes que es 1 segundo.

Nota que nunca deshabilito la interrupción. es decir nunca utilizo Disable, similar a la interrupción de dogflu66

También declara a pulsos como una variable sin signo.

Ahora vamos a tu código:

Código: QBasic/QuickBASIC
  1. ON Interrupt GOTO interpt
  2.  
  3. DIM Pulsos AS UShort
  4. DIM ContadorPulsos AS UShort
  5. EstadoTarea VAR BYTE
  6. Segundos VAR BYTE
  7. Bandera_seg VAR BIT
  8.  
  9. SW1 Var Bit
  10. SW2 Var Bit
  11. LED1 Var Bit
  12.  
  13.  
  14. Main:
  15.        EstadoTarea = 0x00;' Inicializo EstadoTarea
  16.         LOWLED1' apago el led inicialmente
  17. Lazo:
  18.         SELECT CASE EstadoTarea
  19.               CASE 0 ' en case 0, se espera a que presionen sw1
  20.                  IF SW1=0  THEN
  21.                      HIGH LED1    'Al presionar SW1 se enciende el LED
  22.                     EstadoTarea = 1' voy al siguiente caso
  23.                 Endif
  24.               CASE 1' Espero a que presionen el pulsador SW2 para empezar el retardo
  25.                    IF SW2=0  THEN
  26.                     ContadorPulsos = Pulsos' Capturo el valor de pulsos
  27.                     EstadoTarea = 2' voy al siguiente caso
  28.                 Endif
  29.               CASE 2' Espero que hayan pasado 20 pulsos (20 pulsos x 0.1s = 2 segundos)
  30.                  IF ((Pulsos- ContadorPulsos) > 20) THEN
  31.                               LOWLED' apago el led
  32.                               EstadoTarea = 0' regreso al primer estado
  33.                 Endif
  34.         EndSelect
  35. GOTO Lazo:
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: dogflu66 en 10 de Septiembre de 2022, 07:09:15
Entiendo que pulsas una tecla y pasado un tiempo se actualiza el estado del led.
Una tecla es para activarlo y la otra tecla para apagarlo.
Todo esto sin afectar al flujo del programa.
¿Estoy en lo cierto?.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: dogflu66 en 10 de Septiembre de 2022, 07:11:26
Aparte de lo anterior, el código que pusiste antes está como imagen, por lo que no puedo copiarlo y pegarlo en mi IDE.
De todas formas lo he probado y si me funciona, aunque este código solo es un ejemplo y no hace exactamente lo que quieres.

Código: QBasic/QuickBASIC
  1. #define CONFIG = 0x3f50
  2. #define CLOCK_FREQUENCY = 4
  3. CMCON = 7
  4. DIM precarga AS Word
  5. DIM _contador1 AS Word
  6. DIM _contador2 AS Word
  7. Symbol led1 = PORTB.0
  8. Symbol led2 = PORTB.1
  9. Symbol sw1 = PORTA.2
  10. Symbol sw2 = PORTA.3
  11.  
  12. TRISA = %11111111
  13. TRISB = %00000000
  14.  
  15. PORTB = 0
  16. led1 = 0
  17. led2 = 0
  18. _contador1 = 0
  19. _contador2 = 0
  20.  
  21. T1CON = %00111101
  22. precarga = 0xfc17
  23. TMR1H = precarga.HB
  24. TMR1L = precarga.LB
  25. PIE1.0 = 1
  26. INTCON = %11000000
  27.  
  28. 'On itenrrupt Goto interrupcion
  29.  
  30. inicio:
  31.  
  32. IF sw1 = 0 AND _contador1 = 0 THEN
  33.         High led1
  34.         _contador1 = 1000
  35. Endif
  36.  
  37. IF sw2 = 0 AND _contador2 = 0 THEN
  38.         Low led1
  39.         _contador2 = 2000
  40. Endif
  41.  
  42. GOTO inicio
  43. END                                              
  44.  
  45. ON Interrupt  '= a nombre subrutina interrupción y hace Disable
  46. 'Disable
  47.         IF PIR1.0 = 1 THEN
  48.                 T1CON.0 = 0
  49.                 TMR1H = precarga.HB
  50.                 TMR1L = precarga.LB
  51.                 T1CON.0 = 1
  52.                 PIR1.0 = 0
  53.                 IF _contador1 > 0 THEN _contador1 = _contador1 - 1
  54.                 IF _contador2 > 0 THEN _contador2 = _contador2 - 1
  55.         Endif
  56. 'Resume = fin rutina interrupción y hace Enable
  57. RESUME



Y este es el código segun tu esquema:

Código: QBasic/QuickBASIC
  1. AllDigital
  2. ConfigPin RB0 = OUTPUT
  3. ConfigPin RB1 = OUTPUT
  4. ConfigPin RA2 = INPUT
  5. ConfigPin RA3 = INPUT
  6. Symbol led1 = RB0
  7. Symbol led2 = RB1
  8. Symbol sw1 = RA2
  9. Symbol sw2 = RA3
  10.  
  11. 'Contadores para generar las bases de tiempos.
  12. DIM _contador1 AS LONG
  13. DIM _contador2 AS LONG
  14. _contador1 = 0
  15. _contador2 = 0
  16. 'Flag de control
  17. DIM flag1 AS Bit
  18. DIM flag2 AS Bit
  19. flag1 = 0
  20. flag2 = 0
  21.  
  22. Main:
  23.  
  24.         'Temporizador no redisparable, para redisparable quitar flag1 = 0
  25.         'Para ser bloqueado por el anterior añadir "and flag2 = 0"
  26.         IF sw1 = 0 AND flag1 = 0 THEN
  27.                 _contador1 = 1000
  28.                 flag1 = 1
  29.         ELSE
  30.                 IF _contador1 = 0 AND flag1 = 1 THEN
  31.                         High led1
  32.                         flag1 = 0
  33.                 Endif
  34.         Endif
  35.         'Temporizador no redisparable, para redisparable quitar flag2 = 0
  36.         'Para ser bloqueado por el anterior añadir "and flag1 = 0"
  37.         IF sw2 = 0 AND flag2 = 0 THEN
  38.                 _contador1 = 2000
  39.                 flag2 = 1
  40.         ELSE
  41.                 IF _contador1 = 0 AND flag2 = 1 THEN
  42.                         Low led1
  43.                         flag2 = 0
  44.                 Endif
  45.         Endif
  46.        
  47. GOTO Main
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: dogflu66 en 10 de Septiembre de 2022, 08:01:30
Si tu dices que te funciona bien el código que has realizado, como dice don  dogflu66, debes realizar un conteo mas preciso, digamos milisegundos, pero aceptemos tu código y utilicemos décimas de segundo, entonces tu código de la interrupción quedaría así:

Código: QBasic/QuickBASIC
  1. ON Interrupt
  2. IF PIR1.0 = 1 THEN        
  3.     Pulsos=Pulsos+1  
  4. EndIf


Pulsos se incrementan cada 0.1 segundos (por eso cuando es igual a 10 en tu anterior código, asumes que es 1 segundo.

Nota que nunca deshabilito la interrupción. es decir nunca utilizo Disable, similar a la interrupción de dogflu66

También declara a pulsos como una variable sin signo.

Ahora vamos a tu código:

Código: QBasic/QuickBASIC
  1. ON Interrupt GOTO interpt
  2.  
  3. DIM Pulsos AS UShort
  4. DIM ContadorPulsos AS UShort
  5. EstadoTarea VAR BYTE
  6. Segundos VAR BYTE
  7. Bandera_seg VAR BIT
  8.  
  9. SW1 Var Bit
  10. SW2 Var Bit
  11. LED1 Var Bit
  12.  
  13.  
  14. Main:
  15.        EstadoTarea = 0x00;' Inicializo EstadoTarea
  16.         LOWLED1' apago el led inicialmente
  17. Lazo:
  18.         SELECT CASE EstadoTarea
  19.               CASE 0 ' en case 0, se espera a que presionen sw1
  20.                  IF SW1=0  THEN
  21.                      HIGH LED1    'Al presionar SW1 se enciende el LED
  22.                     EstadoTarea = 1' voy al siguiente caso
  23.                 Endif
  24.               CASE 1' Espero a que presionen el pulsador SW2 para empezar el retardo
  25.                    IF SW2=0  THEN
  26.                     ContadorPulsos = Pulsos' Capturo el valor de pulsos
  27.                     EstadoTarea = 2' voy al siguiente caso
  28.                 Endif
  29.               CASE 2' Espero que hayan pasado 20 pulsos (20 pulsos x 0.1s = 2 segundos)
  30.                  IF ((Pulsos- ContadorPulsos) > 20) THEN
  31.                               LOWLED' apago el led
  32.                               EstadoTarea = 0' regreso al primer estado
  33.                 Endif
  34.         EndSelect
  35. GOTO Lazo:

Te salió un código muy elegante  ((:-))
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 10 de Septiembre de 2022, 10:06:02
Si tu dices que te funciona bien el código que has realizado, como dice don  dogflu66, debes realizar un conteo mas preciso, digamos milisegundos, pero aceptemos tu código y utilicemos décimas de segundo, entonces tu código de la interrupción quedaría así:

Código: QBasic/QuickBASIC
  1. ON Interrupt
  2. IF PIR1.0 = 1 THEN        
  3.     Pulsos=Pulsos+1  
  4. EndIf


Pulsos se incrementan cada 0.1 segundos (por eso cuando es igual a 10 en tu anterior código, asumes que es 1 segundo.

Nota que nunca deshabilito la interrupción. es decir nunca utilizo Disable, similar a la interrupción de dogflu66

También declara a pulsos como una variable sin signo.

Ahora vamos a tu código:

Código: QBasic/QuickBASIC
  1. ON Interrupt GOTO interpt
  2.  
  3. DIM Pulsos AS UShort
  4. DIM ContadorPulsos AS UShort
  5. EstadoTarea VAR BYTE
  6. Segundos VAR BYTE
  7. Bandera_seg VAR BIT
  8.  
  9. SW1 Var Bit
  10. SW2 Var Bit
  11. LED1 Var Bit
  12.  
  13.  
  14. Main:
  15.        EstadoTarea = 0x00;' Inicializo EstadoTarea
  16.         LOWLED1' apago el led inicialmente
  17. Lazo:
  18.         SELECT CASE EstadoTarea
  19.               CASE 0 ' en case 0, se espera a que presionen sw1
  20.                  IF SW1=0  THEN
  21.                      HIGH LED1    'Al presionar SW1 se enciende el LED
  22.                     EstadoTarea = 1' voy al siguiente caso
  23.                 Endif
  24.               CASE 1' Espero a que presionen el pulsador SW2 para empezar el retardo
  25.                    IF SW2=0  THEN
  26.                     ContadorPulsos = Pulsos' Capturo el valor de pulsos
  27.                     EstadoTarea = 2' voy al siguiente caso
  28.                 Endif
  29.               CASE 2' Espero que hayan pasado 20 pulsos (20 pulsos x 0.1s = 2 segundos)
  30.                  IF ((Pulsos- ContadorPulsos) > 20) THEN
  31.                               LOWLED' apago el led
  32.                               EstadoTarea = 0' regreso al primer estado
  33.                 Endif
  34.         EndSelect
  35. GOTO Lazo:

Te salió un código muy elegante  ((:-))
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 10 de Septiembre de 2022, 12:49:36
Aparte de lo anterior, el código que pusiste antes está como imagen, por lo que no puedo copiarlo y pegarlo en mi IDE.
De todas formas lo he probado y si me funciona, aunque este código solo es un ejemplo y no hace exactamente lo que quieres.

Dogflu66, gracias por estar pendiente con la resolución de este tema.
El código que mencionas que está como imagen, no es si no, el código que tu sugeriste en el post #23  y que yo solo lo adapté a PBP.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 10 de Septiembre de 2022, 13:10:11
Entiendo que pulsas una tecla y pasado un tiempo se actualiza el estado del led.
Una tecla es para activarlo y la otra tecla para apagarlo.
Todo esto sin afectar al flujo del programa.
¿Estoy en lo cierto?.

Bien como he mencionado en el título de este tema, son dos  tareas:
1.-  On Delay, es decir, presiono el botón rápidamente una sola vez y después de unos segundos (1, 2 o n segundos) se enciende el LED.
2.- Off Delay, es decir, es decir presiono el botón rápidamente una sola vez y transcurridos  (1, 2 o n segundos) el LED que estaba encendido, se apaga.
Saludos!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 10 de Septiembre de 2022, 13:23:27
Si tu dices que te funciona bien el código que has realizado, como dice don  dogflu66, debes realizar un conteo mas preciso, digamos milisegundos, pero aceptemos tu código y utilicemos décimas de segundo, entonces tu código de la interrupción quedaría así:

DominusDRR, Soy una persona adulta, y si digo que he logrado obtener retardos por desborde del timer, es porque es así.
No sé por qué tanta desconfianza en mi capacidad para lograr hacer un retardo con el timer del PIC.
Antes de lograrlo tuve que como muchos de ustedes, leer bastante teoría y con pruebas sucesivas y en orden de complejidad aprender a hacerlo.
He buscado mucho sobre los temas de retardos On Delay y Off Delay, pero hay poquísima información sobre el tema en lo que a lenguaje Basic para PICs se refiere, en cambio para lenguaje "C" logré encontrar algo pero como no estoy familiarizado con ese lenguaje, me resulta indescifrable.
Saludos!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 10 de Septiembre de 2022, 13:29:44

DominusDRR, Soy una persona adulta, y si digo que he logrado obtener retardos por desborde del timer, es porque es así.
No sé por qué tanta desconfianza en mi capacidad para lograr hacer un retardo con el timer del PIC.
Saludos!


No es desconfianza, solamente quería indicar lo que dice dogflu66, se debe contar milisegundos y en función de eso obtener tiempos más grandes como segundos.

Lamento mucho si hubo un mal entendido cultural. También tengo varios años trabajando en sistemas embebidos y comprendo que a veces toma tiempo comprender conceptos nuevos y/o complejos.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: Eduardo2 en 10 de Septiembre de 2022, 15:32:26
...
Bien como he mencionado en el título de este tema, son dos  tareas:
1.-  On Delay, es decir, presiono el botón rápidamente una sola vez y después de unos segundos (1, 2 o n segundos) se enciende el LED.
2.- Off Delay, es decir, es decir presiono el botón rápidamente una sola vez y transcurridos  (1, 2 o n segundos) el LED que estaba encendido, se apaga.
Saludos!

Habiendo leido que no podías usar PAUSE ;) , una manera de hacerlo es mediante una interrupción periódica que maneje contadores descendentes que al llegar a 0 ejecuten lo que corresponda.
Cuando se utilizan períodos de 1ms, 10ms etc , la cuenta inicial son el número de milisegiundos, centésimas de segundos etc. Pero cuando no lo es no pasa nada porque lo que se introduce es el número de períodos.

Por ejemplo:
Declaro un par de contadores para los contadores y las cuentas para 1,2 segundos (o mas)
Código: [Seleccionar]
T1s CON 1*61    ; Conteos para 1seg con interrupciones cada 16.384ms
                ; T2s : 1*(1000/16.384) = 61
T1 VAR WORD     ; Variable que lleva el conteo

T2s CON 2*61    ; Conteos para 2seg con interrupciones cada 16.384ms
                ; T2s : 2*(1000/16.384) = 122
T2 VAR WORD     ; Variable que lleva el conteo

Y mas adelante
Código: [Seleccionar]
............
Main:
    IF SW1=0  THEN T1=T1s  ;Con T1>0 se dispara el conteo
                           ;La cuenta es descendente y en 0 activa el led
   
    IF SW2=0  THEN T2=T2s  ;Con T2>0 se dispara el conteo
                           ;La cuenta es descendente y en 0 desactiva el led
    Goto Main
 
interpt: 
    disable   
   
    if T1>0 then               
        T1 = T1-1
        if T1=0 then HIgh LED1
    endif
   
    if T2>0 then               
        T2 = T2-1
        if T2=0 then LOW LED1
    endif
   
    INTCON.2 = 0    ' Reset timer interrupt flag
    resume
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 10 de Septiembre de 2022, 16:15:44

DominusDRR, Soy una persona adulta, y si digo que he logrado obtener retardos por desborde del timer, es porque es así.
No sé por qué tanta desconfianza en mi capacidad para lograr hacer un retardo con el timer del PIC.
Saludos!


No es desconfianza, solamente quería indicar lo que dice dogflu66, se debe contar milisegundos y en función de eso obtener tiempos más grandes como segundos.

Lamento mucho si hubo un mal entendido cultural. También tengo varios años trabajando en sistemas embebidos y comprendo que a veces toma tiempo comprender conceptos nuevos y/o complejos.

No hay Problema!
El caso es que estamos siendo redundantes con el asunto del retardo.
Bueno espero que con la siguiente información, ese asunto lo demos por sentado.
Bien, al emplear el  PIC 16F628A y su Timer1 de 16 bits, para obtener desbordes cada 100 milisegundos, deberé hacer una precarga de 53036 con oscilador de 4 MHz y un prescaler de 1:8.
Entonces si cuento diez desbordes de 100 ms obtendré 1sg.
Lo que a partir de este momento deberíamos tratar debería ser cómo ingeniarnos para valiendonos de los retardos obtenidos, implementar  los temporizadores On Delay y Off Delay que estoy seguro serán de utilidad para muchos.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 10 de Septiembre de 2022, 16:23:04
No había leído que necesitabas un ON delay al presionar SW1, en el caso que ocupes mi código, se necesita un estado adicional a la tarea

Código: QBasic/QuickBASIC
  1. Main:
  2.        EstadoTarea = 0x00;' Inicializo EstadoTarea
  3.         LOWLED1' apago el led inicialmente
  4. Lazo:
  5.         SELECT CASE EstadoTarea
  6.               CASE 0 ' en case 0, se espera a que presionen sw1
  7.                  IF SW1=0  THEN
  8.                     ContadorPulsos = Pulsos' Capturo el valor de pulsos
  9.                     EstadoTarea = 1' voy al siguiente caso
  10.                 Endif
  11.               CASE 1
  12.                      IF ((Pulsos- ContadorPulsos) > 10) THEN' espero ha que pase 1 segundo
  13.                               HIGH LED1    
  14.                               EstadoTarea = 2
  15.                      Endif
  16.               CASE 2' Espero a que presionen el pulsador SW2 para empezar el retardo
  17.                    IF SW2=0  THEN
  18.                     ContadorPulsos = Pulsos' Capturo el valor de pulsos, nuevamente
  19.                     EstadoTarea = 3' voy al siguiente caso
  20.                 Endif
  21.               CASE 3' Espero que hayan pasado 20 pulsos (20 pulsos x 0.1s = 2 segundos)
  22.                  IF ((Pulsos- ContadorPulsos) > 20) THEN
  23.                               LOWLED' apago el led
  24.                               EstadoTarea = 0' regreso al primer estado
  25.                 Endif
  26.         EndSelect
  27. GOTO Lazo:
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 10 de Septiembre de 2022, 16:30:32
...
Bien como he mencionado en el título de este tema, son dos  tareas:
1.-  On Delay, es decir, presiono el botón rápidamente una sola vez y después de unos segundos (1, 2 o n segundos) se enciende el LED.
2.- Off Delay, es decir, es decir presiono el botón rápidamente una sola vez y transcurridos  (1, 2 o n segundos) el LED que estaba encendido, se apaga.
Saludos!

Habiendo leido que no podías usar PAUSE ;) , una manera de hacerlo es mediante una interrupción periódica que maneje contadores descendentes que al llegar a 0 ejecuten lo que corresponda.
Cuando se utilizan períodos de 1ms, 10ms etc , la cuenta inicial son el número de milisegiundos, centésimas de segundos etc. Pero cuando no lo es no pasa nada porque lo que se introduce es el número de períodos.

Por ejemplo:
Declaro un par de contadores para los contadores y las cuentas para 1,2 segundos (o mas)
Código: [Seleccionar]
T1s CON 1*61    ; Conteos para 1seg con interrupciones cada 16.384ms
                ; T2s : 1*(1000/16.384) = 61
T1 VAR WORD     ; Variable que lleva el conteo

T2s CON 2*61    ; Conteos para 2seg con interrupciones cada 16.384ms
                ; T2s : 2*(1000/16.384) = 122
T2 VAR WORD     ; Variable que lleva el conteo

Y mas adelante
Código: [Seleccionar]
............
Main:
    IF SW1=0  THEN T1=T1s  ;Con T1>0 se dispara el conteo
                           ;La cuenta es descendente y en 0 activa el led
   
    IF SW2=0  THEN T2=T2s  ;Con T2>0 se dispara el conteo
                           ;La cuenta es descendente y en 0 desactiva el led
    Goto Main
 
interpt: 
    disable   
   
    if T1>0 then               
        T1 = T1-1
        if T1=0 then HIgh LED1
    endif
   
    if T2>0 then               
        T2 = T2-1
        if T2=0 then LOW LED1
    endif
   
    INTCON.2 = 0    ' Reset timer interrupt flag
    resume
Eduardo, muchas gracias por tu aporte, todo suma, dice el dicho, lo voy a analizar detenidamente.
No sé si tú ya lo probaste.
El inconveniente, es que en la subrutina de interupción no se debe colocar más código del necesario, para no interferir con la precisión de la temporización.
Te imaginas tener que poner 64 botones con su respectivo LED y resto de código en esa parte?
Saludos cordiales!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 10 de Septiembre de 2022, 16:33:01
No había leído que necesitabas un ON delay al presionar SW1, en el caso que ocupes mi código, se necesita un estado adicional a la tarea

Pero si ese es el título del tema!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 10 de Septiembre de 2022, 16:41:50
No había leído que necesitabas un ON delay al presionar SW1, en el caso que ocupes mi código, se necesita un estado adicional a la tarea

Pero si ese es el título del tema!

La animación que pusiste da la sensación de eso, ya que cuando presionas el pulsador SW1, el LED se enciende inmediatamente, solo se notaba retardo al pagarlo, es decir parecía sólo un TOFF.

Asumí que querías implementar eso primero y luego hacer el TON.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: Eduardo2 en 10 de Septiembre de 2022, 17:02:57
...
Eduardo, muchas gracias por tu aporte, todo suma, dice el dicho, lo voy a analizar detenidamente.
No sé si tú ya lo probaste.
De probarlo debía ser inventándome un hardware con algún micro y el resto del software, porque el hilo ya tiene 3 páginas y todavía no fuiste capaz de subir un código compilable (aunque funcione mal) y recién hace pocos mensajes dijiste que micro usabas.  Algo que deberías haber hecho en el 1er mensaje.

Citar
El inconveniente, es que en la subrutina de interupción no se debe colocar más código del necesario, para no interferir con la precisión de la temporización.
Te imaginas tener que poner 64 botones con su respectivo LED y resto de código en esa parte?
A ver, cuando se tienen 2,3...10 botones y solo se activa desactiva un led el procedimiento es obviamente diferente que cuando se tienen 64 botones que activan rutinas complejas.
Sería bueno que explique bien lo que tenés y querés hacer en lugar de escribir lo mínimo y dar detalles gradualmente.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 10 de Septiembre de 2022, 17:08:29
...
Eduardo, muchas gracias por tu aporte, todo suma, dice el dicho, lo voy a analizar detenidamente.
No sé si tú ya lo probaste.
De probarlo debía ser inventándome un hardware con algún micro y el resto del software, porque el hilo ya tiene 3 páginas y todavía no fuiste capaz de subir un código compilable (aunque funcione mal) y recién hace pocos mensajes dijiste que micro usabas.  Algo que deberías haber hecho en el 1er mensaje.

Citar
El inconveniente, es que en la subrutina de interupción no se debe colocar más código del necesario, para no interferir con la precisión de la temporización.
Te imaginas tener que poner 64 botones con su respectivo LED y resto de código en esa parte?
A ver, cuando se tienen 2,3...10 botones y solo se activa desactiva un led el procedimiento es obviamente diferente que cuando se tienen 64 botones que activan rutinas complejas.
Sería bueno que explique bien lo que tenés y querés hacer en lugar de escribir lo mínimo y dar detalles gradualmente.
No hace falta iventarse nada, solo simula en Proteus y listo.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 10 de Septiembre de 2022, 17:12:46
No había leído que necesitabas un ON delay al presionar SW1, en el caso que ocupes mi código, se necesita un estado adicional a la tarea

Pero si ese es el título del tema!

La animación que pusiste da la sensación de eso, ya que cuando presionas el pulsador SW1, el LED se enciende inmediatamente, solo se notaba retardo al pagarlo, es decir parecía sólo un TOFF.

Asumí que querías implementar eso primero y luego hacer el TON.
Tienes razón, faltó comentar lo suficiente en la animación.
Si, en realidad lo que busco es implementar con el PIC es los dos tipos de retardo, retardo en la conexión y retardo en la desconexión.
Gracias por tu ayuda y paciencia.
Saludos!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: dogflu66 en 10 de Septiembre de 2022, 18:18:29
Bueno este ejemplo hace lo que pedias inicialmente, lo he probado y funciona, otro problema será que lo puedas adaptar a tu lenguaje.
Y si necesitas controlar grandes cantidades de led el software como el hardware cambian. Pero bueno, por algo hay que comenzar.
Te dejo el código completo:

Código: QBasic/QuickBASIC
  1. 'Pic16F628A, oscilador interno 4Mhz
  2. 'Configuración de fuses
  3. #define CONFIG = 0x3f50
  4. Define CLOCK_FREQUENCY = 4  'Oscilador a 4Mhz
  5. 'Include "_FuncionesPic16F628A.bas"
  6. 'Include "_FunctionesTmrBase.bas"
  7. 'Call _setup_oscillator(_osc_4Mhz)
  8. PCON.OSCF = 1  'Oscilador interno 4Mhz
  9. 'Inicializa Timer1 para generar una interrupción cada 1mSeg.
  10. 'Call _setup_timer1(_tmr1_internal, _tmr1_div1)  'Configura TMR1 para 4Mhz
  11. T1CON = 0  'Asigna oscilador interno para el tmr1
  12. T1CON.T1CKPS1 = 0  'Asigna el divisor
  13. T1CON.T1CKPS0 = 0
  14. 'Call _set_timer1(0xfc17)  'Carga contador TMr1 para contar 1mSeg.
  15. T1CON.TMR1ON = 0  'Para el contador del TMR1
  16. TMR1H = 0xfc  'Recarga el byte alto
  17. TMR1L = 0x17  'Recarga el byte bajo
  18. T1CON.TMR1ON = 1  'Activa el contador del TMR1
  19. PIR1.TMR1IF = 0  'Flash dosborde a cero
  20. 'Call _timer1(_on)  'Pone en marcha el Tmr1
  21. T1CON.TMR1ON = 1  'Activa el contador del TMR1
  22. 'Call _enable_interrupts(_int_timer1)  'Permite las interrupciones por desborde Tmr1
  23. PIE1.TMR1IE = 1  'Permite la interrup. TIMER1
  24. 'Call _enable_interrupts(_global)  'Permte las interrupciones globales
  25. INTCON.PEIE = 1  'Bit habilita interrupciones perifericos
  26. Enable  'INTCON.GIE habilita las interrupciones
  27. '************************************************************
  28. AllDigital
  29. ConfigPin RB0 = OUTPUT
  30. ConfigPin RB1 = OUTPUT
  31. ConfigPin RB2 = OUTPUT
  32. ConfigPin RA2 = INPUT
  33. ConfigPin RA3 = INPUT
  34. Symbol led1 = RB0
  35. Symbol led2 = RB1
  36. Symbol sw1 = RA2
  37. Symbol sw2 = RA3
  38.  
  39. 'Contadores para generar las bases de tiempos.
  40. DIM _contador1 AS LONG
  41. DIM _contador2 AS LONG
  42. _contador1 = 0
  43. _contador2 = 0
  44. 'Flag de control
  45. DIM flag1 AS Bit
  46. DIM flag2 AS Bit
  47. flag1 = 0
  48. flag2 = 0
  49. WaitMs 20
  50. Main:
  51.  
  52.         'Temporizador no redisparable, para redisparable quitar flag1 = 0
  53.         'Para ser bloqueado por el anterior añadir "and flag2 = 0"
  54.         IF sw1 = 0 AND flag1 = 0 THEN
  55.                 _contador1 = 1000
  56.                 flag1 = 1
  57.         ELSE
  58.                 IF _contador1 = 0 AND flag1 = 1 THEN
  59.                         High led1
  60.                         flag1 = 0
  61.                 Endif
  62.         Endif
  63.         'Temporizador no redisparable, para redisparable quitar flag2 = 0
  64.         'Para ser bloqueado por el anterior añadir "and flag1 = 0"
  65.         IF sw2 = 0 AND flag2 = 0 THEN
  66.                 _contador1 = 2000
  67.                 flag2 = 1
  68.         ELSE
  69.                 IF _contador1 = 0 AND flag2 = 1 THEN
  70.                         Low led1
  71.                         flag2 = 0
  72.                 Endif
  73.         Endif
  74.        
  75.         IF _contador2 = 0 THEN
  76.                 Toggle RB2
  77.                 _contador2 = 10
  78.         Endif
  79.        
  80. GOTO Main
  81. END                                              
  82. '****************************
  83. ON Interrupt
  84.         Save SYSTEM  'Guarda calculos intermedios y otros del sistema
  85.         'Detecta interrupción Timer1
  86.         IF PIR1.TMR1IF = 1 THEN
  87.                 'Call _set_timer1(0xfc17)  'Recarga registros TMR1 para desborde 1mSeg. y borra PIR1.TMR1IF
  88.                 T1CON.TMR1ON = 0  'Para el contador del TMR1
  89.                 TMR1H = 0xfc  'Recarga el contador byte alto
  90.                 TMR1L = 0x17  'Recarga el contador byte bajo
  91.                 T1CON.TMR1ON = 1  'Activa el contador del TMR1
  92.                 PIR1.TMR1IF = 0  'Flash dosborde a cero
  93.                 IF _contador1 > 0 THEN _contador1 = _contador1 - 1  '_contador BT
  94.                 IF _contador2 > 0 THEN _contador2 = _contador2 - 1  '_contador BT
  95.         Endif
  96. RESUME                                            
  97. '******************************
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 10 de Septiembre de 2022, 19:15:38
Estimados amigos, pido disculpas si no puse la información suficiente para tratar este tema.
A manera de rectificación quiero indicar que el PIC que estoy utilizando es el 16F628A.
El código que indiqué anteriormente es una adaptación del código que tan gentilmente me proporcionó dogflu66 y que yo lo adapté al PBP, lo subí en formato de imagen pensando que era más práctico a la hora de visualizarlo, a continuación lo pongo en formato de texto.

Código:

@ __config _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _BODEN_OFF & _LVP_OFF & _WDT_OFF &

_PWRTE_OFF

Define OSC 4
CMCON = 7
 
Precarga    Var Word         
_contador1  Var Word
_contador2  Var Word                           

   
Symbol LED1 = PORTB.0
Symbol LED2 = PORTB.1
Symbol SW1 = PORTA.2
Symbol SW2 = PORTA.3

TRISA=%11111111                   
TRISB=%00000000
                 
PORTB=0
LED1 = 0
LED2 = 0
_contador1 = 0
_contador2 = 0               
   
   T1CON = %00111101         
   Precarga = 53036           'para obtener desbordes de 100ms         
   TMR1H = Precarga.HighByte  'Precargar el byte alto   
   TMR1L = Precarga.LowByte   'Precargar el byte bajo   
   PIE1.0 = 1               'Habilita la interrupción por

desborde       
   INTCON = %11000000         'Habilita interrupciones globales y periféricas
   
   
   On Interrupt GoTo Interrupcion

Inicio:
        
        IF sw1 = 0 AND _contador1 = 0 THEN
                High led1 
                _contador1 = 1100  'Carga contador con 1Seg.
        Endif
 
        IF sw2 = 0 AND _contador2 = 0 THEN
                Low led1  ;
                _contador2 = 2000  'Carga contador con 2Seg.
        Endif
   
GoTo   Inicio:
   
Interrupcion:
   Disable
   
   If PIR1.0 = 1 Then         ; Ocurrió un desborde del Timer 1
               'Call _set_timer1(0xfc17)  'Recarga registros TMR1 para

desborde 1mSeg. y borra PIR1.TMR1IF
                T1CON.0 = 0  'Para el contador del TMR1
                TMR1H = Precarga.HighByte 'Recarga el contador byte alto
                TMR1L = Precarga.LowByte  'Recarga el contador byte bajo
                T1CON.0 = 1  'Activa el contador del TMR1
                PIR1.0 = 0    'Flash dosborde a cero
                IF _contador1 > 0 THEN _contador1 = _contador1 - 1  '_contador BT
                IF _contador2 > 0 THEN _contador2 = _contador2 - 1  '_contador BT   

         
                            
   EndIf
   
   Resume
   Enable


   End

Grcias por su comprensión.
Saludos!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 10 de Septiembre de 2022, 19:23:59
dogflu66 y Eduardo2 , muchas gracias por los códigos proporcionados, en pocos momentos los voy a probar y estaré comentando los resultados.
Gracias nuevamente,
Sinceramente,
Okapi
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 10 de Septiembre de 2022, 20:09:10
Bueno este ejemplo hace lo que pedias inicialmente, lo he probado y funciona, otro problema será que lo puedas adaptar a tu lenguaje.
Y si necesitas controlar grandes cantidades de led el software como el hardware cambian. Pero bueno, por algo hay que comenzar.
Te dejo el código completo:

Código: QBasic/QuickBASIC
  1. 'Pic16F628A, oscilador interno 4Mhz
  2. 'Configuración de fuses
  3. #define CONFIG = 0x3f50
  4. Define CLOCK_FREQUENCY = 4  'Oscilador a 4Mhz
  5. 'Include "_FuncionesPic16F628A.bas"
  6. 'Include "_FunctionesTmrBase.bas"
  7. 'Call _setup_oscillator(_osc_4Mhz)
  8. PCON.OSCF = 1  'Oscilador interno 4Mhz
  9. 'Inicializa Timer1 para generar una interrupción cada 1mSeg.
  10. 'Call _setup_timer1(_tmr1_internal, _tmr1_div1)  'Configura TMR1 para 4Mhz
  11. T1CON = 0  'Asigna oscilador interno para el tmr1
  12. T1CON.T1CKPS1 = 0  'Asigna el divisor
  13. T1CON.T1CKPS0 = 0
  14. 'Call _set_timer1(0xfc17)  'Carga contador TMr1 para contar 1mSeg.
  15. T1CON.TMR1ON = 0  'Para el contador del TMR1
  16. TMR1H = 0xfc  'Recarga el byte alto
  17. TMR1L = 0x17  'Recarga el byte bajo
  18. T1CON.TMR1ON = 1  'Activa el contador del TMR1
  19. PIR1.TMR1IF = 0  'Flash dosborde a cero
  20. 'Call _timer1(_on)  'Pone en marcha el Tmr1
  21. T1CON.TMR1ON = 1  'Activa el contador del TMR1
  22. 'Call _enable_interrupts(_int_timer1)  'Permite las interrupciones por desborde Tmr1
  23. PIE1.TMR1IE = 1  'Permite la interrup. TIMER1
  24. 'Call _enable_interrupts(_global)  'Permte las interrupciones globales
  25. INTCON.PEIE = 1  'Bit habilita interrupciones perifericos
  26. Enable  'INTCON.GIE habilita las interrupciones
  27. '************************************************************
  28. AllDigital
  29. ConfigPin RB0 = OUTPUT
  30. ConfigPin RB1 = OUTPUT
  31. ConfigPin RB2 = OUTPUT
  32. ConfigPin RA2 = INPUT
  33. ConfigPin RA3 = INPUT
  34. Symbol led1 = RB0
  35. Symbol led2 = RB1
  36. Symbol sw1 = RA2
  37. Symbol sw2 = RA3
  38.  
  39. 'Contadores para generar las bases de tiempos.
  40. DIM _contador1 AS LONG
  41. DIM _contador2 AS LONG
  42. _contador1 = 0
  43. _contador2 = 0
  44. 'Flag de control
  45. DIM flag1 AS Bit
  46. DIM flag2 AS Bit
  47. flag1 = 0
  48. flag2 = 0
  49. WaitMs 20
  50. Main:
  51.  
  52.         'Temporizador no redisparable, para redisparable quitar flag1 = 0
  53.         'Para ser bloqueado por el anterior añadir "and flag2 = 0"
  54.         IF sw1 = 0 AND flag1 = 0 THEN
  55.                 _contador1 = 1000
  56.                 flag1 = 1
  57.         ELSE
  58.                 IF _contador1 = 0 AND flag1 = 1 THEN
  59.                         High led1
  60.                         flag1 = 0
  61.                 Endif
  62.         Endif
  63.         'Temporizador no redisparable, para redisparable quitar flag2 = 0
  64.         'Para ser bloqueado por el anterior añadir "and flag1 = 0"
  65.         IF sw2 = 0 AND flag2 = 0 THEN
  66.                 _contador1 = 2000
  67.                 flag2 = 1
  68.         ELSE
  69.                 IF _contador1 = 0 AND flag2 = 1 THEN
  70.                         Low led1
  71.                         flag2 = 0
  72.                 Endif
  73.         Endif
  74.        
  75.         IF _contador2 = 0 THEN
  76.                 Toggle RB2
  77.                 _contador2 = 10
  78.         Endif
  79.        
  80. GOTO Main
  81. END                                              
  82. '****************************
  83. ON Interrupt
  84.         Save SYSTEM  'Guarda calculos intermedios y otros del sistema
  85.         'Detecta interrupción Timer1
  86.         IF PIR1.TMR1IF = 1 THEN
  87.                 'Call _set_timer1(0xfc17)  'Recarga registros TMR1 para desborde 1mSeg. y borra PIR1.TMR1IF
  88.                 T1CON.TMR1ON = 0  'Para el contador del TMR1
  89.                 TMR1H = 0xfc  'Recarga el contador byte alto
  90.                 TMR1L = 0x17  'Recarga el contador byte bajo
  91.                 T1CON.TMR1ON = 1  'Activa el contador del TMR1
  92.                 PIR1.TMR1IF = 0  'Flash dosborde a cero
  93.                 IF _contador1 > 0 THEN _contador1 = _contador1 - 1  '_contador BT
  94.                 IF _contador2 > 0 THEN _contador2 = _contador2 - 1  '_contador BT
  95.         Endif
  96. RESUME                                            
  97. '******************************
Estimado dogflu, agradezco mucho tu tiempo invertido para ayudarme a vencer esta dificultad de los Temporizadores, en verdad es muy amable de tu parte.
Te comento que he adaptado a PBP el código que enviaste, lo revisé de arriba hacia abajo, para ver si cometí algún error, pero todo está correcto, sin embargo solo funciona la parte que dice toggle RB2 que en PBP es toggle portb.2, el resto no trabaja, es decir, presiono SW1 y no enciende el led.
habilité y des-habilité el ENABLE de la rutina de interrupción, y tampoco funcionó.
No tengo duda de que con el lenguaje que tu usas funcione, pero hay algún detallito que le hace falta a PBP para que funcione.
Por si acaso, adjunto el código en formato de texto.
Gran saludo!

Código:

@ __config _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _BODEN_OFF & _LVP_OFF & _WDT_OFF & _PWRTE_OFF
;*******************************************************************************
Define OSC 4
CMCON = 7
Precarga   Var Word         
_contador1  Var Word
_contador2   Var Word               
flag1   Var Bit   
flag2   Var Bit   
flag1 = 0
flag2 = 0
pAUSE 20         
TRISA=%11111111                   
TRISB=%00000000
Symbol LED1 = PORTB.0
Symbol LED2 = PORTB.1
Symbol SW1 = PORTA.2
Symbol SW2 = PORTA.3
                 
PORTB=0
LED1 = 0
LED2 = 0
_contador1 = 0
_contador2 = 0               
   
   T1CON = %00111101         
   Precarga = 40536         
   TMR1H = Precarga.HighByte  'Precargar el byte alto   
   TMR1L = Precarga.LowByte   'Precargar el byte bajo   
   PIE1.0 = 1               'Habilita la interrupción por desborde       
   INTCON = %11000000         'Habilita interrupciones globales y periféricas
   
   'Completado = 0            ; bandera en 0
   
   On Interrupt GoTo Interrupcion

Inicio:
        
        'Temporizador no redisparable, para redisparable quitar flag1 = 0
        'Para ser bloqueado por el anterior añadir "and flag2 = 0"
        IF sw1 = 0 AND flag1 = 0 THEN
                _contador1 = 1000
                flag1 = 1
        ELSE
                IF _contador1 = 0 AND flag1 = 1 THEN
                        High led1
                        flag1 = 0
                Endif
        Endif
        'Temporizador no redisparable, para redisparable quitar flag2 = 0
        'Para ser bloqueado por el anterior añadir "and flag1 = 0"
        IF sw2 = 0 AND flag2 = 0 THEN
                _contador1 = 2000
                flag2 = 1
        ELSE
                IF _contador1 = 0 AND flag2 = 1 THEN
                        Low led1
                        flag2 = 0
                Endif
        Endif
       
        IF _contador2 = 0 THEN
                Toggle PORTB.2
                _contador2 = 10
        Endif   
GoTo   Inicio:
   
Interrupcion:
   Disable
   
   If PIR1.0 = 1 Then         ; Ocurrió un desborde del Timer 1
               'Call _set_timer1(0xfc17)  'Recarga registros TMR1 para desborde 1mSeg. y borra PIR1.TMR1IF
                T1CON.0 = 0  'Para el contador del TMR1
                TMR1H = Precarga.HighByte 'Recarga el contador byte alto
                TMR1L = Precarga.LowByte  'Recarga el contador byte bajo
                T1CON.0 = 1  'Activa el contador del TMR1
                PIR1.0 = 0    'Flash dosborde a cero
                IF _contador1 > 0 THEN _contador1 = _contador1 - 1  '_contador BT
                IF _contador2 > 0 THEN _contador2 = _contador2 - 1  '_contador BT             
                 
                               
   EndIf
   
   Resume
   'Enable


   End
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 10 de Septiembre de 2022, 21:16:56
...
Bien como he mencionado en el título de este tema, son dos  tareas:
1.-  On Delay, es decir, presiono el botón rápidamente una sola vez y después de unos segundos (1, 2 o n segundos) se enciende el LED.
2.- Off Delay, es decir, es decir presiono el botón rápidamente una sola vez y transcurridos  (1, 2 o n segundos) el LED que estaba encendido, se apaga.
Saludos!

Habiendo leido que no podías usar PAUSE ;) , una manera de hacerlo es mediante una interrupción periódica que maneje contadores descendentes que al llegar a 0 ejecuten lo que corresponda.
Cuando se utilizan períodos de 1ms, 10ms etc , la cuenta inicial son el número de milisegiundos, centésimas de segundos etc. Pero cuando no lo es no pasa nada porque lo que se introduce es el número de períodos.

Por ejemplo:
Declaro un par de contadores para los contadores y las cuentas para 1,2 segundos (o mas)
Código: [Seleccionar]
T1s CON 1*61    ; Conteos para 1seg con interrupciones cada 16.384ms
                ; T2s : 1*(1000/16.384) = 61
T1 VAR WORD     ; Variable que lleva el conteo

T2s CON 2*61    ; Conteos para 2seg con interrupciones cada 16.384ms
                ; T2s : 2*(1000/16.384) = 122
T2 VAR WORD     ; Variable que lleva el conteo

Y mas adelante
Código: [Seleccionar]
............
Main:
    IF SW1=0  THEN T1=T1s  ;Con T1>0 se dispara el conteo
                           ;La cuenta es descendente y en 0 activa el led
   
    IF SW2=0  THEN T2=T2s  ;Con T2>0 se dispara el conteo
                           ;La cuenta es descendente y en 0 desactiva el led
    Goto Main
 
interpt: 
    disable   
   
    if T1>0 then               
        T1 = T1-1
        if T1=0 then HIgh LED1
    endif
   
    if T2>0 then               
        T2 = T2-1
        if T2=0 then LOW LED1
    endif
   
    INTCON.2 = 0    ' Reset timer interrupt flag
    resume

Eduardo 2, acabo de probar  tu código y  si funciona según lo especificado.
Es muy ingeniosa tu solución ((:-)) ((:-)) ((:-)).
Me resta agradecerte mucho, mucho, mucho, por tu generosidad al compartir tus conocimientos, invertir tu valioso tiempo y sobre todo por la paciencia para con este inexperto.
Ahora voy a buscar la manera de dejar lo mínimo del código posible en la subrutina de interrupción.
Nuevamente muchas gracias.
Mi saludo cordial!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 10 de Septiembre de 2022, 21:23:51
dogflu66, DominusDRR  y Eduardo2 , nuevamente un millón de gracias por su tiempo, dedicación y paciencia en la resolución de este problema que para expertos como ustedes se transformó en un reto.
De verdad muchas gracias!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 10 de Septiembre de 2022, 21:28:56
Amigos del foro, sé que en programación hay muchas maneras de resolver un  mismo problema, por tal motivo si alguien tiene otra solución o quiere aportar algo más sobre el tema, bienvenido sea.
Gracias anticipadas!
Saludos!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 10 de Septiembre de 2022, 23:36:21
Amigos del foro, sé que en programación hay muchas maneras de resolver un  mismo problema, por tal motivo si alguien tiene otra solución o quiere aportar algo más sobre el tema, bienvenido sea.
Gracias anticipadas!
Saludos!

Es que si nunca pruebas ninguno de los ejemplos que te ha proporcionado, o si los pruebas pero no muestras el error que generan al compilarlos o intentar simularlos, ningún ejemplo te va ser de utilidad.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: dogflu66 en 11 de Septiembre de 2022, 08:02:52
Prueba el código sin usar el timer y las interrupciones a ver si te funciona, por ir descartando.

Código: QBasic/QuickBASIC
  1. 'Pic16F628A, oscilador interno 4Mhz
  2. 'Configuración de fuses
  3. #define CONFIG = 0x3f50
  4. Define CLOCK_FREQUENCY = 4  'Oscilador a 4Mhz
  5. 'Include "_FuncionesPic16F628A.bas"
  6. 'Include "_FunctionesTmrBase.bas"
  7. 'Call _setup_oscillator(_osc_4Mhz)
  8. PCON.OSCF = 1  'Oscilador interno 4Mhz
  9. '************************************************************
  10. AllDigital
  11. ConfigPin RB0 = OUTPUT
  12. ConfigPin RB1 = OUTPUT
  13. ConfigPin RB2 = OUTPUT
  14. ConfigPin RA2 = INPUT
  15. ConfigPin RA3 = INPUT
  16. Symbol led1 = RB0
  17. Symbol led2 = RB1
  18. Symbol sw1 = RA2
  19. Symbol sw2 = RA3
  20.  
  21. 'Contadores para generar las bases de tiempos.
  22. DIM _contador1 AS LONG
  23. DIM _contador2 AS LONG
  24. _contador1 = 0
  25. _contador2 = 0
  26. 'Flag de control
  27. DIM flag1 AS Bit
  28. DIM flag2 AS Bit
  29. flag1 = 0
  30. flag2 = 0
  31. WaitMs 100
  32. Main:
  33.  
  34.         'Temporizador no redisparable, para redisparable quitar flag1 = 0
  35.         'Para ser bloqueado por el anterior añadir "and flag2 = 0"
  36.         IF sw1 = 0 AND flag1 = 0 THEN
  37.                 _contador1 = 100  '0
  38.                 flag1 = 1
  39.         ELSE
  40.                 IF _contador1 = 0 AND flag1 = 1 THEN
  41.                         High led1
  42.                         flag1 = 0
  43.                 Endif
  44.         Endif
  45.         'Temporizador no redisparable, para redisparable quitar flag2 = 0
  46.         'Para ser bloqueado por el anterior añadir "and flag1 = 0"
  47.         IF sw2 = 0 AND flag2 = 0 THEN
  48.                 _contador1 = 200  '0
  49.                 flag2 = 1
  50.         ELSE
  51.                 IF _contador1 = 0 AND flag2 = 1 THEN
  52.                         Low led1
  53.                         flag2 = 0
  54.                 Endif
  55.         Endif
  56.        
  57.         IF _contador2 = 0 THEN
  58.                 Toggle RB2
  59.                 _contador2 = 10
  60.         Endif
  61.        
  62.         WaitMs 1
  63.         IF _contador1 > 0 THEN _contador1 = _contador1 - 1  '_contador BT
  64.         IF _contador2 > 0 THEN _contador2 = _contador2 - 1  '_contador BT
  65.  
  66.        
  67. GOTO Main
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 11 de Septiembre de 2022, 09:33:25
Es que si nunca pruebas ninguno de los ejemplos que te ha proporcionado, o si los pruebas pero no muestras el error que generan al compilarlos o intentar simularlos, ningún ejemplo te va ser de utilidad.

Hola. No había leído que un código proporcionado, te ha funcionado como querías. Sólo leí tu último comentario y daba la sensación de que buscabas otro código de alguien más, parecía que ninguno te convencía.

Una última cosa que quería aportar es que a pesar que te funciona como esperabas, siempre piensa en que pasaría si suceden cosas absurdas o acciones que un usuario podría hacer (y aunque no lo creas suelen suceder).

Me refiero a que analices los siguientes casos:

¿Qué pasa si presiono al mismo tiempo ambos pulsadores?

¿Qué pasa si presiono SW1 y inmediatamente antes de cumplirse TON presiono SW2?

¿Qué pasa si mantengo presionado SW1 (ó SW2 o ambos a al vez)?

¿Tienes problemas con el rebote mecánico de los pulsadores?

Etc.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 11 de Septiembre de 2022, 11:42:46
Prueba el código sin usar el timer y las interrupciones a ver si te funciona, por ir descartando.

Código: QBasic/QuickBASIC
  1. 'Pic16F628A, oscilador interno 4Mhz
  2. 'Configuración de fuses
  3. #define CONFIG = 0x3f50
  4. Define CLOCK_FREQUENCY = 4  'Oscilador a 4Mhz
  5. 'Include "_FuncionesPic16F628A.bas"
  6. 'Include "_FunctionesTmrBase.bas"
  7. 'Call _setup_oscillator(_osc_4Mhz)
  8. PCON.OSCF = 1  'Oscilador interno 4Mhz
  9. '************************************************************
  10. AllDigital
  11. ConfigPin RB0 = OUTPUT
  12. ConfigPin RB1 = OUTPUT
  13. ConfigPin RB2 = OUTPUT
  14. ConfigPin RA2 = INPUT
  15. ConfigPin RA3 = INPUT
  16. Symbol led1 = RB0
  17. Symbol led2 = RB1
  18. Symbol sw1 = RA2
  19. Symbol sw2 = RA3
  20.  
  21. 'Contadores para generar las bases de tiempos.
  22. DIM _contador1 AS LONG
  23. DIM _contador2 AS LONG
  24. _contador1 = 0
  25. _contador2 = 0
  26. 'Flag de control
  27. DIM flag1 AS Bit
  28. DIM flag2 AS Bit
  29. flag1 = 0
  30. flag2 = 0
  31. WaitMs 100
  32. Main:
  33.  
  34.         'Temporizador no redisparable, para redisparable quitar flag1 = 0
  35.         'Para ser bloqueado por el anterior añadir "and flag2 = 0"
  36.         IF sw1 = 0 AND flag1 = 0 THEN
  37.                 _contador1 = 100  '0
  38.                 flag1 = 1
  39.         ELSE
  40.                 IF _contador1 = 0 AND flag1 = 1 THEN
  41.                         High led1
  42.                         flag1 = 0
  43.                 Endif
  44.         Endif
  45.         'Temporizador no redisparable, para redisparable quitar flag2 = 0
  46.         'Para ser bloqueado por el anterior añadir "and flag1 = 0"
  47.         IF sw2 = 0 AND flag2 = 0 THEN
  48.                 _contador1 = 200  '0
  49.                 flag2 = 1
  50.         ELSE
  51.                 IF _contador1 = 0 AND flag2 = 1 THEN
  52.                         Low led1
  53.                         flag2 = 0
  54.                 Endif
  55.         Endif
  56.        
  57.         IF _contador2 = 0 THEN
  58.                 Toggle RB2
  59.                 _contador2 = 10
  60.         Endif
  61.        
  62.         WaitMs 1
  63.         IF _contador1 > 0 THEN _contador1 = _contador1 - 1  '_contador BT
  64.         IF _contador2 > 0 THEN _contador2 = _contador2 - 1  '_contador BT
  65.  
  66.        
  67. GOTO Main
Buenos días dogflu66.
De acuerdo, voy a hacer lo que propones, ya te cuento cómo me fue.
Muchas gracias!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 11 de Septiembre de 2022, 11:50:55
Es que si nunca pruebas ninguno de los ejemplos que te ha proporcionado, o si los pruebas pero no muestras el error que generan al compilarlos o intentar simularlos, ningún ejemplo te va ser de utilidad.

Hola. No había leído que un código proporcionado, te ha funcionado como querías. Sólo leí tu último comentario y daba la sensación de que buscabas otro código de alguien más, parecía que ninguno te convencía.

Una última cosa que quería aportar es que a pesar que te funciona como esperabas, siempre piensa en que pasaría si suceden cosas absurdas o acciones que un usuario podría hacer (y aunque no lo creas suelen suceder).

Me refiero a que analices los siguientes casos:

¿Qué pasa si presiono al mismo tiempo ambos pulsadores?

¿Qué pasa si presiono SW1 y inmediatamente antes de cumplirse TON presiono SW2?

¿Qué pasa si mantengo presionado SW1 (ó SW2 o ambos a al vez)?

¿Tienes problemas con el rebote mecánico de los pulsadores?

Etc.
DominusDRR
No te preocupes.
En cuanto a las cosas absurdas que los usuarios suelen hacer, tienes toda la razón, es algo para tener muy en cuenta, lo tendré presente si tengo alguna novedad, estaré comentando inmediatamente.
Saludos!
Gracias por tu valiosa ayuda.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 11 de Septiembre de 2022, 17:57:03
Prueba el código sin usar el timer y las interrupciones a ver si te funciona, por ir descartando.

Estimado amigo dogflu66, ya realicé lo que me recomendaste, pero tampoco funciona.
Qué podrá ser?
Seguiré intentando.
Muchas gracias.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 11 de Septiembre de 2022, 18:03:22
Prueba el código sin usar el timer y las interrupciones a ver si te funciona, por ir descartando.

Estimado amigo dogflu66, ya realicé lo que me recomendaste, pero tampoco funciona.
Qué podrá ser?
Seguiré intentando.
Muchas gracias.

Deberías compartir el proyecto con ese código para que te ayuden a determinar cual es el error.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 11 de Septiembre de 2022, 18:04:45
Es que si nunca pruebas ninguno de los ejemplos que te ha proporcionado, o si los pruebas pero no muestras el error que generan al compilarlos o intentar simularlos, ningún ejemplo te va ser de utilidad.

Hola. No había leído que un código proporcionado, te ha funcionado como querías. Sólo leí tu último comentario y daba la sensación de que buscabas otro código de alguien más, parecía que ninguno te convencía.
No hay problema.

Una última cosa que quería aportar es que a pesar que te funciona como esperabas, siempre piensa en que pasaría si suceden cosas absurdas o acciones que un usuario podría hacer (y aunque no lo creas suelen suceder).

Me refiero a que analices los siguientes casos:

¿Qué pasa si presiono al mismo tiempo ambos pulsadores?

¿Qué pasa si presiono SW1 y inmediatamente antes de cumplirse TON presiono SW2?

¿Qué pasa si mantengo presionado SW1 (ó SW2 o ambos a al vez)?

¿Tienes problemas con el rebote mecánico de los pulsadores?

Etc.
Estimado Dominus DRR, tenías razón, he tropezado con un inconveniente en el código y justamente es que al mantener presionado el pulsador, no se activa el LED, sino hasta que se lo suelte.
Gracias por los consejos muy oportunos.
saludos!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 11 de Septiembre de 2022, 18:08:40
Prueba el código sin usar el timer y las interrupciones a ver si te funciona, por ir descartando.

Estimado amigo dogflu66, ya realicé lo que me recomendaste, pero tampoco funciona.
Qué podrá ser?
Seguiré intentando.
Muchas gracias.

Deberías compartir el proyecto con ese código para que te ayuden a determinar cual es el error.

Si, ahora lo tengo y entendí que eso es lo primordial, a propósito tal vez sabes tú si está permitido subir archivos de simulación de Proteus?
Muchas gracias!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 11 de Septiembre de 2022, 18:10:02
Es que si nunca pruebas ninguno de los ejemplos que te ha proporcionado, o si los pruebas pero no muestras el error que generan al compilarlos o intentar simularlos, ningún ejemplo te va ser de utilidad.

Hola. No había leído que un código proporcionado, te ha funcionado como querías. Sólo leí tu último comentario y daba la sensación de que buscabas otro código de alguien más, parecía que ninguno te convencía.
No hay problema.

Una última cosa que quería aportar es que a pesar que te funciona como esperabas, siempre piensa en que pasaría si suceden cosas absurdas o acciones que un usuario podría hacer (y aunque no lo creas suelen suceder).

Me refiero a que analices los siguientes casos:

¿Qué pasa si presiono al mismo tiempo ambos pulsadores?

¿Qué pasa si presiono SW1 y inmediatamente antes de cumplirse TON presiono SW2?

¿Qué pasa si mantengo presionado SW1 (ó SW2 o ambos a al vez)?

¿Tienes problemas con el rebote mecánico de los pulsadores?

Etc.
Estimado Dominus DRR, tenías razón, he tropezado con un inconveniente en el código y justamente es que al mantener presionado el pulsador, no se activa el LED, sino hasta que se lo suelte.
Gracias por los consejos muy oportunos.
saludos!



Piensa en procesos recurrentes como el ejemplo que escribí, ahí podrías crear une estado para esperar que el usuario suelte el pulsante para empezar los procesos.

Así se diseñan los sistemas con pulsantes o botones. hasta en software, cuando pulsas un botón el ratón del computador, se ejecuta el proceso al soltarlo, no al presionarlo.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 11 de Septiembre de 2022, 18:11:22
Prueba el código sin usar el timer y las interrupciones a ver si te funciona, por ir descartando.

Estimado amigo dogflu66, ya realicé lo que me recomendaste, pero tampoco funciona.
Qué podrá ser?
Seguiré intentando.
Muchas gracias.

Deberías compartir el proyecto con ese código para que te ayuden a determinar cual es el error.

Si, ahora lo tengo y entendí que eso es lo primordial, a propósito tal vez sabes tú si está permitido subir archivos de simulación de Proteus?
Muchas gracias!

Si, no hay problema en compartir un proyecto, Suelen subirlo a google drive o alguno similar.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 11 de Septiembre de 2022, 18:36:34
Estimados amigos del foro de Basic par PIC, adjunto envío los archivos necesarios para el proyecto de temporizadores On Delay y Off Delay con el fin poder analizarlo y mejorarlo de ser posible.
El código lo tenemos gracias al compañero Eduardo2 qué es quien nos proporcionó.
En este momento el inconveniente que tiene este temporizador es que si se mantiene presionado el pulsador, el LED no llega a encenderse, sino hasta que el pulsador sea soltado, lo que no sucede con un Timer On Delay real que es lo que se pretende emular.
Ojalá juntos podamos resolverlo.
Saludos a todos!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 11 de Septiembre de 2022, 18:59:31
Estimados amigos del foro de Basic par PIC, adjunto envío los archivos necesarios para el proyecto de temporizadores On Delay y Off Delay con el fin poder analizarlo y mejorarlo de ser posible.
El código lo tenemos gracias al compañero Eduardo2 qué es quien nos proporcionó.
En este momento el inconveniente que tiene este temporizador es que si se mantiene presionado el pulsador, el LED no llega a encenderse, sino hasta que el pulsador sea soltado, lo que no sucede con un Timer On Delay real que es lo que se pretende emular.
Ojalá juntos podamos resolverlo.
Saludos a todos!

me he atrevido a modificar el código de don Eduardo2 para usarlo como tarea de estados:

Código: QBasic/QuickBASIC
  1. _1000_ms CON 1*61    ; Conteos para 1seg con interrupciones cada 16.384ms
  2.                 ; T2s : 1*(1000/16.384) = 61
  3.  
  4.  
  5. _2000_ms CON 2*61    ; Conteos para 2seg con interrupciones cada 16.384ms
  6.                 ; T2s : 2*(1000/16.384) = 122
  7.                
  8. Pulsos VAR BYTE  
  9. ContadorPulsos VAR BYTE
  10.  
  11.  
  12. ESPERAR_PRESIONAR_SW1 CON   0
  13. ESPERAR_SOLTAR_SW1 CON      1
  14. CAPTURAR_PULSOS_PARA_TON    2
  15. ESPERAR_TON                 3
  16. ESPERAR_PRESIONAR_SW2 CON   4
  17. ESPERAR_SOLTAR_SW2 CON      5
  18. CAPTURAR_PULSOS_PARA_TOFF   6
  19.  
  20. ...........
  21. Main:
  22.     EstadoTarea = ESPERAR_PRESIONAR_SW' Inicializo EstadoTarea
  23.     LOWLED1' apago el led inicialmente
  24. Lazo:
  25.     SELECT CASE EstadoTarea
  26.         CASE ESPERAR_PRESIONAR_SW1
  27.             IF SW1=0  THEN
  28.                 EstadoTarea = ESPERAR_SOLTAR_SW1
  29.             Endif
  30.         CASE ESPERAR_SOLTAR_SW1            
  31.              IF SW1=1  THEN' espero hasta que dejen de presionar SW1
  32.                 EstadoTarea = CAPTURAR_PULSOS_PARA_TON ' voy al siguiente caso
  33.             Endif
  34.         CASE CAPTURAR_PULSOS_PARA_TON
  35.             ContadorPulsos = Pulsos
  36.             EstadoTarea = ESPERAR_TON
  37.         CASE ESPERAR_TON
  38.             IF ((Pulsos- ContadorPulsos) > _2000_ms) THEN
  39.                 HIGH LED1  
  40.                 EstadoTarea = ESPERAR_PRESIONAR_SW1 CON
  41.                 Endif
  42.         CASE ESPERAR_PRESIONAR_SW2
  43.             IF SW2=0  THEN
  44.                 EstadoTarea = ESPERAR_SOLTAR_SW2
  45.             Endif
  46.         CASE ESPERAR_SOLTAR_SW2            
  47.              IF SW2=1  THEN' espero hasta que dejen de presionar SW12
  48.                 EstadoTarea = CAPTURAR_PULSOS_PARA_TOFF ' voy al siguiente caso
  49.             Endif
  50.         CASE CAPTURAR_PULSOS_PARA_TOFF' Espero que hayan pasado 20 pulsos (20 pulsos x 0.1s = 2 segundos)
  51.             IF ((Pulsos- ContadorPulsos) > _1000_ms) THEN
  52.                 LOWLED' apago el led
  53.                 EstadoTarea = 0' regreso al primer estado
  54.             Endif
  55.     EndSelect
  56. GOTO Lazo:
  57.  
  58.  
  59. interpt:
  60.     'disable    
  61.     Pulsos++;
  62.     INTCON.2 = 0    ' Reset timer interrupt flag
  63.     RESUME
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 11 de Septiembre de 2022, 19:08:59

Piensa en procesos recurrentes como el ejemplo que escribí, ahí podrías crear une estado para esperar que el usuario suelte el pulsante para empezar los procesos.

Así se diseñan los sistemas con pulsantes o botones. hasta en software, cuando pulsas un botón el ratón del computador, se ejecuta el proceso al soltarlo, no al presionarlo.

Si, es decir se activan por flancos, ya sea de bajada o bien de subida.
En el circuito propuesto es necesario que se active al presionar, no al soltar, osea se debería activar al pasar de "1" a "0" es decir en el flanco de bajada ya que los pulsadores están en modo Pull Up.
Debe haber una manera de hacerlo, en estos momentos estoy haciendo unas pruebas, espero lograrlo.
Saludos!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 11 de Septiembre de 2022, 19:14:59

Piensa en procesos recurrentes como el ejemplo que escribí, ahí podrías crear une estado para esperar que el usuario suelte el pulsante para empezar los procesos.

Así se diseñan los sistemas con pulsantes o botones. hasta en software, cuando pulsas un botón el ratón del computador, se ejecuta el proceso al soltarlo, no al presionarlo.

Si, es decir se activan por flancos, ya sea de bajada o bien de subida.
En el circuito propuesto es necesario que se active al presionar, no al soltar, osea se debería activar al pasar de "1" a "0" es decir en el flanco de bajada ya que los pulsadores están en modo Pull Up.
Debe haber una manera de hacerlo, en estos momentos estoy haciendo unas pruebas, espero lograrlo.
Saludos!

Entonces quedaría como lo propuse antes, per aprovechando los cálculos de tiempo y la interrupción de Eduardo2

De esa manera, no importa si te quedas presionado los botones.

Código: QBasic/QuickBASIC
  1. _1000ms CON 1*61    ; Conteos para 1seg con interrupciones cada 16.384ms
  2.                 ; T2s : 1*(1000/16.384) = 61
  3.  
  4.  
  5. _2000ms CON 2*61    ; Conteos para 2seg con interrupciones cada 16.384ms
  6.                 ; T2s : 2*(1000/16.384) = 122
  7.                
  8. Pulsos VAR BYTE  
  9. ContadorPulsos VAR BYTE
  10.  
  11.  
  12. ESPERAR_PRESIONAR_SW1       CON     0
  13. CAPTURAR_PULSOS_PARA_TON    CON     1
  14. ESPERAR_TON                 CON     2
  15. ESPERAR_PRESIONAR_SW2 CON   CON     3
  16. CAPTURAR_PULSOS_PARA_TOFF   CON     4
  17.  
  18. ...........
  19. Main:
  20.     EstadoTarea = ESPERAR_PRESIONAR_SW' Inicializo EstadoTarea
  21.     LOWLED1' apago el led inicialmente
  22. Lazo:
  23.     SELECT CASE EstadoTarea
  24.         CASE ESPERAR_PRESIONAR_SW1
  25.             IF SW1=0  THEN
  26.             EstadoTarea = CAPTURAR_PULSOS_PARA_TON ' voy al siguiente caso
  27.             Endif
  28.         CASE CAPTURAR_PULSOS_PARA_TON
  29.             ContadorPulsos = Pulsos
  30.             EstadoTarea = ESPERAR_TON
  31.         CASE ESPERAR_TON
  32.             IF ((Pulsos- ContadorPulsos) > _2000ms) THEN
  33.                 HIGH LED1  
  34.                 EstadoTarea = ESPERAR_PRESIONAR_SW1
  35.             Endif
  36.         CASE ESPERAR_PRESIONAR_SW2
  37.             IF SW2=0  THEN
  38.                EstadoTarea = CAPTURAR_PULSOS_PARA_TOFF ' voy al siguiente caso
  39.             Endif
  40.         CASE CAPTURAR_PULSOS_PARA_TOFF' Espero que hayan pasado 20 pulsos (20 pulsos x 0.1s = 2 segundos)
  41.             IF ((Pulsos- ContadorPulsos) > _1000ms) THEN
  42.                 LOWLED' apago el led
  43.                 EstadoTarea = ESPERAR_PRESIONAR_SW1 CON' regreso al primer estado
  44.             Endif
  45.     EndSelect
  46. GOTO Lazo:
  47.  
  48.  
  49. interpt:
  50.     'disable    
  51.     Pulsos = Pulsos + 1;
  52.     INTCON.2 = 0    ' Reset timer interrupt flag
  53.     RESUME
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 11 de Septiembre de 2022, 21:21:35
Código: [Seleccionar]
Entonces quedaría como lo propuse antes, per aprovechando los cálculos de tiempo y la interrupción de Eduardo2

[/quote]
Saludos DominusDDR.
Una vez más gracias por tu tiempo y esfuerzo para ayudar a construir estos emuladores de retardo en la conexión y desconexión.
He adaptado el código que tan gentilmente brindaste, pero al momento de la simulación, este se comporta de la misma forma que el código proporcionado por Eduardo2, es decir únicamente al soltar SW1 se enciende LED1, de igual manera, solo al soltar SW2 se apaga.
Adjunto el código y el hex para la simulación.
Hasta pronto.

Código:
@ __config _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _BODEN_OFF & _LVP_OFF & _WDT_OFF & _PWRTE_OFF

Define OSC 4
CMCON = 7


Precarga   Var Word                                       
Symbol LED1 = PORTB.0
Symbol LED2 = PORTB.1
Symbol SW1 =  PORTA.2
Symbol SW2 =  PORTA.3


_1000_ms CON 1*6    ; Conteos para 1seg con interrupciones cada 16.384ms
                ; T2s : 1*(1000/16.384) = 61
 
 
_2000_ms CON 2*6    ; Conteos para 2seg con interrupciones cada 16.384ms
                ; T2s : 2*(1000/16.384) = 122
               
Pulsos VAR BYTE 
ContadorPulsos VAR BYTE
EstadoTarea  VAR BYTE

ESPERAR_PRESIONAR_SW1 CON     0
ESPERAR_SOLTAR_SW1 CON        1
CAPTURAR_PULSOS_PARA_TON CON  2
ESPERAR_TON  CON              3
ESPERAR_PRESIONAR_SW2 CON     4
ESPERAR_SOLTAR_SW2 CON        5
CAPTURAR_PULSOS_PARA_TOFF CON 6
ESPERAR_TOFF  CON             7
 
TRISA=%11111111                   
TRISB=%00000000
                 
PORTB=0
LED1 = 0
LED2 = 0               
   
   T1CON = %00111101         
   Precarga = 40536         
   TMR1H = Precarga.HighByte  'Precargar el byte alto   
   TMR1L = Precarga.LowByte   'Precargar el byte bajo   
   PIE1.0 = 1               'Habilita la interrupción por desborde       
   INTCON = %11000000         'Habilita interrupciones globales y periféricas
   
   
   On Interrupt GoTo Interrupcion

Main:
    EstadoTarea = ESPERAR_PRESIONAR_SW1' Inicializo EstadoTarea
    LOW LED1' apago el led inicialmente
Lazo:
    SELECT CASE EstadoTarea
        CASE ESPERAR_PRESIONAR_SW1
            IF SW1=0  THEN
                EstadoTarea = ESPERAR_SOLTAR_SW1                 
            Endif
        CASE ESPERAR_SOLTAR_SW1             
             IF SW1=1  THEN' espero hasta que dejen de presionar SW1
                EstadoTarea = CAPTURAR_PULSOS_PARA_TON ' voy al siguiente caso
            Endif
        CASE CAPTURAR_PULSOS_PARA_TON
            ContadorPulsos = Pulsos
            EstadoTarea = ESPERAR_TON
        CASE ESPERAR_TON
            IF ((Pulsos- ContadorPulsos) > _2000_ms) THEN
                HIGH LED1   
                EstadoTarea = ESPERAR_PRESIONAR_SW2
                Endif
               
        CASE ESPERAR_PRESIONAR_SW2
            IF SW2=0  THEN
                EstadoTarea = ESPERAR_SOLTAR_SW2
            Endif
        CASE ESPERAR_SOLTAR_SW2             
             IF SW2=1  THEN' espero hasta que dejen de presionar SW2
                EstadoTarea = CAPTURAR_PULSOS_PARA_TOFF ' voy al siguiente caso
            Endif
        CASE CAPTURAR_PULSOS_PARA_TOFF' Espero que hayan pasado 20 pulsos (20 pulsos x 0.1s = 2 segundos)
                   
            IF ((Pulsos- ContadorPulsos) > _1000_ms) THEN
                LOW LED1' apago el led
                EstadoTarea = 0' regreso al primer estado                 
            Endif
    END SELECT
GOTO Lazo:
   
Interrupcion:
   Disable
   
   If PIR1.0 = 1 Then         ; Ocurrió un desborde del Timer 1
               'Call _set_timer1(0xfc17)  'Recarga registros TMR1 para desborde 1mSeg. y borra PIR1.TMR1IF
                T1CON.0 = 0  'Para el contador del TMR1
                TMR1H = Precarga.HighByte 'Recarga el contador byte alto
                TMR1L = Precarga.LowByte  'Recarga el contador byte bajo
                T1CON.0 = 1  'Activa el contador del TMR1
                PIR1.0 = 0    'Flash dosborde a cero
'Pulsos ++;
toggle LED2
 Pulsos = Pulsos + 1
    endif
   
    INTCON.2 = 0    ' Reset timer interrupt flag           
   
   Resume
   Enable


   End
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 11 de Septiembre de 2022, 21:30:57

Saludos DominusDDR.
Una vez más gracias por tu tiempo y esfuerzo para ayudar a construir estos emuladores de retardo en la conexión y desconexión.
He adaptado el código que tan gentilmente brindaste, pero al momento de la simulación, este se comporta de la misma forma que el código proporcionado por Eduardo2, es decir únicamente al soltar SW1 se enciende LED1, de igual manera, solo al soltar SW2 se apaga.
Adjunto el código y el hex para la simulación.
Hasta pronto.




Si, ese es así, espera soltar los pulsadores. Por eso en #72 puse el inicial que hice más la interrupción de Eduardo2, ese funciona tan pronto presionas los botones.

Código: QBasic/QuickBASIC
  1. _1000ms CON 1*61    ; Conteos para 1seg con interrupciones cada 16.384ms
  2.                 ; T2s : 1*(1000/16.384) = 61
  3.  
  4.  
  5. _2000ms CON 2*61    ; Conteos para 2seg con interrupciones cada 16.384ms
  6.                 ; T2s : 2*(1000/16.384) = 122
  7.                
  8. Pulsos VAR BYTE  
  9. ContadorPulsos VAR BYTE
  10.  
  11.  
  12. ESPERAR_PRESIONAR_SW1       CON     0
  13. CAPTURAR_PULSOS_PARA_TON    CON     1
  14. ESPERAR_TON                 CON     2
  15. ESPERAR_PRESIONAR_SW2 CON   CON     3
  16. CAPTURAR_PULSOS_PARA_TOFF   CON     4
  17.  
  18. ...........
  19. Main:
  20.     EstadoTarea = ESPERAR_PRESIONAR_SW' Inicializo EstadoTarea
  21.     LOWLED1' apago el led inicialmente
  22. Lazo:
  23.     SELECT CASE EstadoTarea
  24.         CASE ESPERAR_PRESIONAR_SW1
  25.             IF SW1=0  THEN
  26.             EstadoTarea = CAPTURAR_PULSOS_PARA_TON ' voy al siguiente caso
  27.             Endif
  28.         CASE CAPTURAR_PULSOS_PARA_TON
  29.             ContadorPulsos = Pulsos
  30.             EstadoTarea = ESPERAR_TON
  31.         CASE ESPERAR_TON
  32.             IF ((Pulsos- ContadorPulsos) > _2000ms) THEN
  33.                 HIGH LED1  
  34.                 EstadoTarea = ESPERAR_PRESIONAR_SW1
  35.             Endif
  36.         CASE ESPERAR_PRESIONAR_SW2
  37.             IF SW2=0  THEN
  38.                EstadoTarea = CAPTURAR_PULSOS_PARA_TOFF ' voy al siguiente caso
  39.             Endif
  40.         CASE CAPTURAR_PULSOS_PARA_TOFF' Espero que hayan pasado 20 pulsos (20 pulsos x 0.1s = 2 segundos)
  41.             IF ((Pulsos- ContadorPulsos) > _1000ms) THEN
  42.                 LOWLED' apago el led
  43.                 EstadoTarea = ESPERAR_PRESIONAR_SW1 CON' regreso al primer estado
  44.             Endif
  45.     EndSelect
  46. GOTO Lazo:
  47.  
  48.  
  49. interpt:
  50.     'disable    
  51.     Pulsos = Pulsos + 1;
  52.     INTCON.2 = 0    ' Reset timer interrupt flag
  53.     RESUME
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 12 de Septiembre de 2022, 00:01:53

Saludos DominusDDR.
Una vez más gracias por tu tiempo y esfuerzo para ayudar a construir estos emuladores de retardo en la conexión y desconexión.
He adaptado el código que tan gentilmente brindaste, pero al momento de la simulación, este se comporta de la misma forma que el código proporcionado por Eduardo2, es decir únicamente al soltar SW1 se enciende LED1, de igual manera, solo al soltar SW2 se apaga.
Adjunto el código y el hex para la simulación.
Hasta pronto.




Si, ese es así, espera soltar los pulsadores. Por eso en #72 puse el inicial que hice más la interrupción de Eduardo2, ese funciona tan pronto presionas los botones.

Código: QBasic/QuickBASIC
  1. _1000ms CON 1*61    ; Conteos para 1seg con interrupciones cada 16.384ms
  2.                 ; T2s : 1*(1000/16.384) = 61
  3.  
  4.  
  5. _2000ms CON 2*61    ; Conteos para 2seg con interrupciones cada 16.384ms
  6.                 ; T2s : 2*(1000/16.384) = 122
  7.                
  8. Pulsos VAR BYTE  
  9. ContadorPulsos VAR BYTE
  10.  
  11.  
  12. ESPERAR_PRESIONAR_SW1       CON     0
  13. CAPTURAR_PULSOS_PARA_TON    CON     1
  14. ESPERAR_TON                 CON     2
  15. ESPERAR_PRESIONAR_SW2 CON   CON     3
  16. CAPTURAR_PULSOS_PARA_TOFF   CON     4
  17.  
  18. ...........
  19. Main:
  20.     EstadoTarea = ESPERAR_PRESIONAR_SW' Inicializo EstadoTarea
  21.     LOWLED1' apago el led inicialmente
  22. Lazo:
  23.     SELECT CASE EstadoTarea
  24.         CASE ESPERAR_PRESIONAR_SW1
  25.             IF SW1=0  THEN
  26.             EstadoTarea = CAPTURAR_PULSOS_PARA_TON ' voy al siguiente caso
  27.             Endif
  28.         CASE CAPTURAR_PULSOS_PARA_TON
  29.             ContadorPulsos = Pulsos
  30.             EstadoTarea = ESPERAR_TON
  31.         CASE ESPERAR_TON
  32.             IF ((Pulsos- ContadorPulsos) > _2000ms) THEN
  33.                 HIGH LED1  
  34.                 EstadoTarea = ESPERAR_PRESIONAR_SW1
  35.             Endif
  36.         CASE ESPERAR_PRESIONAR_SW2
  37.             IF SW2=0  THEN
  38.                EstadoTarea = CAPTURAR_PULSOS_PARA_TOFF ' voy al siguiente caso
  39.             Endif
  40.         CASE CAPTURAR_PULSOS_PARA_TOFF' Espero que hayan pasado 20 pulsos (20 pulsos x 0.1s = 2 segundos)
  41.             IF ((Pulsos- ContadorPulsos) > _1000ms) THEN
  42.                 LOWLED' apago el led
  43.                 EstadoTarea = ESPERAR_PRESIONAR_SW1 CON' regreso al primer estado
  44.             Endif
  45.     EndSelect
  46. GOTO Lazo:
  47.  
  48.  
  49. interpt:
  50.     'disable    
  51.     Pulsos = Pulsos + 1;
  52.     INTCON.2 = 0    ' Reset timer interrupt flag
  53.     RESUME
Estimado amigo, el código que acabé de compartir, es el del post # 72.
Solo funciona al soltar los botones.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 12 de Septiembre de 2022, 08:54:06
Estimado amigo, el código que acabé de compartir, es el del post # 72.
Solo funciona al soltar los botones.

El código en #72 no posee los estados ESPERAR_SOLTAR_SW1 y ESPERAR_SOLTAR_SW2. En cambio cuando en tu comentario de #73, están esos estados que mencioné.

Adjunto una imagen para mejor comprensión.

Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 12 de Septiembre de 2022, 11:13:37
Estimado amigo, el código que acabé de compartir, es el del post # 72.
Solo funciona al soltar los botones.

El código en #72 no posee los estados ESPERAR_SOLTAR_SW1 y ESPERAR_SOLTAR_SW2. En cambio cuando en tu comentario de #73, están esos estados que mencioné.

Adjunto una imagen para mejor comprensión.
DomunusDRR el post al que te refieres es el #70 y no el #72 como lo mencionas.
Ahora lo voy a probar y te cuento.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 12 de Septiembre de 2022, 11:24:59
Estimado amigo, el código que acabé de compartir, es el del post # 72.
Solo funciona al soltar los botones.

El código en #72 no posee los estados ESPERAR_SOLTAR_SW1 y ESPERAR_SOLTAR_SW2. En cambio cuando en tu comentario de #73, están esos estados que mencioné.

Adjunto una imagen para mejor comprensión.
.


DomunusDRR el post al que te refieres es el #70 y no el #72 como lo mencionas.
Ahora lo voy a probar y te cuento.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 13 de Septiembre de 2022, 12:31:13
Espero que todos se encuentren muy bien.
Gracias Dominus Drr por proporcionar el código para los temporizadores.
He realizado las pruebas correspondiente y funciona.
Únicamente hice unas pequeñísimas modificaciones para que emule lo mejor posible a  los TON y TOF reales.
Nuevamente gracias a DominusDRR y a dogflu66 así como también a Eduardo2 que aportaron tiempo e ingenio para vencer este desafío.
De todas maneras, si alguien tiene otra solución o quiere aportar algo más, bienvenido sea.
A continuación adjunto los archivos del temporizador On Delay y Off Delay.
Saludos cordiales!
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 13 de Septiembre de 2022, 12:44:10
Espero que todos se encuentren muy bien.
Gracias Dominus Drr por proporcionar el código para los temporizadores.
He realizado las pruebas correspondiente y funciona.
Únicamente hice unas pequeñísimas modificaciones para que emule lo mejor posible a  los TON y TOF reales.
Nuevamente gracias a DominusDRR y a dogflu66 así como también a Eduardo2 que aportaron tiempo e ingenio para vencer este desafío.
De todas maneras, si alguien tiene otra solución o quiere aportar algo más, bienvenido sea.
A continuación adjunto los archivos del temporizador On Delay y Off Delay.
Saludos cordiales!

Pienso que la interrupción sólo debería incrementar los pulsos, el resto del código creo que está demás, debería ser sólo así:

Código: QBasic/QuickBASIC
  1. Interrupcion:
  2.         Disable
  3.        
  4.         IF PIR1.0 = 1 THEN                      ; Ocurrió un desborde del TIMER 1
  5.                     'Call _set_timer1(0xfc17)  'Recarga registros TMR1 para desborde 1mSeg. y borra PIR1.TMR1IF
  6.                 'T1CON.0 = 0  'Para el contador del TMR1
  7.                 'TMR1H = Precarga.HighByte 'Recarga el contador byte alto
  8.                 'TMR1L = Precarga.LowByte  'Recarga el contador byte bajo
  9.                 'T1CON.0 = 1  'Activa el contador del TMR1
  10.                 'PIR1.0 = 0      'Flash dosborde a cero
  11.  
  12.               Pulsos = Pulsos + 1
  13.     endif
  14.    
  15.     INTCON.2 = 0    ' Reset timer interrupt flag            
  16.        
  17.         RESUME
  18.         Enable

Ahora que entiendes los conceptos de una tarea en estados, cualquier otro proceso puedes hacerlo de esa manera, y cada a uno sería independiente del otro, con poca o nula interferencia.

Todo lo que hace tu tarea de temporizador On OFF la puedes poner en una función digamos así:

Código: QBasic/QuickBASIC
  1. Private FUNCTION TareaTonOff()
  2.   SELECT CASE EstadoTarea
  3.         CASE ESPERAR_PRESIONAR_SW1
  4.             IF SW1=0  THEN
  5.                 EstadoTarea = CAPTURAR_PULSOS_PARA_TON ' voy al siguiente caso
  6.             Endif
  7.         CASE CAPTURAR_PULSOS_PARA_TON
  8.             ContadorPulsos = Pulsos
  9.             EstadoTarea = ESPERAR_TON
  10.         CASE ESPERAR_TON
  11.             IF ((Pulsos- ContadorPulsos) > _2000_ms) THEN
  12.                 HIGH LED1  
  13.                 EstadoTarea = ESPERAR_PRESIONAR_SW2
  14.                 Endif
  15.         CASE ESPERAR_PRESIONAR_SW2
  16.             IF SW2=0  THEN
  17.                 LOW LED1' apago el led
  18.                 EstadoTarea = 0' regreso al primer estado                
  19.             Endif
  20.     END SELECT
  21. END FUNCTION

Y desde el programa principal la puedes llamar:

Código: QBasic/QuickBASIC
  1. Main:
  2.     EstadoTarea = ESPERAR_PRESIONAR_SW1 'Inicializo EstadoTarea
  3.     LOW LED1' apago el led inicialmente
  4. Lazo:
  5.     TareaTonOff()
  6. GOTO Lazo:

Cualquier otro proceso debe ser una tarea y ejecutarse en el alzo principal:

Código: QBasic/QuickBASIC
  1. Main:
  2.     EstadoTarea = ESPERAR_PRESIONAR_SW1 'Inicializo EstadoTarea
  3.     EstadoTarea2 = ESTADO_INICIAL_TAREA2 '
  4.     EstadoTarea3 = ESTADO_INICIAL_TAREA3 '
  5.     ....
  6.     EstadoTareaN = ESTADO_INICIAL_TAREA_N '
  7.     LOW LED1' apago el led inicialmente
  8. Lazo:
  9.     TareaTonOff()
  10.     Tarea2()
  11.     Tarea3()
  12.     .....
  13.     TareaN()
  14. GOTO Lazo:



Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 13 de Septiembre de 2022, 13:46:55

Pienso que la interrupción sólo debería incrementar los pulsos, el resto del código creo que está demás, debería ser sólo así:

Código: QBasic/QuickBASIC
  1. Interrupcion:
  2.         Disable
  3.        
  4.         IF PIR1.0 = 1 THEN                      ; Ocurrió un desborde del TIMER 1
  5.                     'Call _set_timer1(0xfc17)  'Recarga registros TMR1 para desborde 1mSeg. y borra PIR1.TMR1IF
  6.                 'T1CON.0 = 0  'Para el contador del TMR1
  7.                 'TMR1H = Precarga.HighByte 'Recarga el contador byte alto
  8.                 'TMR1L = Precarga.LowByte  'Recarga el contador byte bajo
  9.                 'T1CON.0 = 1  'Activa el contador del TMR1
  10.                 'PIR1.0 = 0      'Flash dosborde a cero
  11.  
  12.               Pulsos = Pulsos + 1
  13.     endif
  14.    
  15.     INTCON.2 = 0    ' Reset timer interrupt flag            
  16.        
  17.         RESUME
  18.         Enable

Así es como está, yo no noto cuál es la diferencia.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 13 de Septiembre de 2022, 13:48:32

Pienso que la interrupción sólo debería incrementar los pulsos, el resto del código creo que está demás, debería ser sólo así:

Código: QBasic/QuickBASIC
  1. Interrupcion:
  2.         Disable
  3.        
  4.         IF PIR1.0 = 1 THEN                      ; Ocurrió un desborde del TIMER 1
  5.                     'Call _set_timer1(0xfc17)  'Recarga registros TMR1 para desborde 1mSeg. y borra PIR1.TMR1IF
  6.                 'T1CON.0 = 0  'Para el contador del TMR1
  7.                 'TMR1H = Precarga.HighByte 'Recarga el contador byte alto
  8.                 'TMR1L = Precarga.LowByte  'Recarga el contador byte bajo
  9.                 'T1CON.0 = 1  'Activa el contador del TMR1
  10.                 'PIR1.0 = 0      'Flash dosborde a cero
  11.  
  12.               Pulsos = Pulsos + 1
  13.     endif
  14.    
  15.     INTCON.2 = 0    ' Reset timer interrupt flag            
  16.        
  17.         RESUME
  18.         Enable

Así es como está, yo no noto cuál es la diferencia.

Entonces vi mal los archivos txt que enviaste en el comprimido.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 13 de Septiembre de 2022, 14:00:24

Pienso que la interrupción sólo debería incrementar los pulsos, el resto del código creo que está demás, debería ser sólo así:

Código: QBasic/QuickBASIC
  1. Interrupcion:
  2.         Disable
  3.        
  4.         IF PIR1.0 = 1 THEN                      ; Ocurrió un desborde del TIMER 1
  5.                     'Call _set_timer1(0xfc17)  'Recarga registros TMR1 para desborde 1mSeg. y borra PIR1.TMR1IF
  6.                 'T1CON.0 = 0  'Para el contador del TMR1
  7.                 'TMR1H = Precarga.HighByte 'Recarga el contador byte alto
  8.                 'TMR1L = Precarga.LowByte  'Recarga el contador byte bajo
  9.                 'T1CON.0 = 1  'Activa el contador del TMR1
  10.                 'PIR1.0 = 0      'Flash dosborde a cero
  11.  
  12.               Pulsos = Pulsos + 1
  13.     endif
  14.    
  15.     INTCON.2 = 0    ' Reset timer interrupt flag            
  16.        
  17.         RESUME
  18.         Enable

Así es como está, yo no noto cuál es la diferencia.

Entonces vi mal los archivos txt que enviaste en el comprimido.

Al estar en archivo de texto, se torna un tanto confuso, tranquilo no hay problema.
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 13 de Septiembre de 2022, 14:08:16


Ahora que entiendes los conceptos de una tarea en estado, cualquier otro proceso puedes hacerlo de esa manera, y cada a uno sería independiente del otro, con poca o nula interferencia.

Todo lo que hace tu tarea de temporizado la puedes poner en una función digamos así:

Código: QBasic/QuickBASIC
  1. Private FUNCTION TareaTonOff()
  2.   SELECT CASE EstadoTarea
  3.         CASE ESPERAR_PRESIONAR_SW1
  4.             IF SW1=0  THEN
  5.                 EstadoTarea = CAPTURAR_PULSOS_PARA_TON ' voy al siguiente caso
  6.             Endif
  7.         CASE CAPTURAR_PULSOS_PARA_TON
  8.             ContadorPulsos = Pulsos
  9.             EstadoTarea = ESPERAR_TON
  10.         CASE ESPERAR_TON
  11.             IF ((Pulsos- ContadorPulsos) > _2000_ms) THEN
  12.                 HIGH LED1  
  13.                 EstadoTarea = ESPERAR_PRESIONAR_SW2
  14.                 Endif
  15.         CASE ESPERAR_PRESIONAR_SW2
  16.             IF SW2=0  THEN
  17.                 LOW LED1' apago el led
  18.                 EstadoTarea = 0' regreso al primer estado                
  19.             Endif
  20.     END SELECT
  21. END FUNCTION

Y desde el programa principal la puedes llamar:

Código: QBasic/QuickBASIC
  1. Main:
  2.     EstadoTarea = ESPERAR_PRESIONAR_SW1 'Inicializo EstadoTarea
  3.     LOW LED1' apago el led inicialmente
  4. Lazo:
  5.     TareaTonOff()
  6. GOTO Lazo:

Cualquier otro proceso debe ser una tarea y ejecutarse en el alzo principal:

Código: QBasic/QuickBASIC
  1. Main:
  2.     EstadoTarea = ESPERAR_PRESIONAR_SW1 'Inicializo EstadoTarea
  3.     EstadoTarea2 = ESTADO_INICIAL_TAREA2 '
  4.     EstadoTarea3 = ESTADO_INICIAL_TAREA3 '
  5.     ....
  6.     EstadoTareaN = ESTADO_INICIAL_TAREA_N '
  7.     LOW LED1' apago el led inicialmente
  8. Lazo:
  9.     TareaTonOff()
  10.     Tarea2()
  11.     Tarea3()
  12.     .....
  13.     TareaN()
  14. GOTO Lazo:
Gracias Dominus DRR.
Me parece genial esta información sobre tarea en estado, espero ponerle en práctica lo antes posible . Alguna sugerencia de dónde puedo encontrar más información y de ser posible ejemplos?
Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: DominusDRR en 13 de Septiembre de 2022, 14:13:21


Ahora que entiendes los conceptos de una tarea en estado, cualquier otro proceso puedes hacerlo de esa manera, y cada a uno sería independiente del otro, con poca o nula interferencia.

Todo lo que hace tu tarea de temporizado la puedes poner en una función digamos así:

Código: QBasic/QuickBASIC
  1. Private FUNCTION TareaTonOff()
  2.   SELECT CASE EstadoTarea
  3.         CASE ESPERAR_PRESIONAR_SW1
  4.             IF SW1=0  THEN
  5.                 EstadoTarea = CAPTURAR_PULSOS_PARA_TON ' voy al siguiente caso
  6.             Endif
  7.         CASE CAPTURAR_PULSOS_PARA_TON
  8.             ContadorPulsos = Pulsos
  9.             EstadoTarea = ESPERAR_TON
  10.         CASE ESPERAR_TON
  11.             IF ((Pulsos- ContadorPulsos) > _2000_ms) THEN
  12.                 HIGH LED1  
  13.                 EstadoTarea = ESPERAR_PRESIONAR_SW2
  14.                 Endif
  15.         CASE ESPERAR_PRESIONAR_SW2
  16.             IF SW2=0  THEN
  17.                 LOW LED1' apago el led
  18.                 EstadoTarea = 0' regreso al primer estado                
  19.             Endif
  20.     END SELECT
  21. END FUNCTION

Y desde el programa principal la puedes llamar:

Código: QBasic/QuickBASIC
  1. Main:
  2.     EstadoTarea = ESPERAR_PRESIONAR_SW1 'Inicializo EstadoTarea
  3.     LOW LED1' apago el led inicialmente
  4. Lazo:
  5.     TareaTonOff()
  6. GOTO Lazo:

Cualquier otro proceso debe ser una tarea y ejecutarse en el alzo principal:

Código: QBasic/QuickBASIC
  1. Main:
  2.     EstadoTarea = ESPERAR_PRESIONAR_SW1 'Inicializo EstadoTarea
  3.     EstadoTarea2 = ESTADO_INICIAL_TAREA2 '
  4.     EstadoTarea3 = ESTADO_INICIAL_TAREA3 '
  5.     ....
  6.     EstadoTareaN = ESTADO_INICIAL_TAREA_N '
  7.     LOW LED1' apago el led inicialmente
  8. Lazo:
  9.     TareaTonOff()
  10.     Tarea2()
  11.     Tarea3()
  12.     .....
  13.     TareaN()
  14. GOTO Lazo:
Gracias Dominus DRR.
Me parece genial esta información sobre tarea en estado, espero ponerle en práctica lo antes posible . Alguna sugerencia de dónde puedo encontrar más información y de ser posible ejemplos?

Es un concepto de programación, hay de diferentes tipos unos más complejos que otros, es el principio para entender RTOs y sistemas operativos.

Con Basic, no se donde habrá tales conceptos:

Los primeros capítulos de este libro te sirvan:

https://leanpub.com/programacionpracticadelmicrocontroladorpic32 (https://leanpub.com/programacionpracticadelmicrocontroladorpic32)

O un videito te puede dar algunas ideas: (Desde el minuto 03:18)


Título: Re:Time Off Delay (TOF) & Time On Delay (TON)
Publicado por: okapi en 13 de Septiembre de 2022, 17:41:36
Muchas Gracias por la información.
Se hace referencia al lenguaje de programación C, me imagino que es más versátil que otros
Saludos!