Dear Pololu Forum,
I use the Maestro Servo Controller controlled by a PC since a while to automize a model railway including self driving cars.
Now I tried to run the car controll as a script on a 24-Channel controller. Therefore I need a kind of multitasking feature.
The code snipped added as example shows a part of the complete script, where e.g. 2 bus-stopps are included, each wich a huge delay.
How can I controll the other actors by connected button, while the delay blocks teh script?
# this loop will listen for buttons beeing pressed.When a button
# is pressed it runs the corresponding sequence.
begin
sensor_1 if actor0_toggle endif
sensor_2 if actor1_toggle endif
sensor_3 if actor2_toggle endif
sensor_4a if sequence_bus_stopp1 endif
sensor_4b if sequence_bus_stopp1 endif
sensor_5 if sequence_bus_stopp2 endif
repeat
# These subroutines each return 1 if the corresponding
# button is pressed, and return 0 otherwise.
# sensor_1 at channel 18
# sensor_2 at channel 19
# sensor_3 at channel 20
# sensor_4a at channel 21
# sensor_4b at channel 22
# sensor_4c at channel 23
sub sensor_1
18 get_position 500 less_than
return
sub sensor_2
19 get_position 500 less_than
return
sub sensor_3
20 get_position 500 less_than
return
sub sensor_4a
21 get_position 500 greater_than
return
sub sensor_4b
22 get_position 500 greater_than
return
sub sensor_5
23 get_position 500 less_than
return
#----------------------------------------------
# Subroutines defining actions to be perfomed
sub actor0_toggle
0 get_position # get position of servo 0
6005 less_than # if true -> 1, if false ->0
if
7000 0 servo
else
5000 0 servo
endif
return
sub actor1_toggle
1 get_position # get position of servo
6005 less_than # if true -> 1, if false ->0
if
7000 1 servo
else
5000 1 servo
endif
return
sub actor2_toggle
2 get_position # get position of servo
6005 less_than # if true -> 1, if false ->0
if
7000 2 servo
else
5000 2 servo
endif
return
sub sequence_bus_stopp1
7000 3 servo #set switch to park lane
7000 4 servo #set stopp
1500 delay
5000 3 servo #reset switch
30000 delay
5000 4 servo #reset stopp
return
sub sequence_bus_stopp2
7000 5 servo #set stopp
30000 delay
5000 5 servo #reset stopp
return
Best regards
Chris
Hello, Chris.
It is possible to do what you described by replacing your blocking DELAY commands with some code that uses the non-blocking GET_MS command to keep track of how much time has passed. The GET_MS command puts the current value of the millisecond timer on the stack. It might be difficult to keep track of multiple non-blocking delays at once, so I would suggest starting with getting one working first. You can see an example of how to do non-blocking code in a Maestro script in this post by Jon. Reading though the example in my post in this thread might be helpful as well.
If you try changing your delays into non-blocking delays and run into problems, you can post your updated script here, and I would be glad to take a look.
Brandon
Hellon BrandonM,
thanks for the hint to get_ms.
I realized to separate waiting loops in the following script, it´s working fine!
#initialize
60 # waiting time for bus stopp1 in seconds
0 # stack-place for timer bus stopp1
30 # waiting time for bus stopp2 in seconds
0 # stack-place for timer bus stopp2
0 # initialize seconds_timer, how many seconds have elapsed
get_ms # initialize current_time_elapsed
# this loop will listen for buttons beeing pressed.When a button
# is pressed it runs the corresponding sequence.
begin
seconds_timer_update
sensor_1 if actor0_toggle endif
#sensor_2 if actor1_toggle endif
#sensor_3 if actor2_toggle endif
sensor_4a if sequence_bus_stopp1_set endif
sensor_4b if sequence_bus_stopp1_set endif
sequence_bus_stopp1_reset
sensor_5 if sequence_bus_stopp2_set endif
sequence_bus_stopp2_reset
repeat
# These subroutines each return 1 if the corresponding
# button is pressed, and return 0 otherwise.
# sensor_1 at channel 18
# sensor_2 at channel 19
# sensor_3 at channel 20
# sensor_4a at channel 21
# sensor_4b at channel 22
# sensor_5 at channel 23
sub seconds_timer_update
# counts the seconds since started
begin
get_ms 1 pick minus 1000 greater_than while
1000 plus # (current_time_elapsed += 1000)
swap 1 plus swap # (seconds_timer += 1)
repeat
return
sub sensor_1
18 get_position 500 less_than
return
sub sensor_2
19 get_position 500 less_than
return
sub sensor_3
20 get_position 500 less_than
return
sub sensor_4a
21 get_position 500 greater_than
return
sub sensor_4b
22 get_position 500 greater_than
return
sub sensor_5
19 get_position 500 less_than
return
#----------------------------------------------
# Subroutines defining actions to be perfomed
sub actor0_toggle
0 get_position # get position of servo 0
6005 less_than # if true -> 1, if false ->0
if
7000 0 servo
else
5000 0 servo
endif
return
sub actor1_toggle
1 get_position # get position of servo
6005 less_than # if true -> 1, if false ->0
if
7000 1 servo
else
5000 1 servo
endif
return
sub actor2_toggle
2 get_position # get position of servo
6005 less_than # if true -> 1, if false ->0
if
7000 2 servo
else
5000 2 servo
endif
return
sub sequence_bus_stopp1_set
4 get_position 6000 less_than #bus stopp1 reset
if
7000 3 servo #set switch to park lane
7000 4 servo #set stopp
1500 delay
5000 3 servo #reset switch
4 peek 1 poke #store actual time for stopp1 set
endif
return
sub sequence_bus_stopp1_reset
4 get_position 6000 greater_than #bus stopp1 set
if
1 peek 0 peek plus #stored stop time plus waiting time
4 peek swap greater_than # greater than actual time
if
5000 4 servo #reset stopp1
0 1 poke #reset stored time for stopp1
endif
endif
return
sub sequence_bus_stopp2_set
5 get_position 6000 less_than #bus stopp2 reset
if
7000 5 servo #set stopp
4 peek 3 poke #store actual time for stopp2 set
endif
return
sub sequence_bus_stopp2_reset
5 get_position 6000 greater_than #bus stopp2 set
if
3 peek 2 peek plus #stored stop time plus waiting time
4 peek swap greater_than # greater than actual time
if
5000 5 servo #reset stopp2
0 3 poke #reset stored time for stopp2
endif
endif
return
1 Like
I am glad you were able to get it working! Thank you for letting us know and sharing your code.
Brandon