Shop OBEX P1 Docs P2 Docs Learn Events
State Machine — Parallax Forums

State Machine

mminasianmminasian Posts: 26
edited 2009-07-08 00:01 in Propeller 1
I am trying to setup a simple state machine which activates two pins at a time (to be used eventually in a switching circuit). For now I am hooking up pins 0 through 4 to LEDs on my PDB. I want them to scroll through, with speed determined by a delay, and direction, by a variable. Perhaps someone can point out where I'm going wrong. I currently see no output. Any help is much appreciated. Thanks!

var
  Long machine_delay
  byte direction

pub run_machine(current_state) 
  dira[noparse][[/noparse]0..4]~~
  repeat 
  if current_state > 5
    current_state := 1
    
  case direction 
   1:
    case current_state
      1 : outa[noparse][[/noparse]0..4] := %11000 
      2 : outa[noparse][[/noparse]0..4] := %01100
      3 : outa[noparse][[/noparse]0..4] := %00110
      4 : outa[noparse][[/noparse]0..4] := %00011
      5 : outa[noparse][[/noparse]0..4] := %10001
    current_state++
    waitcnt(machine_delay + cnt)
   2:
    case current_state
      1 : outa[noparse][[/noparse]0..4] := %11000
      2 : outa[noparse][[/noparse]0..4] := %10001
      3 : outa[noparse][[/noparse]0..4] := %00011
      4 : outa[noparse][[/noparse]0..4] := %00110
      5 : outa[noparse][[/noparse]0..4] := %01100
    current_state++
    waitcnt(machine_delay + cnt)
pub get_direction
  return direction
pub set_direction (dir)
  direction := dir
pub get_delay
  return machine_delay
pub set_delay(del)
  machine_delay := del




PUB MainLoop
  machine.set_delay(2_000_000)
  machine.set_direction(1)
  'cognew(machine.run_machine(1), @Stack)
  machine.run_machine(1)
  waitcnt(300_000_000 + cnt)
  machine.set_direction(2)




