desktop

Problema con condiciones IF en PICBasic

Hola amigos nuevamente por aqui, espero no molestar con mi insistencia.
Les doy mas o menos un alcance mas cercano del problema del proyecto.

en el caso2: hora int 23:59 hora apag 02:20 hora enc 02:40
la hora de int puede ser cualquier hora antes de las 23:59 y la hora de apa y enc deben ser después de las 00:00 horas.
cuando la hora tiempo real esta en el minuto 39 o menos es deecir 38,37,36,etc de cualquier hora por ejemplo:

eehora eemin int apa enc
23 : 39 23:59 02:20 02:40

21:39 / 20:39 .... cualquier hora :39 para atrás , el semaforo no enciende, pero tan luego pasa el minutos 39, se vuelve a la normalidad.
Adjunto el archivo que estoy compilando y el esquema en isis proteus.
Muchas gracias
 

Adjuntos

  • nvo archivo.rar
    37.6 KB · Visitas: 12
Última edición:
Hola amigos nuevamente por aqui, espero no molestar con mi insistencia.
Les doy mas o menos un alcance mas cercano del problema del proyecto.

en el caso2: hora int 23:59 hora apag 02:20 hora enc 02:40
la hora de int puede ser cualquier hora antes de las 23:59 y la hora de apa y enc deben ser después de las 00:00 horas.
cuando la hora tiempo real esta en el minuto 39 o menos es deecir 38,37,36,etc de cualquier hora por ejemplo:

eehora eemin int apa enc
23 : 39 23:59 02:20 02:40

21:39 / 20:39 .... cualquier hora :39 para atrás , el semaforo no enciende, pero tan luego pasa el minutos 39, se vuelve a la normalidad.
Adjunto el archivo que estoy compilando y el esquema en isis proteus.
Muchas gracias

Buenas.
He estado analizando tu código, y también hay un bug en tu comparación de casos, por ejemplo si la hora intermitencia es 23:30, hora de apagado 01:45 y hora de encendido 02:40 el programa no hace nada, solo lee el rtc.
Referente a tu problema de Caso 2 hay subo el código con algunas modificaciones para que lo pruebes y analices:
 

Adjuntos

  • nvo archivo.rar
    268 KB · Visitas: 11
Viendo el código, la verdad me enredé.
Por eso siempre les he aconsejado que hagan el programa por partes, y ya cuando una función les de buen resultado, la incluyan a lo que será el programa principal.

Lo problemas que pude ver en el programa se deben a usar retardos excesivos y escrituras a la pantalla durante el servicio de interrupción.
Tampoco debes usar un Return dentro del servicio de interrupción porque se provocará un desborde de pila.

También hay una mala estructura y muchas variables que se pueden sintetizar en arreglos.
Empieza por partes y prueba cada función, cuando la tengas sigue con el resto del programa.

Yo cuando tengo que hacer un programa grande, lo hago por partes para ir probando las rutinas independientes.
Así voy acumulando carpetas con programas de prueba que posteriormente añado al principal.
Cuando ya están funcionando en conjunto con el resto del programa, las borro o las guardo como ejemplos.
 
Buenas Noches, Amigos otra vez por aquí después de mucho tiempo, pero contento de regresar a explorar esta pagina con una pregunta.
Espero me puedan apoyar de ante mano muchas gracias.
Hace unos años me favorecieron en la solucion de un codigo en pic basic pro, y el amigo RobertTorres me dio una pista, y quiero decirle que me sirvio mucho, tal es que eh podido encontrar la lógica d su analisis que me compartio. aquilo dejo:
en archivos adjuntos,.
aquí la pregunta. porque las sentencias por separadas funcionan bien, pero cuando las junto para dejar listo todo como un solo programa, como que se pierde la LÓGICA Y no obedece, cuando junto los tres casos el tercero mas que todo ya no me obedece. Bueno eso es amigos, ojala me puedan dar una manito, muchas gracias.

