Loop issues


Closed Thread
Results 1 to 19 of 19

Thread: Loop issues

Hybrid View

  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,389


    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 07:35.
    Warning I'm not a teacher

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


    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 20:41.

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


    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
    May 2013
    Location
    australia
    Posts
    2,389


    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

  8. #8
    Join Date
    May 2013
    Location
    australia
    Posts
    2,389


    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

  9. #9
    Join Date
    May 2013
    Location
    australia
    Posts
    2,389


    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 06:09.
    Warning I'm not a teacher

  10. #10
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,809


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    Richard, this is a case study programming example!

    Ioannis

  11. #11
    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

  12. #12
    Join Date
    May 2013
    Location
    australia
    Posts
    2,389


    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, 00:45
  2. Issues with a feedback loop.
    By jmgelba in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 11th June 2012, 18:54
  3. if ... then loop
    By lerameur in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 9th November 2010, 23:08
  4. Help with loop
    By wildbilly in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 2nd January 2007, 16:59
  5. While LOOP
    By actionplus in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 5th March 2004, 14: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