another state machine example


+ Reply to Thread
Results 1 to 3 of 3
  1. #1
    Join Date
    May 2013
    Location
    australia
    Posts
    1,945

    Default another state machine example

    on the other forum this was asked

    I'd like to create a millisecond counter with a range from 5 milliseconds to 40 milliseconds. It does not have to be resolved to a single millisecond; e.g. need to know when it's hit each in a series of N+5 (5,10,15,20,25,30,35,40) milliseconds known. There'll be a photo interrupter reading an aperture in a disk and possibly be 8 LEDs each designating those 8 positions. Sort of like how an LED guitar tuner displays; 1st LED=5ms, 2nd=10ms, 3rd=15ms, etc.
    Will I need a subroutine to avoid inaccuracy? Can I get by with PULSIN?
    http://support.melabs.com/forum/picb...unter#post8333

    no complete code solution was asked for. seemed a waste so i will post my idea here as an example of a state machine solution rather than waste the effort
    the asm code is a leftover of first implementing a full charlieplexer for the leds , until i realized there was never a need to show more than one at any one time
    and cut it down to a charlie with no plexer

    Name:  Screenshot 2021-10-19 203559.jpg
Views: 61
Size:  136.8 KB

    Code:
     ;@ 12f1822#CONFIG
      __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
      __config _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_19 & _LVP_OFF
    #ENDCONFIG
    
    
    
    
    goto overasm 
    asm
    pc_val           ;led charlieplex lata data 
        addwf   PCL, F                   
        retlw 	2       
        retlw 	1             	
        retlw 	1   
        retlw 	4
        retlw 	1
        retlw 	32                         
        retlw 	2  
        retlw 	4
        retlw 	2
    tc_val             ;led charlieplex trisa data 
        addwf   PCL, F           
        retlw 252
        retlw 252
        retlw 250
        retlw 250
        retlw 222 
        retlw 222 
        retlw 249
        retlw 249
        retlw 221
    _LDS     ;SHOW LED  X=1 TO 9
        BANKSEL LATA       ;start with all LEDS  off
        clrf LATA
        BANKSEL TRISA
        movlw 0xff
        IORWF TRISA,F
        BANKSEL 0
        decf _ledx ,w          
        L?CALL  tc_val      ;lookup tris value
        BANKSEL TRISA
        MOVWF  TRISA
        BANKSEL  _ledx
        decf _ledx,W
        L?CALL  pc_val      ;lookup port value
        BANKSEL LATA               
        MOVWF  LATA         ;ignite the led
        BANKSEL 0  
        RETURN 
     endasm
    overasm:
    
    
    DEFINE OSC 16
    OSCCON = $78
    ANSELA = 0
    
    
    TRIGGER  VAR       PORTa.4    ;timer gate control pin
    timer    var word  ext        ;the result in uS
    ledx     var byte  bank0      ;current led to ignite   1-9
    tmp      var word             ;temporary store 
    state    VAR BYTE             ;current state of machine  0, uninitialised  1, seeking pulse  2, pulse detected  3, good result 4, error
    old_state VAR BYTE            ;previous state of machine 
    @timer = TMR1L                ;alias tmr1 to timer var
    clear
    
    
    'post
    FOR  ledx= 1 TO 9
        CALL LDS     ;SHOW LEDx  
        pause 80
    NEXT
    
    
    IOCAN.4 = 1      ;SET FALLING EDGE DETECTION INT ON TRIGGER PIN 
    T1CON   = $20    ;timer off
    T1GCON  = $c0    ;timer gate control to count on high gate
    state   = 1      ;all done lets go
    
    
    MAIN:
        if state != old_state then        ;manage state change
            if state == 1 then            'reset timer
                pir1.0 = 0
                TIMER = 0
                T1CON.0 = 1
                ledx= 9           ;led 9 on
                CALL LDS
                IOCAF=0
            elseif state == 2   then      ;evaluate result
                if pir1.0 then    ;timer overflow
                    ledx= 4       ;led overflow on
                    state = 4                     
                elseif timer < 4800 then  ;too short
                    ledx= 8       ;led UNDER on
                    state = 4 
                elseif timer > 40200 then ;too long
                    ledx= 1       ;led OVER on
                    state = 4 
                else                      ;goldilocks
                    TMP = TIMER / 5000 - 1
                    IF TIMER // 5000 > 2499 THEN TMP = TMP + 1    ;round up
                    ledx= 8 - TMP ;led ledx on
                    state = 3 
                endif
                CALL LDS      ;SHOW LEDx
                TMP=1500        ;15 sec timeout to show result then reset
            endif
            old_state = state      
        endif
        select case state     ;manage current state  
            case  1           ;SEEKING A PULSE CAPTURE EVENT
                IF IOCAF.4 || pir1.0   THEN    ;FALLING  EDGE ON TRIGGER PIN DETECTED or overflow
                    T1CON.0 = 0     ;stop timer no retriggering
                    LATA = 0        'led9 oFF show pulse captured
                    state = 2 
                endif
            case  3           ;good result show it
                if tmp then           ;15 sec timeout then reset
                    TMP = TMP - 1     
                else
                    state = 1         ;then reset
                endif  
            case  4           ;error condition flash ledx
                if tmp then           ;15 sec timeout countdown then reset
                    if tmp//50==0 then LATA = 0    
                    if tmp//50==25 then CALL LDS  
                    TMP = TMP - 1     
                else
                    state = 1         ;then reset
                endif     
        end select 
              PAUSE   10       ;set loop to 10 mS 
    GOTO   MAIN
    Last edited by richard; - 19th October 2021 at 11:42.
    This is more entertaining than Free to Air TV

  2. #2
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,124

    Default Re: another state machine example

    A great piece of programming example that shows what a tiny PIC can do!

    Thanks Richard for the lessons!

    Ioannis

  3. #3
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,124

    Default Re: another state machine example

    And while on Finite State Machine, here is a great tutorial on this subject by Tracey Allen:

    http://emesystems.com/OLDSITE/BS2fsm.htm

    Ioannis

Similar Threads

  1. reading I/O state of pic12f675...
    By iw2fvo in forum mel PIC BASIC Pro
    Replies: 21
    Last Post: - 14th May 2017, 09:50
  2. Replies: 4
    Last Post: - 17th May 2014, 18:24
  3. DC - AC Solid State Relay
    By shahidali55 in forum General
    Replies: 6
    Last Post: - 10th November 2007, 17:01
  4. State machine programming
    By tjstevens in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 17th April 2007, 23:45
  5. Replies: 2
    Last Post: - 27th March 2007, 13:48

Posting Permissions

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