Código:
on interrupt goto CONFIGURAR
INTCON = %10010000
OPTION_REG.6=0
    FOR a = 1 TO 100   
    if (APhora >= INHora) and (APhora >= ENhora) then caso1
    pause 100
    next
    FOR a = 1 TO 100
    if (INhora >= ENhora) and (INhora >= APhora) then caso2
    pause 100
    next
    FOR a = 1 TO 100   
    if (ENhora >= APhora) and (ENhora >= INHora) then caso3
    pause 100
    next
    
goto inicio
 
te tomaste tu tiempo al parecer o_O Agosto 2016, Marzo 2018...
Podrias subir lo que estas sumando o haciendo en la interrupcion?... si no veo todo el programa, no puedo ayudarte... ahi solo veo tres contadores que nunca van a sali del loop si no cambian los valores de APhora, INHora,ENhora.... entonces, tengo que ver como configuraste cada variable, tengo que ver que haces cuando pega el salto la interrupcion , etc etc... ponete las pilas papa ;)
 
mira, si no mal entendi el programa, el problema radica en que se pierde el microcontrolador cuando esta dentro de la interrupcion... Para que esto no pase, tenes que indicarle al microcontrolador cuando arranca y cuando termina la interrupcio ya que uinterrupcion lo que hace es dejar de lado o que estaba haciendo paara atender otra cosa y finalizada esta, vuelve al punto donde habia quedado (en algunos caso si, en otros puedes seguir atendiendo otra cosas, pero debes de activar nuevamente la bandera de la interrupcion para arranque nuevamente el timer a trabajar).
En tu caso, si bien se ve que configuras la interrupcion, fijate que debajo de esta configuracion colocas parte de lo que seria la rutina de la interrupcion, pero sin anidar a un subprograma... o sea, las lineas de abajo no tienen etiqueta y la cerras con DISABLE

Enriquecido (Código BB):
on interrupt goto CONFIGURAR

INTCON = %10010000

OPTION_REG.6=0

     

    if (APhora >= INHora) and (APhora >= ENhora) then caso1



    if (INhora >= ENhora) and (INhora >= APhora) then caso2

   

    if (ENhora >= APhora) and (ENhora >= INHora) then caso3

 

goto inicio

     

caso1:

IF (EEHORA >=APHora) and (EEMIN>=APminu)  then  apagar

if (EEHORA >=INHora) and (EEMIN => INminu) then intermitente

if (EEHORA >=ENhora) and (EEMIN>=ENCminu) and (EEHORA =<INhora) then programa



if (EEHORA >= 00) AND (EEMIN >= 00) AND (EEHORA <= ENhora) then  apagar    

if (EEHORA >= 00) and (EEmin >= 00) and (EEhora <= INhora) then programa

if (EEHORA >= 00) AND (EEMIN >= 00) AND (EEHORA >= INHORA) then  intermitente    ;AND (EEMIN <= INminu) then    

    goto inicio

     

caso2:

IF (EEHORA >=INHora) and (EEMIN>=INminu)  then  intermitente

if (EEHORA >=ENhora) and (EEMIN => ENCminu) then programa

if (EEHORA >=APhora) and (EEMIN>=APminu) and (EEHORA =<ENHORA) then  apagar  


if (EEHORA >= 00) AND (EEMIN >= 00) AND (EEHORA <= APhora) then  intermitente    ;AND (EEMIN <= INminu) then    

if (EEHORA >= 00) and (EEmin >= 00) and (EEhora <= ENhora) then apagar

if (EEHORA >= 00) AND (EEMIN >= 00) AND (EEHORA >= ENHORA) then  programa    ;AND (EEMIN <= INminu) then    

    goto inicio

       

caso3:

IF (EEHORA >=ENHora) and (EEMIN>=ENCminu)  then  programa  

if (EEHORA >=APhora) and (EEMIN => APminu) then apagar

if (EEHORA >=INhora) and (EEMIN>=INminu) and (EEHORA =<APHORA) then  intermitente  


if (EEHORA >= 00) AND (EEMIN >= 00) AND (EEHORA <= INhora) then  programa    

if (EEHORA >= 00) and (EEmin >= 00) and (EEhora <= APhora) then intermitente

if (EEHORA >= 00) AND (EEMIN >= 00) AND (EEHORA >= APHORA) then  apagar    ;AND (EEMIN <= INminu) then    


    goto inicio

   

