Loop issues


Closed Thread
Results 1 to 19 of 19

Thread: Loop issues

  1. #1
    Join Date
    Feb 2004
    Location
    Michigan, USA
    Posts
    305

    Default Loop issues

    I have a very simple test loop that only partly functions and I cannot figure out why.


    main:
    if PortB.0 = 0 then
    if PortB.1 = 1 then
    if PortB.4 = 1 then
    runtime = 60
    endif
    endif
    endif

    if PortB.0 = 1 then
    if PortB.1 = 1 then
    if PortB.4 = 1 then
    runtime = 90
    endif
    endif
    endif

    if PortB.0 = 1 then
    if PortB.1 = 0 then
    if PortB.4 = 0 then
    runtime = 120
    endif
    endif
    endif

    pause 1
    write 0, runtime.highbyte
    write 1, runtime.lowbyte

    if SSW = 1 then
    redport = 1
    pause 200
    redport = 0
    pause 200
    goto main
    endif

    if SSW = 0 then
    redport = 1
    goto main1
    endif

    ended = 0
    goto main


    main1:
    redport = 0
    blueport = 1
    pause 500
    redport = 0
    blueport = 0

    goto main1


    The problem is that this portion of code..

    if SSW = 0 then
    redport = 1
    goto main1
    endif


    It does turn on the LED at redport, and keeps it on while SSW = 0 but does not jump to main1, and I have no idea why.
    If SSW remains at 1 it sits in its loop and flashes the LED perfectly and detects the change to 0 every time. I'm baffled by this!

  2. #2
    Join Date
    Apr 2014
    Location
    OK
    Posts
    557


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    Just for diagnostics, try putting "goto main1" as the very first line in your "main:" If it goes there, then we need to look at something else. If not, there's something wrong with main1:.

  3. #3
    Join Date
    Feb 2013
    Posts
    1,078


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    Side question - these nesting of IF-THEN are used to avoid usage of AND/OR operators?

  4. #4
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    Side question - these nesting of IF-THEN are used to avoid usage of AND/OR operators?

    or even a little binary arithmetic

    Code:
    if PortB.0 = 0 then
    if PortB.1 = 1 then
    if PortB.4 = 1 then
    runtime = 60
    endif
    endif
    endif
    
    
    if PortB.0 = 1 then
    if PortB.1 = 1 then
    if PortB.4 = 1 then
    runtime = 90
    endif
    endif
    endif
    
    
    if PortB.0 = 1 then
    if PortB.1 = 0 then
    if PortB.4 = 0 then
    runtime = 120
    endif
    endif
    endif
    shrinks to
    Code:
    if PortB&19 == 18 then
    runtime = 60
    elseif PortB&19 == 19 then
    runtime = 90
    elseif PortB&19 == 1 then
    runtime = 120
    endif

    with regard to the loop

    if SSW = 1 then ???????????? what is ssw

    snippets are a total failure as usual

    could be the pin if its a pin is still set to analog
    Last edited by richard; - 24th September 2021 at 08:35.
    Warning I'm not a teacher

  5. #5
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,795


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    Code:
    main1:
    redport = 0
    blueport = 1
    pause 500
    redport = 0
    blueport = 0
    
    goto main1
    
    
    The problem is that this portion of code..
    
    if SSW = 0 then
    redport = 1
    goto main1
    endif
    in this part of the code, if SSW=0, the redport will be on for a very narrow time frame. I doubt that you will be able to see it. And then it will loop for ever in the main1.

    Ioannis
    Last edited by Ioannis; - 25th September 2021 at 21:41.

  6. #6
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    in this part of the code, if SSW=0, the redport will be on for a very narrow time frame. I doubt that you will be able to see it. And then it will loop for ever in the main1.

    whatever redport is , might be a bit var that could never be seen

    the snippet is useless , so many things undefined
    Warning I'm not a teacher

  7. #7
    Join Date
    Feb 2004
    Location
    Michigan, USA
    Posts
    305


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    Here's the entire code.
    Redport = 0 was a typo and should have been = 1. The loop worked once I disabled the external oscillator requirements for timer1.
    18F1320 using internal 8MHz oscillator (because I have hundreds of them from a past project! :-) )

    So this code is almost there functionally but has a couple of problems.

    The project is to run some high power LED's for either 60, 90, 120 seconds. There is a lid that has to be closed (SSW=1) before it will allow the LED's to be turned on. If the lid is open, it will just sit there and flash redport until the lid is closed. At this point with lid closed, the redport indicator led will be on solid and it'll move into main1.
    The main LED's get turned on with a momentary push button switch by the user. The timer should start, count up until Runtime is reached, switch off the LED's (enable1 and enable2 = 0) turn on greenport which is a green "done" indicator LED, and it should sit there until the lid is opened again.
    On lid open it should return to the first loop and flash redport until the lid is closed again. While the timer is counting and the main LED's are on it has to monitor for the lid being opened and shut off the main LED's and return to the first loop with the counter ready to start at Runtime.

    So that said here is what works:
    It sets up correctly, will load either 60, 90 or 120 in to Runtime, will sit and flash redport with the lid open.
    It will go in to main1 with a solid redport and wait for the pushbutton input (Startswitch)
    It will turn on the timer, count and when done will turn off the main LED's and turn on greenport and sit there until the lid is lifted (SSW=1)

    What isn't working is:
    Its not counting to the correct number in Runtime. I use greenport in the timer loop to basically have a pulse to look at on the scope showing that the timer is indeed running, and it is. The pulses are approx 1ms apart but they are only running 50% of the time. So say 100 pulses 1ms apart (I haven't counted the actual number yet) then nothing for 100ms then 100 pulses 1ms apart etc etc.
    Currently it runs for about 630ms if Runtime = 60, about 900ms if Runtime = 90 and never turns off if Runtime = 120. I added the thousandths to see if I could increase the on time and it doesn't respond, staying on all the time. When the lid is lifted it does interesting things and gives a wonderful flashing combination of the red green and blue indicator LED's. Clearly I'm setting up the timer wrong but I'm not sure what I'm doing wrong at this point and could use some fresh eyes.
    Last edited by jmgelba; - 28th September 2021 at 02:24.

  8. #8
    Join Date
    Feb 2004
    Location
    Michigan, USA
    Posts
    305


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    OSCCON = %01110011
    DEFINE OSC 8
    DEFINE WRITE_INT 1
    Include "modedefs.bas"

    SSW var PortA.7
    redport var PortB.5
    blueport var PortB.7
    greenport var PortB.6
    enable1 var PortB.2
    enable2 var PortB.3
    runtime var word
    RunningFlag var BIT
    Startswitch var PortA.3
    ended var bit
    Thousandths var word
    Hundredths var word
    Seconds var word
    comp var bit


    adcon0.0 = 0
    adcon1.3 = 1
    adcon1.4 = 1
    adcon1.5 = 1
    adcon1.6 = 1
    TRISA = %11111000
    TRISB = %00010011
    PortB.5 = 0
    PortB.2 = 0
    T1CON = %00000100

    comp = 0
    redport = 0
    greenport = 0
    blueport = 0
    enable1 = 0
    enable2 = 0
    ended = 0
    runningflag = 0
    thousandths = 0
    Hundredths = 0
    Seconds = 0

    Gosub SetTimer

    blueport = 1 'testing outputs
    pause 2000
    blueport = 0
    greenport = 1
    pause 2000
    greenport = 0

    On Interrupt goto Starttimer
    PIE1.0=1 ' Enable TMR1 Interrupts
    INTCON.6=1 ' Enable all unmasked Interrupts
    INTCON.7=1 ' Enable Global Interrupts



    main:

    if PortB.0 = 0 then
    if PortB.1 = 1 then
    if PortB.4 = 1 then
    runtime = 60
    endif
    endif
    endif

    if PortB.0 = 1 then
    if PortB.1 = 1 then
    if PortB.4 = 1 then
    runtime = 90
    endif
    endif
    endif

    if PortB.0 = 1 then
    if PortB.1 = 0 then
    if PortB.4 = 0 then
    runtime = 120
    endif
    endif
    endif

    write 5, runtime

    if SSW = 1 then
    redport = 1
    pause 200
    redport = 0
    pause 200
    goto main
    endif

    if SSW = 0 then
    redport = 1
    goto main1
    endif

    goto main

    'main code loop

    Enable
    main1:

    if ssw = 1 then 'checks to see if lid is closed, if not,
    goto main 'go back to first loop and wait
    endif 'if lid is closed, continue on to next requirement

    if SSW = 0 and startswitch = 1 then 'starts the first run of the timer if lid
    ended = 0 'is closed and push button has been pressed
    runningflag = 1 'and sets a flag to show timer is running
    GOSUB StartTimer
    endif

    if runningflag = 1 then 'checks to see if timer was started and
    gosub starttimer 'if true loops for next cycle
    endif

    goto main1
    disable




    completed:
    T1CON.0=0
    enable1 = 0
    enable2 = 0
    greenport = 1
    redport = 0
    blueport = 0
    runningflag = 0
    comp = 1
    if ssw = 1 then
    greenport = 0
    goto main
    endif
    goto completed
    return

    '
    ' Subroutine Loads TMR1 values
    ' ============================
    SetTimer:
    T1CON.0=0 ' Stop the Clock
    TMR1H=$B1
    TMR1L=$e7
    PIR1.0=0 ' Reset TMR1's Interupt Flag
    Return

    ' Subroutine to stop the timer, reset, and shutoff outputs
    Stoptimer:
    T1CON.0=0
    TMR1H=$B1
    TMR1L=$E7
    PIR1.0=0
    enable1 = 0
    enable2 = 0
    thousandths = 0
    Hundredths = 0
    Seconds = 0
    redport = 0
    blueport = 0
    greenport = 1
    runningflag = 0
    ended = 1
    'gosub settimer
    Pause 1000
    return


    Starttimer:
    redport = 1 'output to show timer is running
    blueport = 1
    greenport = 0 'provides a pulse to measure for diagnostics to check timer is actually running
    greenport= 1
    greenport = 0
    enable1 = 1 'turns on both LED channels
    enable2 = 1
    Gosub SetTimer ' Set the Timer for next Interrupt
    If RunningFlag=1 then ' If timing actually enabled then continue
    thousandths=thousandths+1
    if thousandths>999 then
    thousandths=0
    Hundredths=Hundredths+1
    If Hundredths>99 then
    Hundredths=0
    Seconds=Seconds+1
    write 10, seconds 'just to see if it turns off at runtime seconds
    ' Increment the Seconds

    if seconds = runtime then
    gosub stoptimer
    goto completed
    endif
    endif
    endif
    endif

    if ssw = 1 then
    gosub stoptimer
    goto main
    endif

    Resume

    End

  9. #9
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,795


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    1. RMW issue here:

    greenport = 0 'provides a pulse to measure for diagnostics to check timer is actually running
    greenport= 1
    greenport = 0

    I think you will not see the greenport change because of RMW issue. It depends on the capacitive load of the port though.

    2. SetTimer turns off the timer.

    So the rest of the commands after this line

    Gosub SetTimer ' Set the Timer for next Interrupt

    I guess are not executed.

    The Interrupt routine should be less loaded also.

    If time allows I will try to see more on your code.

    Ioannis

  10. #10
    Join Date
    Feb 2004
    Location
    Michigan, USA
    Posts
    305


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    Ioannis, thank you for your reply. I do actually see a pulse and have been using it to measure changes I've been making, although it is always fairly constant at about 1ms pulse to pulse. I'll assume this is because I'm turning off the timer rather than letting it run. Interestingly though, it does stop when seconds = runtime. Its just that seconds aren't 1000ms long :-D Uff just checked, 68uS between pulses, not 1ms as previously stated.
    Last edited by jmgelba; - 28th September 2021 at 11:48.

  11. #11
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    There are many issues



    starting here
    1.
    Code:
    disable ;  missing
    Starttimer:
    redport = 1 'output to show timer is running
    blueport = 1
    greenport = 0 'provides a pulse to measure for diagnostics to check timer is actually running
    greenport= 1
    greenport = 0
    enable1 = 1 'turns on both LED channels
    enable2 = 1
    Gosub SetTimer ' Set the Timer for next Interrupt   ;  never a good look  in a isr
    If RunningFlag=1 then ' If timing actually enabled then continue
    thousandths=thousandths+1 ;////   the isr  is set to 10mS   wtf
    if thousandths>999 then 
    thousandths=0
    Hundredths=Hundredths+1
    If Hundredths>99 then  ; what how
    Hundredths=0
    Seconds=Seconds+1
    write 10, seconds 'just to see if it turns off at runtime seconds
    ' Increment the Seconds
    
    
    if seconds = runtime then
    gosub stoptimer
    goto completed
    endif
    endif
    endif
    endif
    
    
    if ssw = 1 then
    gosub stoptimer
    goto main    you should never do this in an interrupt 
    endif
    
    
    Resume
    enable ;lmissing


    you cannot call a isr as a subroutine . there is no return
    2.
    Code:
    if SSW = 0 and startswitch = 1 then 'starts the first run of the timer if lid
    ended = 0 'is closed and push button has been pressed
    runningflag = 1 'and sets a flag to show timer is running
    GOSUB StartTimer
    endif
    3.
    the timer timer 1 is never turned on

    4.
    'INTCON.7=1 ' Enable Global Interrupts no do not do this

    this works
    Code:
    #CONFIG  CONFIG  OSC=INTIO1, FSCM=ON, IESO=ON, PWRT=OFF, BOR=ON, BORV=27, WDT=ON
      CONFIG  WDTPS=512, MCLRE=ON, STVR=ON, LVP=OFF, DEBUG=OFF, CP0=OFF, CP1=OFF
      CONFIG  CPB=OFF, CPD=OFF, WRT0=OFF, WRT1=OFF, WRTC=OFF, WRTB=OFF, WRTD=OFF
      CONFIG  EBTR0=OFF, EBTR1=OFF, EBTRB=OFF
    #ENDCONFIG
    OSCCON = 110011
    DEFINE OSC 8
    DEFINE WRITE_INT 1
    'Include "modedefs.bas"
        DEFINE DEBUG_REG PORTA
        DEFINE DEBUG_BIT 0      ;  if not used for pwr  
        DEFINE DEBUG_BAUD 9600
        DEFINE DEBUG_MODE 0     
        pause 2000
        Debug "Start",13 ,10  
    
    
    SSW var PortA.7
    redport var PortB.5
    blueport var PortB.7
    greenport var PortB.6
    enable1 var PortB.2
    enable2 var PortB.3
    runtime var word
    RunningFlag var BIT
    Startswitch var PortA.3
    ended var bit
    Thousandths var word
    
    
    Seconds var word
    comp var bit
    
    
     adcon1=$7f
    'adcon0.0 = 0
    'adcon1.3 = 1
    'adcon1.4 = 1
    'adcon1.5 = 1
    'adcon1.6 = 1
    TRISA = 111000
    TRISB = 010011
    PortB.5 = 0
    PortB.2 = 0
    T1CON=0
    TMR1H=$B1     ;10mS
    TMR1L=$e7
    lata.0=0   ;debug
    
    
     pause 1000
        Debug "Start",13 ,10  
    comp = 0
    redport = 0
    greenport = 0
    blueport = 0
    enable1 = 0
    enable2 = 0
    'ended = 0
    runningflag = 0
    thousandths = 0
    
    
    Seconds = 0
    
    
    
    
    
    
    blueport = 1 'testing outputs
    pause 200
    blueport = 0
    greenport = 1
    pause 200
    greenport = 0
    
    
    T1CON.0=0
    On Interrupt goto Starttimer
    PIE1.0=1 ' Enable TMR1 Interrupts
    INTCON.6=1 ' Enable all unmasked Interrupts
    'INTCON.7=1 ' Enable Global Interrupts 
    
    
    
    
    
    
    main:
    if (PortB&19) == 18 then
        runtime = 10
    elseif (PortB&19) == 19 then
        runtime = 90
    elseif (PortB&19) == 1 then
        runtime = 120
    endif
    
    
    'Debug "runtime ",dec runtime," ",dec portb,13 ,10  
    ''write 5, runtime
    'pause 2000
    if SSW = 1 then
        redport = 1
        pause 200
        redport = 0
        pause 200
        goto main
    endif
    
    
    if SSW = 0 then
        redport = 1
        goto main1
    endif
    
    
    goto main
    
    
    'main code loop
    
    
    Enable
    main1:
        Debug "main1",dec runtime,13 ,10 
        if ssw = 1 then 'checks to see if lid is closed, if not,
            goto main 'go back to first loop and wait
        endif 'if lid is closed, continue on to next requirement
        if (SSW = 0 )and (startswitch = 1) then 'starts the first run of the timer if lid
    '        Debug "start",dec runtime,13 ,10 
            runningflag = 1 'and sets a flag to show timer is running
            T1CON.0=1 ; timer on
            enable1 = 1
            enable2 = 1
            blueport = 1
            comp = 0
            while runningflag: wend  
            enable1 = 0
            enable2 = 0
            greenport = 1
            blueport = 0
            comp = 1
            redport = 0
        endif
        if comp==1 then
        WHILE  SSW = 0 : wend  
        greenport = 0
        Debug "DUNN",dec runtime,13 ,10 
        ENDIF
        goto main
            
    goto main1
    
    
    end
    
    
        disable
    Starttimer:
        lata.1=1 ;debug to clock  time
        T1CON.0=0
        TMR1H=$B1+TMR1H     ;10mS
        TMR1L=$e7 +TMR1L
        if STATUS.0 THEN  TMR1H =TMR1H +1
        PIR1.0=0 ' Reset TMR1's Interupt Flag
        T1CON.0=1
        thousandths=thousandths+10
        if thousandths>999 then
            thousandths=0
            Seconds=Seconds+1
        endif
        if (seconds = runtime) || (ssw = 1) then
            runningflag = 0
            T1CON.0=0
        endif
        lata.1=0;debug to clock  time
        Resume
        enable
    End


    my view of schematic
    Name:  Screenshot 2021-09-28 194517.jpg
Views: 463
Size:  145.6 KB
    Last edited by richard; - 28th September 2021 at 11:58.
    Warning I'm not a teacher

  12. #12
    Join Date
    Feb 2004
    Location
    Michigan, USA
    Posts
    305


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    Wow Richard, thanks for that! I guess I was way off. I used Melanie's Olympic Timer as the basis for my code and she included some of the things that you have advised against such as adding the SetTimer subroutine call in the Starttimer routine and INTCON.7=1.

    I tried your code and needed to change a few things.

    OSCCON = 110011
    TRISA = 111000
    TRISB = 010011

    became

    OSCCON = %01110011
    TRISA = %11111000
    TRISB = %00010011

    in order to compile.

    If you open the lid while its running and close it again, then push the start button, it doesn't turn on the outputs and start timing again. It does jump back to main, it will jump in to main1 and put the red led on solid, but doesn't run main1.
    If the switch is in the 60 second run position it runs for about 10 seconds - which I saw you had runtime = 10 so I changed that.
    In the 90 second position it runs for 90 seconds - perfect.
    In the 120 second position it ends almost instantly. I noticed this would happen sometimes in my code too. 100 and less and it works each time. I don't know what this phenomena is.
    Last edited by jmgelba; - 28th September 2021 at 16:01.

  13. #13
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    we are still in a covid lockdown [no 5 i think ] hence i'm bored shitless and will do anything that takes my interest

    yes the forum has the ability to eat % symbols

    If the switch is in the 60 second run position it runs for about 10 seconds - which I saw you had runtime = 10 so I changed that.
    60 seconds is too long to wait while testing

    In the 120 second position it ends almost instantly. I noticed this would happen sometimes in my code too. 100 and less and it works each time. I don't know what this phenomena is.
    not on the simulator , works ok at all settings




    if you want to be able to run code repeatedly then seconds and comp need to be reset to zero before a rerun
    like this
    Code:
    #CONFIG  CONFIG  OSC=INTIO1, FSCM=ON, IESO=ON, PWRT=OFF, BOR=ON, BORV=27, WDT=ON
      CONFIG  WDTPS=512, MCLRE=ON, STVR=ON, LVP=OFF, DEBUG=OFF, CP0=OFF, CP1=OFF
      CONFIG  CPB=OFF, CPD=OFF, WRT0=OFF, WRT1=OFF, WRTC=OFF, WRTB=OFF, WRTD=OFF
      CONFIG  EBTR0=OFF, EBTR1=OFF, EBTRB=OFF
    #ENDCONFIG
    OSCCON = % 01110011
    DEFINE OSC 8
    
    
        DEFINE DEBUG_REG PORTA
        DEFINE DEBUG_BIT 0        
        DEFINE DEBUG_BAUD 9600
        DEFINE DEBUG_MODE 0     
        pause 2000
        Debug "Start",13 ,10  
    
    
    SSW var PortA.7
    redport var PortB.5
    blueport var PortB.7
    greenport var PortB.6
    enable1 var PortB.2
    enable2 var PortB.3
    runtime var word
    RunningFlag var BIT
    Startswitch var PortA.3
    ended var bit
    Thousandths var word
    Seconds var word
    comp var bit
    
    
    adcon1=$7f
    TRISA = % 11111000
    TRISB = % 00010011
    PortB.5 = 0
    PortB.2 = 0
    T1CON=0
    TMR1H=$B1     ;10mS
    TMR1L=$e7
    lata.0=0   ;debug
    
    
    pause 1000
    Debug 13 ,10 ,"ready",13 ,10  
    comp = 0
    redport = 0
    greenport = 0
    blueport = 0
    enable1 = 0
    enable2 = 0
    runningflag = 0
    thousandths = 0
    Seconds = 0
    
    
    
    
    blueport = 1 'testing outputs
    pause 200
    blueport = 0
    greenport = 1
    pause 200
    greenport = 0
    
    
    T1CON.0=0
    On Interrupt goto Starttimer
    PIE1.0=1 ' Enable TMR1 Interrupts
    INTCON.6=1 ' Enable all unmasked Interrupts
    
    
    
    
    main:
        if (PortB&19) == 18 then
            runtime = 10
        elseif (PortB&19) == 19 then
            runtime = 90
        elseif (PortB&19) == 1 then
            runtime = 120
        endif
        if SSW = 1 then
            redport = 1
            pause 200
            redport = 0
            pause 200
            goto main
        endif
        if SSW = 0 then
            redport = 1
            comp=0
            goto main1
        endif
    goto main
    
    
    'main code loop
    
    
    Enable
    main1:
    '    Debug "main1 loop ",dec runtime,13 ,10 
        if ssw = 1 then 'checks to see if lid is closed, if not,
            goto main 'go back to first loop and wait
        endif 'if lid is closed, continue on to next requirement
        if (SSW = 0 )and (startswitch = 1) then 'starts the first run of the timer if lid
    '        Debug "start",dec runtime,13 ,10 
            runningflag = 1 'and sets a flag to show timer is running
            T1CON.0=1
            enable1 = 1
            enable2 = 1
            blueport = 1
            comp = 0
            while runningflag: wend  
            enable1 = 0
            enable2 = 0
            greenport = 1
            blueport = 0
            comp = 1
            redport = 0
        endif
        if comp==1 then
            Debug "DUNN",dec runtime,13 ,10 
            WHILE  SSW = 0 : wend  
            greenport = 0
        ENDIF
        goto main
    goto main1
    
    
    end
    
    
    
    
        disable
    Starttimer:
        lata.1=1
        T1CON.0=0
        TMR1H=$B1+TMR1H     ;10mS
        TMR1L=$e7 +TMR1L
        if STATUS.0 THEN  TMR1H =TMR1H +1
        PIR1.0=0 ' Reset TMR1's Interupt Flag
        T1CON.0=1
        thousandths=thousandths+10
        if thousandths>999 then
            thousandths=0
            Seconds=Seconds+1
        endif
        if (seconds = runtime) || (ssw = 1) then
            seconds = 0
            runningflag = 0
            T1CON.0=0
        endif
        lata.1=0
        Resume
        enable
    End
    Warning I'm not a teacher

  14. #14
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    a state machine approach simplifies the logic enormously , has a much more predictable result
    and is vastly simpler to debug

    Code:
    #CONFIG  CONFIG  OSC=INTIO1, FSCM=ON, IESO=ON, PWRT=OFF, BOR=ON, BORV=27, WDT=ON
      CONFIG  WDTPS=512, MCLRE=ON, STVR=ON, LVP=OFF, DEBUG=OFF, CP0=OFF, CP1=OFF
      CONFIG  CPB=OFF, CPD=OFF, WRT0=OFF, WRT1=OFF, WRTC=OFF, WRTB=OFF, WRTD=OFF
      CONFIG  EBTR0=OFF, EBTR1=OFF, EBTRB=OFF
    #ENDCONFIG
    OSCCON = %01110000
    DEFINE OSC 8
    
    
        DEFINE DEBUG_REG PORTA
        DEFINE DEBUG_BIT 0       
        DEFINE DEBUG_BAUD 9600
        DEFINE DEBUG_MODE 0     
       
    
    
    SSW var PortA.7
    redport var latB.5
    blueport var latB.7
    greenport var PortB.6
    enable1 var PortB.2
    enable2 var PortB.3
    runtime var word
    RunningFlag var BIT
    comp var bit
    Startswitch var PortA.3
    ended var bit
    Thousandths var word
    Seconds var word
    now     var word
    machine_state var byte ; [ 0  lid up  1  waiting to start 2 running 3 ended]
    old_state var byte
    timer1_reload con    45543 ;10mS
    DEFINE INTHAND   timer          ;COMMENT OUT IF DT_INTS USED
    goto   overasm
    asm
    timer      ;tmr1 isr
        MOVE?CT 0, T1CON, TMR1ON ; 1 stop timer
        MOVLW LOW(_timer1_reload) ; 1 Add TimerReload to the 
        ADDWF TMR1L,F ; 1 value in Timer1
        BTFSC STATUS,C ; 1/2
        INCF TMR1H,F ; 1
        MOVLW HIGH(_timer1_reload) ; 1
        ADDWF TMR1H,F ; 1
        MOVE?CT 1, T1CON, TMR1ON ; 1 start timer
        banksel  _Thousandths
        INCF _Thousandths
        BTFSC STATUS,C 
        INCF _Thousandths+1
        BANKSEL PIR1      ;COMMENT OUT IF DT_INTS USED
        BCF PIR1   ,0     ;COMMENT OUT IF DT_INTS USED
        RETFIE            ;COMMENT OUT IF DT_INTS USED
        endasm 
    overasm:
     
    adcon1=$7f
    TRISA = %11111000
    TRISB = %00010011
    PortB = 0
    T1CON=0
    TMR1H=$B1     ;10mS
    TMR1L=$e7
    PIE1.0=1 ' Enable TMR1 Interrupts
    INTCON.6=1 ' Enable all unmasked Interrupts' 
    lata.0=1   ;debug
     pause 1000
        Debug "Start",13 ,10 
    clear
    'post
    latB = 32
    pause 200
    latB =64
    pause 200
    latB =128
    pause 200
    latB =0 
    T1CON=1
    INTCON.7=1 
     
    main:
        T1CON=0
        now  =  thousandths
        T1CON=1
        if SSW  then machine_state = 0 
        if old_state !=  machine_state then
        Debug 13 ,10 , "new state " 
            select case   machine_state
            case 0
                 latB = latB &  ~204    ; blue,green,ena,enb all off
                 Debug dec 0
            case 1  
            if (PortB&19) == 18 then
                runtime = 1000
            elseif (PortB&19) == 19 then
                runtime = 9000
            elseif (PortB&19) == 1 then
                runtime = 12000
            endif    
            redport = 1
            Debug dec 1,"rt ",dec  runtime
            case 2
               latB = latB | 12      ;ena,enb on
               Seconds =  now
               blueport = 1
               redport = 0
               Debug dec 2
            case 3
               latB = latB &  ~12      ;ena,enb off
               blueport = 0
               greenport = 1
               redport = 0
               Debug dec 3
            end select 
            old_state =  machine_state  
        endif
        select case   machine_state
        case 0
           if now//20=0 then  redport = !redport
           if ssw==0  then machine_state =1 
        case 1
            if startswitch == 1 then machine_state =2
        case 2 
            if  now - Seconds > runtime then machine_state=3
        end select
        pause 10
    goto main
    
    
    end
    Warning I'm not a teacher

  15. #15
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    new cleaned up version with comments

    just to emphasize the versality of state machine approach
    debounce of start button added
    validation of runtime selection added



    Code:
    '****************************************************************'
    *  Name    : UNTITLED.BAS                                      *
    '*  Author  : richard                                           *
    '*  Notice  : Copyright (c) 2021 caveat emptor                  *
    '*          : All Rights Reserved                               *
    '*  Date    : 28/09/2021                                        *
    '*  Version : 1.0                                               *
    '*  Notes   :  18f1320                                          *
    '*          :                                                   *
    '****************************************************************
    #CONFIG
      CONFIG  OSC=INTIO1, FSCM=ON, IESO=ON, PWRT=OFF, BOR=ON, BORV=27, WDT=ON
      CONFIG  WDTPS=512, MCLRE=ON, STVR=ON, LVP=OFF, DEBUG=OFF, CP0=OFF, CP1=OFF
      CONFIG  CPB=OFF, CPD=OFF, WRT0=OFF, WRT1=OFF, WRTC=OFF, WRTB=OFF, WRTD=OFF
      CONFIG  EBTR0=OFF, EBTR1=OFF, EBTRB=OFF
    #ENDCONFIG
    
    
    DEFINE OSC 8
    
    
    
    
    DEFINE DEBUG_REG PORTA      ;debug
    DEFINE DEBUG_BIT 0       
    DEFINE DEBUG_BAUD 9600
    DEFINE DEBUG_MODE 0
    
    
    SSW var PortA.7
    red var latB.5   ;use lat to avoid rmw
    blue var latB.7     
    green var latB.6
    enable1 var latB.2
    enable2 var latB.3
    Startswitch var PortA.3
    
    
    runtime var word
    Thousandths var word     ; can measure upto 655 seconds in 10mS quanta
    Seconds var word
    now     var word
    machine_state var byte ; possible states [ 0 lid up, 1 waiting for start button, 2 running, 3 ended]
    old_state var byte
    start    var byte
    timer1_reload con    45543 ;10mS
    
    
    DEFINE INTHAND   ticker          
    goto   overasm
    asm
    ticker      ;tmr1 isr
        MOVE?CT 0, T1CON, TMR1ON ; 1 stop timer
        MOVLW LOW(_timer1_reload) ; 1 Add TimerReload to the 
        ADDWF TMR1L,F ; 1 value in Timer1
        BTFSC STATUS,C ; 1/2
        INCF TMR1H,F ; 1
        MOVLW HIGH(_timer1_reload) ; 1
        ADDWF TMR1H,F ; 1
        MOVE?CT 1, T1CON, TMR1ON ; 1 start timer
        banksel  _Thousandths
        INCF _Thousandths
        BTFSC STATUS,C 
        INCF _Thousandths+1
        BANKSEL PIR1      
        BCF PIR1   ,0     
        RETFIE            
        endasm 
    overasm:
    
    
    OSCCON = %01110000 
    adcon1=$7f
    TRISA = %11111000
    TRISB = %00010011
    PortB = 0
    T1CON=0
    TMR1H=$B1     ;10mS
    TMR1L=$e7
    PIE1.0=1 ' Enable TMR1 Interrupts
    INTCON.6=1 ' Enable all unmasked Interrupts' 
    lata.0=1   ;debug
    clear
    
    
    pause 1000          ;debug
    Debug "Start",13 ,10   ;debug
    
    
    'post
    latB = 32
    pause 200
    latB =64
    pause 200
    latB =128
    pause 200
    latB =0 
    
    
     ;isr begin
    T1CON=1   ;timer on
    INTCON.7=1  
     
    main:
        T1CON=0
        now  =  thousandths    ; get current time
        T1CON=1
        start=start<<1 + startswitch  ;debounce startswitch
        if SSW  then machine_state = 0     ; lid up emergency stop ??
        if old_state !=  machine_state then       ; manage changes of state
            Debug 13 ,10 , "new state "     ;debug
            select case   machine_state            ; the new state
            case 0                   ;lid up ,all stop
                 latB = latB &  ~204    ; blue,green,ena,enb all off
                 Debug dec 0                 ;debug
            case 1                   ;lid down read runtime then we are good to go
                runtime = 0    ; default if incorrect sw setting ie 0 2 3 16 17  
                if (PortB&19) == 18 then     ;runtime is sec * 100    read from dipsw on b0,1,4  
                    runtime = 500                 '5
                elseif (PortB&19) == 19 then
                    runtime = 9000                '90
                elseif (PortB&19) == 1 then
                    runtime = 12000               '120
                endif  ;  validate  that  rt sw setting is valid  1 18 or 19 as not  all posdibilites have a result
                if   runtime == 0 then  machine_state = 0   ; abort invalid runtime  red slow flash
                if   machine_state then  red = 1                ;red on solid
                Debug dec 1,"rt = ",dec  runtime    ;debug
            case 2                       ; start button pressed
               latB =  140      ;ena,enb,blue on red off
               Seconds =  now          ;note starting time
               Debug dec 2
            case 3                     ;time up
               latB = 64      ;ena,enb,blue,red off  green on
               Debug dec 3                ;debug
            end select 
            old_state =  machine_state  
        endif
        select case   machine_state      ; manage current state
            case 0               ;monitor lid sw rapid flash red led
               if now//20==0 then  red = !red
               if ssw==0  then machine_state =1 
            case 1                   ;lid down monitor start button 
                if start == 255 then machine_state = 2
            case 2                ; running is time up ?
                if  now - Seconds > runtime then machine_state = 3 '[the beauty of unsigned subtraction}
        end select
        pause 10
    goto main
    
    
    end
    Last edited by richard; - 29th September 2021 at 07:09.
    Warning I'm not a teacher

  16. #16
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,795


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    Richard, this is a case study programming example!

    Ioannis

  17. #17
    Join Date
    Jan 2011
    Location
    Sydney, Australia
    Posts
    166


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    Ioannis, more a "select case" study programming example

    Cheers
    Barry

  18. #18
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    there are three ways to design a program for a single core chip
    1 cooperative task sharing
    2 state machine
    3 spaghetti

    two are predictable , reliable and easy to debug. both will unravel yards of spaghetti every time

    a ticker is a very useful tool for any process that needs time supervision

    put it all together and the world is your oyster


    if you have a goto in your code as a logical flow control device you are well on the way to spaghetti
    goto is the first warning sign
    Last edited by richard; - 30th September 2021 at 02:06.
    Warning I'm not a teacher

  19. #19
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    I used Melanie's Olympic Timer as the basis for my code and she included some of the things that you have advised against such as adding the SetTimer subroutine call in the Starttimer routine and INTCON.7=1.

    i should address some of these issues when using on interrupt


    subroutine call in isr
    pbp code is not re-entrant if the isr is called while the foreground task is running the same routine the result will be unpredictable
    subroutines in an isr are bad practice mostly

    INTCON.7=1
    pbp on interrupt is not a real interrupt , the int flag is simply checked on completion of every command with flow diverted if flag set
    if you actually enable interrupts where does the int vector point ? not good not needed
    Warning I'm not a teacher

Similar Threads

  1. Do Loop
    By skybox in forum mel PIC BASIC Pro
    Replies: 13
    Last Post: - 27th December 2012, 01:45
  2. Issues with a feedback loop.
    By jmgelba in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 11th June 2012, 19:54
  3. if ... then loop
    By lerameur in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 10th November 2010, 00:08
  4. Help with loop
    By wildbilly in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 2nd January 2007, 17:59
  5. While LOOP
    By actionplus in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 5th March 2004, 15:59

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts