Mini Maestro 24 with multiple buttons

Hello,
I recently purchased a mini maestro 24 that i am using in a project to do route control for a model railroad. It uses 6 buttons and 15 servos as point motors in various combinations. The script I’ve written works fine and has no issues. It does however behave in a way that isn’t exactly ideal for what I’m trying to accomplish( having to cycle through one buttons entire sequence before being allowed to move on to another button).
It was mentioned in a past post that running the buttons independently was possible but was more complex. Multiple Maestros was also a mentioned possibility, but that is a cost prohibitive solution for me. My goal would be to either find a way to stop one sequence so I can move on to another or use the mentioned independent button approach. From what I’ve been able to learn so far the former won’t work, it has to complete the sequence. I have a mini maestro 12 doing the same duty on another train layout, but it is only one button with 9 servos and was much easier to solve on my own.
I was wondering where I might learn more about this independent button approach as it would be much more suitable to my goal. I’m still pretty new to maestro scripting and have quite a way to go but would still like to get some direction to go concerning this alternative. I’ve been reading through posts here on the forum and searching online in general but am having no luck finding further information anywhere.

Hi.

Here is an example script using state machines in order to perform multi-tasking to make buttons operate independently. This script is for two buttons, but can be modified for more.

The script uses two buttons, one connected to channel 18 and one connected to channel 19. You will need to set those two channels as inputs in the Channel Settings tab of the Maestro Control Center and you should check the checkbox at the bottom of the Channel Settings tab to enable the internal pull-up resistors on those pins; that way you don’t need to supply your own pull-up resistors. When the button on channel 18 is pressed, it triggers a small sequence of movements for servos 1 and 2. When the buttons on channel 19 is pressed, it triggers a small sequence of movements for servo 0. You can expand this script to have more buttons, more servos, and more steps in the sequences.

0 # State A
0 # State B
0 # Last State A Change Time
0 # Last State B Change Time

# This example uses state machines in order to perform 
# multi-tasking to make buttons operate independently.

begin
  task_a
  task_b
repeat

sub task_a
  state_a 0 equals
  if
    8000 1 servo # set Servo 1 to 2.00 ms
    6000 2 servo # set Servo 2 to 1.50 ms
    button_a 
    if
      1 set_state_a
      # put the current time on the set_last_state_a_change_time variable
      get_ms set_last_state_a_change_time
    endif
  endif
  state_a 1 equals
  if
    6000 1 servo # set Servo 1 to 1.50 ms
    8000 2 servo # set Servo 2 to 2.00 ms
    # if (get_ms - last_state_a_change_time) >= 500
    get_ms last_state_a_change_time minus 2000 greater_than
    if
      0 set_state_a 
    endif
  endif
  return

sub task_b
  state_b 0 equals
  if
    4000 0 servo # set Servo 0 to 1.00 ms
    button_b
    if
      1 set_state_b
      # put the current time on the set_last_state_b_change_time variable
      get_ms set_last_state_b_change_time
    endif
  endif
  state_b 1 equals
  if
    4500 0 servo # set Servo 0 to 1.125 ms
    # if (get_ms - last_state_b_change_time) >= 500
    get_ms last_state_b_change_time minus 2100 greater_than
    if
      0 set_state_b
    endif
  endif
  return

sub button_a
  18 get_position 500 less_than
  return
  
sub button_b
  19 get_position 500 less_than
  return

sub state_a
  0 peek
  return

sub set_state_a
  0 poke
  return

sub state_b
  1 peek
  return

sub set_state_b
  1 poke
  return

sub last_state_a_change_time
  2 peek
  return

sub set_last_state_a_change_time
  2 poke
  return
  
sub last_state_b_change_time
  3 peek
  return

sub set_last_state_b_change_time
  3 poke
  return

- Zeeshan

Thank you very much for the sample. State machines…not a term I would have ever guessed. I’ll have to take some time to understand exactly what is going on in the example. It is a great starting point,better than I was hoping for. I just need to learn what I can plug into the script and where. I already have my 6 buttons wired to the controller with pull up resistors, I made the extra circuitry for my plan before the maestro even arrived. I had all the hardware setup,ready to plug in and start figuring out my script.
I hadn’t figured my script was really necessary since it already worked, but I’ll include it anyway so it can be seen just what I’m doing. I’m sure it’s nowhere near perfect, but may still be of some use. Again…thank you very much. I really appreciate the help.

begin
  button_0 if Sequence_0 endif
  button_1 if Sequence_1 endif
  button_2 if Sequence_2 endif
  button_3 if Sequence_3 endif
  button_4 if Sequence_4 endif
  button_5 if Sequence_5 endif
repeat

goto main_loop

sub button_0
  0 get_position 500 less_than
  return

sub button_1
  1 get_position 500 less_than
  return

sub button_2
  2 get_position 500 less_than
  return

sub button_3
  3 get_position 500 less_than
  return

sub button_4
  4 get_position 500 less_than
  return

sub button_5

  5 get_position 500 less_than
  return

sub wait_for_button_0_press
  wait_for_button_0_open_10ms
  wait_for_button_0_closed_10ms
  return

sub wait_for_button_0_open_10ms
  get_ms
  begin
    button_0
    if
      drop get_ms
    else
      get_ms over minus 10 greater_than
      if drop return endif
    endif
  repeat

sub wait_for_button_0_closed_10ms
  get_ms
  begin
    button_0
    if
      get_ms over minus 10 greater_than
      if drop return endif
    else
      drop get_ms
    endif
  repeat

sub wait_for_button_1_press
  wait_for_button_1_open_10ms
  wait_for_button_1_closed_10ms
  return