programa:

       if fase=2 then dosfases

       if fase=3 then tresfases

     

dosfases:

        x=x+1

        if x > fase1 then paso2

        porta=%00001100

        portc.0=1

        PORTE=%000000000

        pause 1000

        goto inicio

paso2:      

        y=y+1

        if y > 3 then paso3

        PORTC.5 = 1;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

        porta=%00001010

        PORTC.0=0

        PORTE=%00000100

        pause 1000

        goto inicio

paso3:      

        z=z+1

        if z > fase2 then paso4

        porta=%00000001

        PORTC.0=0

        PORTE=%00000011

        pause 1000

        goto inicio

       

paso4:

        w=w+1

        if w > 3 then borrar

        porta=%00100001

        PORTC.0=0

        PORTE=%000000010

        pause 1000

        goto inicio

borrar:

        x = 0

        y = 0

        z = 0

        w = 0

        goto inicio

       

tresfases:

        x=x+1

        if x > fase1 then paso22

        porta=%00001100

        portc.0=0

        PORTE=%000000010

        for M = 1 to 10

        pause 100

        next

        goto inicio

paso22:      

        y=y+1

        if y > 3 then paso33

        PORTC.5 = 1;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

        porta=%00001010

        PORTC.0=0

        PORTE=%000000010

        for M = 1 to 10

        pause 100

        next

        goto inicio

paso33:      

        z=z+1

        if z > fase2 then paso44

        porta=%00000001

        PORTC.0=0

        PORTE=%00000011

        for M = 1 to 10

        pause 100

        next

        goto inicio


paso44:

        w=w+1

        if w > 3 then paso5

        porta=%00100001

        PORTC.0=0

        PORTE=%000000010

        for M = 1 to 10

        pause 100

        next

        goto inicio

       

paso5:

        u=u+1

        if u > fase3  then paso6

        porta=%00001001

        PORTC.0=1

        PORTE=%000000000

        for M = 1 to 10

        pause 100

        next

        goto inicio

paso6:

        v=v+1

        if v > 3 then borrar2

        porta=%00001001

        PORTC.0=0

        PORTE=%00000100

        for M = 1 to 10

        pause 100

        next

        goto inicio

       

borrar2:

        x = 0

        y = 0

        z = 0

        u = 0

        v = 0

        w = 0

        goto inicio

       

intermitente:

        porta=%000100010

        PORTE=%000000100

        portc.0=0

        for M = 1 to 5

        pause 100

        next

        porta=%000000000

        PORTE=%000000000

        for M = 1 to 5

        pause 100

        next

        goto inicio

       

apagar:  

        porta=0

        porte=0

        portc.0=0

        goto inicio          

   

disable

CONFIGURAR:
....

Justo debajo de DISABLE, le indicas al microcontrolador que arranca justamente la etiqueta a donde saltar en caso de interrupcion.... corrige eso y cuentanos como te fue... en lo posible, intenta que no pasen otros dos años :ROFLMAO::LOL: Saludos
 
En pocas palabras, que no incluyas todas esas rutinas dentro del servicio de interrupción.
Eso lo comenté en el post #23 y hasta ahora tu código sigue igual, aún con el Return dentro de la interrupción. o_O
Para eso existen las banderas (Flags) que puedes verificar para ejecutar rutinas.
 
Ola buenas tardes, estoy un poco cruzado los cables del cerebro con respecto a sus aportes de ayuda. Quería enviarles una imagen enseñándoles de donde saque mi programa base, del libro de microcontroladores Carlos Reyes A.. esta es.
 

Adjuntos

  • doc.rar
    175.4 KB · Visitas: 2
Sí, pero eso es sólo un ejemplo que enciende un LED cuando ocurre la interrupción externa por RB0.
Pero tú ingresaste la mayor parte del programa dentro del servicio de interrupción.
Una interrupción no debe ser usada de la forma en que lo hiciste.
Si hubieras escrito tu programa en lenguaje ensamblador, jamás hubiera dado señales de vida.

Lo que debes hacer es retirar todo ese código del servicio de interrupción y usar banderas.

