Pololu Robotics & Electronics
Menu
My account Comments or questions? About Pololu Contact Ordering information Distributors

Pololu Forum

Can you help me modify my code?

Hi,
I’m using a Micro Maestro 6-Channel to control 2 servos. Everything works fine when I run my script. My problem is how I would like to trigger the script in my real world application. Here’s my script for reference.

begin
  4000 0 3968 8000 0 0 0 frame_0..5 # Frame 0
  4000 8000 3968 frame_1_2 # Frame 1
repeat

sub frame_0..5
  5 servo
  4 servo
  3 servo
  2 servo
  1 servo
  0 servo
  delay
  return

sub frame_1_2
  2 servo
  1 servo
  delay
  return

I would like to trigger it off a 6V flashing lamp. The lamp is normally off. The lamp flashes on at certain times and that’s when I’d like to start my script. I will be using a relay that will power on with the lamp providing me with a dry contact. The problem is I would like to trigger Frame 0 on the first pulse and ignore the rest of the pulses. The lamp pulses once every.5 seconds if I remember right. I would like the script to continually look at the pulse and if it’s still present do nothing after running Frame0. If the pulse is not present for more than 1.5 seconds run Frame 1. I don’t know if this is possible as I’m not a code guy but I would love it if someone could give me a hand.
Thanks,
Tim

If it helps frame 0 moves 2 servos (on channels 1 an 2) to open a gate. Frame 1 closes the gate.

Also in playing around last night I was able to add in my switch code but it goes through a full open and close cycle when it sees the switch. Below is the code that does that.

[code]# When the script is not doing anything else,

this loop will listen for button presses. When a button

is pressed it runs the corresponding sequence.

begin
button_a if sequence_a endif
repeat

These subroutines each return 1 if the corresponding

button is pressed, and return 0 otherwise.

Currently button_a is assigned to channel 0,

button_b is assigned to channel 1, and

button_c is assigned to channel 2.

These channels must be configured as Inputs in the

Channel Settings tab.

sub button_a
0 get_position 500 less_than
return

sub sequence_a
4000 0 3968 8000 0 0 0 frame_0…5 # Frame 0 Open Gate

4000 8000 3968 frame_1_2 # Frame 1 Close Gate

return

sub frame_0…5
5 servo
4 servo
3 servo
2 servo
1 servo
0 servo
delay
return

sub frame_1_2
2 servo
1 servo
delay
return
[/code]

Hello, Tim.

Regarding to your first post, you would probably need some type of sensor that can read the pulses from your lamp and provide some analog or digital output that can be read by a Maestro channel configured as an input. There is an example script for using an analog input to control servos in the “Example Scripts” section of the Maestro user’s guide, which can help you get started.

For your second post, it is not clear to me what you mean by “it goes through a full open and close cycle”, but I recommend you use the “Using a button or switch to control servos” example and modify the frame subroutine to execute your frame sequences. For example:

sub frame
  wait_for_button_press
  4000 0 3968 8000 0 0 0 frame_0..5 # Frame 0
  4000 8000 3968 frame_1_2 # Frame 1
  return

The full example in the guide has some simple button debouncing in it that you might find helpful for triggering a subroutine off of just the first pulse in a string of pulses.

- Amanda

Hi Amanda. Thanks for your response. I’ll be using a relay to covert the lamp pulse to a dry contact so that’s not an issue. Also in my second post I have the switch integrated and it runs the servos but I can’t figure out how to get it to run one sequence upon the first button press and a different sequence on the second button press.

In my failed attempts I’ve tried the “Using a button or switch to control servos” example and modified it as follows. The problem I’m having with this code is it will only operate one servo at a time alternating between the two every time I press the switch. I’m not a programmer and I’m having a heck of a time getting anything to work right. Again any help or especially examples other than what’s in the manual (I’ve tried all combinations of the examples in the manual) would be appreciated.

I’m outlining my goals:
Goal 1. Get the script to control 2 servos at once and move them from position a to position b (I can define the positions later) when a button is pressed.
Goal 2. Get the script to control 2 servos at once and move them from position b to position a when the button is pressed a second time.
Goal 3. Get the script to trigger the two servos as described in goal 1 and ignore all further button presses until there are no longer any button presses for 1 second. When there are no more button presses for 1 second trigger the 2 servos as described in goal 2.