sub wait_for_button_1_open_10ms
  get_ms
  begin
    button_1
    if
      drop get_ms
    else
      get_ms over minus 10 greater_than
      if drop return endif
    endif
  repeat

sub wait_for_button_1_closed_10ms
  get_ms
  begin
    button_1
    if
      get_ms over minus 10 greater_than
      if drop return endif
    else
      drop get_ms
    endif
  repeat

sub wait_for_button_2_press
  wait_for_button_2_open_10ms
  wait_for_button_2_closed_10ms
  return

sub wait_for_button_2_open_10ms
  get_ms
  begin
    button_2
    if
      drop get_ms
    else
      get_ms over minus 10 greater_than
      if drop return endif
    endif
  repeat

sub wait_for_button_2_closed_10ms
  get_ms
  begin
    button_2
    if
      get_ms over minus 10 greater_than
      if drop return endif
    else
      drop get_ms
    endif
  repeat

sub wait_for_button_3_press
  wait_for_button_3_open_10ms
  wait_for_button_3_closed_10ms
  return

sub wait_for_button_3_open_10ms
  get_ms
  begin
    button_3
    if
      drop get_ms
    else
      get_ms over minus 10 greater_than
      if drop return endif
    endif
  repeat

sub wait_for_button_3_closed_10ms
  get_ms
  begin
    button_3
    if
      get_ms over minus 10 greater_than
      if drop return endif
    else
      drop get_ms
    endif
  repeat

sub wait_for_button_4_press
  wait_for_button_4_open_10ms
  wait_for_button_4_closed_10ms
  return

sub wait_for_button_4_open_10ms
  get_ms
  begin
    button_4
    if
      drop get_ms
    else
      get_ms over minus 10 greater_than
      if drop return endif
    endif
  repeat

sub wait_for_button_4_closed_10ms
  get_ms
  begin
    button_4
    if
      get_ms over minus 10 greater_than
      if drop return endif
    else
      drop get_ms
    endif
  repeat

sub wait_for_button_5_press
  wait_for_button_5_open_10ms
  wait_for_button_5_closed_10ms
  return

sub wait_for_button_5_open_10ms
  get_ms
  begin
    button_5
    if
      drop get_ms
    else
      get_ms over minus 10 greater_than
      if drop return endif
    endif
  repeat

sub wait_for_button_5_closed_10ms
  get_ms
  begin
    button_5
    if
      get_ms over minus 10 greater_than
      if drop return endif
    else
      drop get_ms
    endif
  repeat

main_loop:
begin


### Sequence subroutines: ###

# Sequence 0
sub Sequence_0
  1000 6208 3200 6400 0 0 0 
  0 0 0 0 0 0 
  0 0 0 0 0 0 frame_6..23 # Frame 0
  wait_for_button_0_press
  1000 5056 1984 frame_6_7 # Frame 1
  return
# Sequence 1
sub Sequence_1
  1000 0 3200 5312 6272 0 0 
  0 0 0 0 0 0 
  0 0 0 0 0 0 frame_6..23 # Frame 0
  wait_for_button_1_press
  1000 6400 7808 frame_8_9 # Frame 1
  return
# Sequence 2
sub Sequence_2
  1000 0 0 0 0 5760 6720 
  0 0 0 0 0 0 
  0 0 0 0 0 0 frame_6..23 # Frame 0
  wait_for_button_2_press
  1000 6912 5888 frame_10_11 # Frame 1
  return
# Sequence 3
sub Sequence_3
  1000 0 0 0 0 0 0 
  5632 6016 0 0 0 0 
  0 0 0 0 0 0 frame_6..23 # Frame 0
  wait_for_button_3_press
  1000 7104 4864 frame_12_13 # Frame 1
  return
# Sequence 4
sub Sequence_4
  1000 0 0 0 0 0 0 
  0 0 7296 5184 0 0 
  0 0 0 0 0 0 frame_6..23 # Frame 0
  wait_for_button_4_press
  1000 6400 frame_15 # Frame 1
  wait_for_button_4_press
  1000 6336 5184 frame_14_15 # Frame 2
  return
# Sequence 5
sub Sequence_5
  1000 0 0 0 0 0 0 
  0 0 0 0 7040 4864 
  5952 5952 5504 0 0 0 frame_6..23 # Frame 0
  wait_for_button_5_press
  1000 6080 5312 6528 frame_17..19 # Frame 1
  wait_for_button_5_press
  1000 5504 4864 5952 6464 frame_16_17_19_20 # Frame 2
  wait_for_button_5_press
  1000 6080 5504 frame_17_20 # Frame 3
  return
repeat

sub frame_6..23
  23 servo
  22 servo
  21 servo
  20 servo
  19 servo
  18 servo
  17 servo
  16 servo
  15 servo
  14 servo
  13 servo
  12 servo
  11 servo
  10 servo
  9 servo
  8 servo
  7 servo
  6 servo
  delay
  return

sub frame_6_7
  7 servo
  6 servo
  delay
  return

sub frame_8_9
  9 servo
  8 servo
  delay
  return

sub frame_10_11
  11 servo
  10 servo
  delay
  return

sub frame_12_13
  13 servo
  12 servo
  delay
  return

sub frame_15
  15 servo
  delay
  return

sub frame_14_15
  15 servo
  14 servo
  delay
  return

sub frame_17..19
  19 servo
  18 servo
  17 servo
  delay
  return

sub frame_16_17_19_20
  20 servo
  19 servo
  17 servo
  16 servo
  delay
  return

sub frame_17_20
  20 servo
  17 servo
  delay
  return

Dave