Por ejemplo:
Código:
Servicio_Interrupciones:
    Disable

    If INTCON.1 = 1 Then    ; Si ocurre una interrupción por RB0...
        INTCON.1 = 0        ; Regresar a 0 el bit INTF
        Bandera_RB0 = 1     ; Indicar que ocurrió una interrupción por RB0
    EndIf

    Resume
    Enable
Posteriormente puedes comprobar "Bandera_RB0" dentro del bucle principal y ejecutar rutinas, sin olvidar regresar a 0 "Bandera_RB0"
 
¿Has programado antes en algún lenguaje? Si no se ha hecho, cuesta un poco más.
No te desanimes, presta atención a todo lo que te dijeron sobre donde debe ir cada cosa.
A veces querer corregir lo que se tiene, puede llegar a ser muy complicado.
Pasar en limpio e ir compilando por partes, te ayudará.
Muchas veces es muy buena idea hacer un diagrama de flujo para tener claro cada paso.
 
Hoja de datos, entra al topico de pbp ue hay en el.foro y centraye en los aportes del kia darkbyte... fijate que subio un pdf tambien que habla de configurcion del 16f877... eso mismo, te ayuda a entender como configurar otros pic... ojo, es complejo, a mi me cuesta cundo tengo que meter mano en micros que nunca use...
 
Hola, buenas noches, estimados amigos.
E
stuve haciendo un ejercicio con interrupción por timer 0 para poder entender un poco más acerca de este tema que me tiene un poco tonteado, jajaja.
Cogí un ejemplo de temporizador con el cronómetro de mecatrodatos en la pagina 1 del curso de pic basic pro.
S
e ve ahí que su temporizador es de 5 minutos, pero yo lo estoy haciendo programable y descendente a 0.
T
oda la programación me funciona, excepto que cuando llega a cero no se detiene el tiempo.
U
na pregunta. ¿Podrán revisarlo para ver qué no estoy comprendiendo? Por eso me da ese error.
Aquí-les adjunto mi programación y la simulación en proteus. Gracias por su comprensión.
 

Adjuntos

  • pregunta.rar
    17.5 KB · Visitas: 7
Ola buenas noches, aqui subo la modificación del programa del contador, tengo algunos inconvenientes con el pulsador stop que cuando la cuenta esta en stop y continuo presionando esta tecla , empieza a decrementar la cuenta por cada pulsada que le doy, cosa que no debe hacer. por favor revisen mi archivo, para continuar con el otro programa , que estoy plantado en hacer. muchas gracias.
 

Adjuntos

  • preguntita.rar
    9.6 KB · Visitas: 7
Buen día a los miembros del foro. Quisiera que me echen una mano con esto que no logro determinarlo
mi consulta es lo siguiente:

tengo 3 botones

btn0 biestable on - off
btn1 pulsador astable
btn2 biestable on - off

Led0 salida del pulsador bnt0
Led1 salida del pulsador btn1
Led2 salida del pulsador btn2

prensiono los botones todos encienden y apagan independientemente
la logica esta aqui...

* led2 enciende, si led0 esta encendido, caso contrario led 2 no enciende
hasta todo bien...
* presiono btn1, led0 y led2 se apagan, ya que led0 arrastra a led2, hasta ahi todo correcto

El problema radica aqui... quiero que cuando led0 se apague y led2 este encendido al momento de volver a presionar btn0 vuelva a encender led2 como si se tratase de dos interruptores en serie, btn2 esta cerrado y btn0 cerrado

IMG_1.jpg


* El segundo sería cuando led0 y led2 estan encendido al presionar btn1 estos leds deben apagarse y cuando el suelte el boton pulsador btn1 deberian volverse a prender como era en un principio ya que led0 y led2 se apagan independientemente con sus respectivos botones.

Gracias de antemano por la ayuda que me puedan brindar, adjunto archivos para la simulación.
Código:
#CONFIG

    __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_ON & _LVP_OFF & _CP_OFF

    #ENDCONFIG


DEFINE OSC 4                ; Definir que se trabajará con 4MHz.


CMCON     = 7          ' PortA = digital I/O

VRCON     = 0          ' A/D Voltage reference disabled

