Loop issues


Closed Thread
Results 1 to 19 of 19

Thread: Loop issues

Hybrid View

  1. #1
    Join Date
    May 2013
    Location
    australia
    Posts
    2,653


    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

  2. #2
    Join Date
    May 2013
    Location
    australia
    Posts
    2,653


    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

  3. #3
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,139


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    Richard, this is a case study programming example!

    Ioannis

  4. #4
    Join Date
    Jan 2011
    Location
    Sydney, Australia
    Posts
    172


    Did you find this post helpful? Yes | No

    Default Re: Loop issues

    Ioannis, more a "select case" study programming example

    Cheers
    Barry

  5. #5
    Join Date
    May 2013
    Location
    australia
    Posts
    2,653


    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 01:06.
    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 : 0

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