(I eventually want this running on its own dedicated cog, but that's another issue i suppose)

Comments

  • TimmooreTimmoore Posts: 1,031
    edited 2009-07-07 19:00
    Looks like your indentation has problems, look around the repeat statement, the following lines are not indented and it looks like they should be.
  • mminasianmminasian Posts: 26
    edited 2009-07-07 19:03
    Yep that was it! What a stupid mistake. Thanks.
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-07-07 19:04
    Indentation!

    You have to indent the whole stuff inside the repeat, otherwise your program ends faster than you can see the LED blink.


    PS: Ok ... you won ;o)
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-07-07 19:24
    Yes, the whole block after the repeat has to move one tab to the right.

    BTW:
    This is not a state-machine. State-machines have states and events (or transitions).
    In your case, you wouldn't increment the state (state++), but send an event "forward" or "backward". The current state will then decide what the next state will be.
    <http://en.wikipedia.org/wiki/Finite-state_machine&gt;
    case state
      1 : case event
             forward: state:= 2;
             backward: state:= 6;
             stop: return;
      2 : case event
             forward: ....
    
    


    Note that you have to generate events outside of the outer case. This might be polling a switch, or a timer generating events or ... whatever

    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • mminasianmminasian Posts: 26
    edited 2009-07-07 19:37
    Nick this is somewhat true. What I am doing is a bit of a derivative on that. I am using a Moore machine. I took the easy way out by separating the two directions into two different cases. However, each set of two LEDs EG. 01100, represents a state. The machine holds in a state for a given "delay." It ALWAYS goes to the next state, unless interrupted by a "brake." (Yes brake, not break, we're talking about a go cart here). Eventually (once I get my stupid encoders to interface correctly), I will have a gas pedal, and brake pedal which given their value, will determine the direction, and speed with which they change.

    "The FSM uses only entry actions, i.e., output depends only on the state."

    Technically this is a Mealy machine because of the directional operator, but its more easily thought of in one direction, as a Moore.

    The only way I would really update my code to make it any more like your example (and this is trivial) is in each case "state" to change the value of current_state to the next number, instead of incrementing up.

    Post Edited (mminasian) : 7/7/2009 7:42:51 PM GMT
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-07-07 19:41
    > Nick this is somewhat true. What I am doing is a bit of a derivative on that.

    It looks quite degenerated. wink.gif
    Seems as if you could use an array of patterns and move along it with incrementing/decrementing an index that wraps around at the ends. Would be more compact.


    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • mminasianmminasian Posts: 26
    edited 2009-07-07 19:49
    pub run_machine
      dira[noparse][[/noparse]0..4]~~
      repeat 
          case current_state
            1 : outa[noparse][[/noparse]0..4] := %11000
             case direction
              1: current_state := 2
              2: current_state := 5
             
            2 : outa[noparse][[/noparse]0..4] := %01100
             case direction
              1: current_state := 3
              2: current_state := 1
            3 : outa[noparse][[/noparse]0..4] := %00110
             case direction
              1: current_state := 4
              2: current_state := 2
            4 : outa[noparse][[/noparse]0..4] := %00011
             case direction
              1: current_state := 5
              2: current_state := 3
            5 : outa[noparse][[/noparse]0..4] := %10001
             case direction
              1: current_state := 1
              2: current_state := 4
          waitcnt(machine_delay + cnt)
    
    



    HAPPY!?! haha tongue.gif
  • mminasianmminasian Posts: 26
    edited 2009-07-07 19:51
    Oh and I'm an EE which might explain my lack of interest in code eloquence [noparse]:)[/noparse]
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-07-07 21:38
    > HAPPY!?! haha tongue.gif

    Perfect, but it looks soooo ugly. wink.gif (OK, my fault)
    I see a shifting pattern, this SHOUTS for a different solution. Look for ROL and ROR.

    byte pattern = %11001100;

    if forward
    pattern<-= 1;
    if backward
    pattern->= 1;

    Hope ROL and ROR works on bytes.

    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • mminasianmminasian Posts: 26
    edited 2009-07-07 22:16
    For some reason the bits are not rotating through, they just scroll through once and end...

    Byte current_state
    
    dira[noparse][[/noparse]0..4]~~
      current_state := %11000
      repeat
        outa[noparse][[/noparse]0..4] := current_state
        if(direction == 1)
          current_state ->= 1
        if (direction ==2)
          current_state <-= 1 
    
    
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-07-07 22:20
    > they just scroll through once and end...

    Then it is a SHL / SHR
    If you draw each pattern below the other (I didn't), it gets most obvious what has to be done.

    Patterns! Patterns! Gang of three (bad book).


    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • mminasianmminasian Posts: 26
    edited 2009-07-07 22:23
    That's what I was trying to do...

    11000
    01100
    00110
    00011
    10001

    This should be a rotate, using shift yields the same result
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-07-07 22:31
    > This should be a rotate, using shift yields the same result

    You'll notice the minor difference after more than one pass on the round robbin. wink.gif


    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • mminasianmminasian Posts: 26
    edited 2009-07-07 22:36
    I understand what the difference is SUPPOSED to be. I'm not seeing a bitwise rotate as I'm expecting to. Using a rotate (<-=) yields the expected result from a shift. What gives?
  • Nick MuellerNick Mueller Posts: 815
    edited 2009-07-07 22:51
    I think the motor will have to make more than one revolution. With shifting, the pattern is lost, with rotating, it will be fed back.
    Like a 74595 that has the SerIN connectet to the SerOUT or not (register preloaded, of course).
    Connected: ROL/ROR
    Disconnected: SHL/SHR


    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • mminasianmminasian Posts: 26
    edited 2009-07-07 23:04
    Totally agree. For some reason, rotating is losing the patten.
  • mparkmpark Posts: 1,305
    edited 2009-07-08 00:01
    Apparently the rotate works on a 32-bit intermediate result. Storing the result in a byte variable loses the high bits.
Sign In or Register to comment.