TRISA     = %11111111

TRISB     = %00000000  '




'========================================================================


'Symbol BOTON = PORTA.0


R VAR BYTE

B0 VAR BYTE




'B1 VAR BYTE

B2 VAR BYTE

B3 VAR BYTE

B4 VAR BYTE

B5 VAR BYTE

B6 VAR BYTE

B7 VAR BYTE




Bttn0  var portA.0         ' BTN 0

Btn1  var portA.1          ' BTN 1

Bttn2 var portA.2          ' BTN 2

Bttn3 var portA.3

Bttn4 var portA.4

Bttn6 var portA.6

Bttn7 var portA.7




LED1 VAR PORTB.0          '  LED0

LED2 VAR PORTB.1          '  LED1

LED3 VAR PORTB.2          '  LED3

LED4 VAR PORTB.3          '

LED5 VAR PORTB.4          '

LED6 var PORTB.5          '

LED7 var PORTB.6









PORTB = 0

PORTA = 0

'beep = 0

'led4 = 0    'Inicializar el pin RA3 en 0

'boton = 0

'sensor = 0

clear       'Limpiar RAM (Inicializa variables a 0)


 

'led1=0


'=============================== primera opción ==============================







BTNS:

gosub ESPACIO                         



IF Btn1 = 0 then

LED2 =  1

pause 10


led1 = 0     ' VNT    OFF

led3 = 0     ' QM     OFF

'IF btn1 = 0 then



else

led2  = 0


'led1 = 0

'led3 = 0

 

 goto btn0

'endif

endif

 

Btn0:

    'gosub ESPACIO1


    BUTTON PORTA.0,0,255,1,b0,0,btn2      ' Pin, Down, Delay, Rate, Bvar, Action, Etiqueta

 

    TOGGLE LED1                                 ' Lee Pin y opcionalmente ejecuta anti-rebote y auto-repetición.

 

    IF led1 and led3 = 1 then

    led3 = 1

 

    else

    led3 = 0

    endif

 

 

    '''endif   

'Btn1:                                                                       

   ' BUTTON PORTA.1,0,255,1,b1,0,btn2                                           

    'TOGGLE LED2                                        '       


Btn2:                                                                                 ' Estado del pin cuando se oprime el pulsador (0-1)

    BUTTON PORTA.2,0,255,1,b2,0,btn3          ' Delay Contador de ciclos antes de que comience la auto-repetición (0-255).                                     

 

    TOGGLE LED3                                                ' Si es 0, no se efectua anti-rebote ni auto-repetición. Si es 255 se eliminan rebotes, pero no auto-repetición.

 

     IF led1 and led3 = 1 then

   led3 = 1

 

    else

    led3 = 0

 

     endif

    


Btn3:

    BUTTON PORTA.3,0,255,1,b3,0,btn4                ' Rate Valor de auto-repetición (0-255)

 

    TOGGLE LED4

Btn4:

    BUTTON PORTA.4,0,255,1,b4,0,btn5                ' Bvar Variable con tamaño de byte usada internamente para conteo de demoras y repeticiones.

 

    TOGGLE LED5                                      ' Debe ser inicializada a 0 antes de ser usada y no ser usada en cualquier lugar del programa.

Btn5:

    BUTTON PORTA.6,0,255,1,b5,0,btn6                ' Action Estado del pulsador al ser actuado.

 

    TOGGLE LED6

Btn6:                                                                              ' Etiqueta La ejecución comienza en esta etiqueta si es cierto Action.

    BUTTON PORTA.7,0,255,1,b6,0,BTNS'btn0

 

    TOGGLE LED7

    Goto BTNS'Btn0

    END


'Btn7:

   ' BUTTON PORTA.8,0,255,1,b7,0,Btn0

    'TOGGLE LED8

    'Goto Btn0

    'END



'goto BTNS

ESPACIO: ;programa de antirrebote de teclas

IF btn1 = 0 THEN ESPACIO  ;si la tecla sigue pulsada ir espacio

pause 10

return
 

Adjuntos

  • BTN LOGIC.zip
    82.7 KB · Visitas: 1
Atrás
Arriba