I’d be willing to pay someone to write this code for me at this point. Not sure if that’s a violation of this forum. If it is I apologize in advance.

[code]goto main_loop
sub button
0 get_position 500 less_than
return
sub wait_for_button
wait_for_button_closed_10ms
return
sub wait_for_button_press_10ms
get_ms
begin
button
if
drop get_ms
else
get_ms over minus 10 greater_than
if drop return endif
endif
repeat

sub wait_for_button_closed_10ms
get_ms
begin
button
if
get_ms over minus 10 greater_than
if drop return endif
else
drop get_ms
endif
repeat

main_loop:
begin
4000 1 servo frame
8000 2 servo frame
8000 1 servo frame
4000 2 servo frame

repeat

sub frame
wait_for_button

wait_for_button_press_10ms #This line makes it so holding the button only counts as one press instead of looping
return

Sequence 2

begin
4000 3968 8000 0 0 frame_1…4 # Frame 0
500 8000 3968 frame_1_2 # Frame 1
repeat

sub frame_1…4
4 servo
3 servo
2 servo
1 servo
delay
return

sub frame_1_2
2 servo
1 servo
delay
return
[/code]

I briefly looked at your code and noticed in the first BEGIN/REPEAT block you are moving one servo at a time with each button press. You might try removing the first and third “frame” subroutine calls from the loop. Like so:

main_loop:
begin
4000 1 servo
8000 2 servo frame
8000 1 servo
4000 2 servo frame
repeat

That way both servos (channels 1 & 2) will move each time you press the button. I also noticed that the lines below the “Sequence 2” comment will never run, but it seems like you might just be keeping your original code there as reference.

As for your goal of having a single button to do two different things, you could use something like a state variable to keep track of the button presses and execute the associated sequence based on that variable. To get an idea of how to do that, you can look at some example code using a state variable in this forum post.

By the way, there is no policy on our forum against offering to pay someone to help you with your project.

- Amanda

Thanks so much Amanda! Using the one frame for the 2 servos did the trick. I’ll take a look at the thread you suggested.
Thanks again!

Ok. So I figured out how to convert my 6VDC pulsing signal into a steady output with some external components (capacitor, resistor, diode and relay). So when the lamp is flashing I can now power a relay and keep the contact closed while the lamp is flashing. When the lamp stops flashing my relay turns off.

My code below works fine with a pulse trigger. One pulse opens the gate and the second pulse closes the gate. In this code if I hold the button down it will go through both the open gate and close gate frames over and over.

[code]1 #Sets an initial state (open)
begin

0 get_position
10 less_than #Check if button is pushed
if

dup
if #If gate is open, run frame to close it

close_gate #Run the close_gate subroutine
drop #Change the state to 0
0

else #If gate is closed, run frame to open it

open_gate #Run the open_gate subroutine
drop #Change the state to 1
1

endif

endif

repeat

Sequence subroutines:

open_gate

sub open_gate
4000 0 3968 8000 0 0 0 frame_0…5 # Frame 0 Open Gate

return

close_gate

sub close_gate
4000 8000 3968 frame_1_2 # Frame 1 Close Gate

return

sub frame_0…5
5 servo
4 servo
3 servo
2 servo
1 servo
0 servo
delay
return

sub frame_1_2
2 servo
1 servo
delay
return
[/code]

I would like to change the code to open the gate when the button is held and close the gate when the button is released.

The most recent code you posted will only enter the first IF statement when a button is pressed, so if you hold the button down, the code will always enter that IF statement and proceed to toggle between executing open_gate or close_gate continuously until you release the button.

To open the gate when you hold down your button and close the gate when you release it, you might try replacing your code above the “Sequence subroutines” comment with the “Using a button or switch to control servos” example code. Then you should be able to add subroutine calls to open_gate and close_gate within in the wait_for_button_closed_10ms and wait_for_button_open_10ms subroutines to get the behavior you want. The code below is an example of what your modified wait_for_button_open_10ms subroutine might look like:

sub wait_for_button_open_10ms
  get_ms # put the current time on the stack
  begin
    # reset the time on the stack if it is pressed
    button
    if
      drop get_ms
    else
      get_ms over minus 10 greater_than
      if close_gate drop return endif	#close the gate when button has been released for more than 10ms
    endif
  repeat

- Amanda