I’m looking to run up a motor via an ESC and Maestro. Has anybody got any code-snippets for accumulating a count over time? I need my script to drive the motor based on a potentiometer position. If however a push-button on another input is pressed, the script will add an arbitrary value to the pot position and drive the ESC to this slightly higher position. The script then lets some time pass, before repeating as long as the switch stays pressed. This ramps up the motor over-and-above the pot setting as long as I keep the button pressed. The switch is actually a bite-switch and this is a pot plus for hands-free (the bite-switch) system.
Below is my very rudimentary start. Any snippets to help would be much appreciated. Many thanks, Brendan.
# SCRIPT TO CONTROL A MOTOR ESC
#
# Inputs:
# a) Potentiometer on '0'
# b) Push-button switch on '1'
# Output: One only - ESC on '2'
#
# Functionality:
# 1) Drive servo '2' to position relative to pot '0'
# 2) If Push-button '1' pressed go to a rampup sub and...
# A) Get position of pot
# i) Add pot value to a a small number
# ii) Drive servo to this number, remember number
# iii) Wait for a small time
# Va) Is push-button still pressed? Yes - back to i) to repeat
# Vb) Is push-button still pressed? No - forget accumulated number and back to 1)
begin
swt_rampup # Goto subroutine swt_rampup
0 get_position # Get the position of the Potentiometer
2 servo # Send this value to the servo (ESC)
repeat
sub swt_rampup
begin
1 get_position 500 less_than # Is the swt active ("less_than")
if
return # If swt inactive break out of sub
else
delay 1000
if
return
endif
endif
repeat
From your description, it sounds like you want the servo output to be based on the potentiometer when the switch is not pressed and when the switched is pressed, have the servo output increase until it is released. If that is the case, doing something like this might work for you:
begin
1 get_position 500 less_than if #check if the switch is pressed
2 get_position 40 plus
2 servo #set the servo
100 delay #short delay
else
0 get_position # get the value of the pot, 0-1023
4 times 4000 plus # scale it to 4000-8092, approximately 1-2 ms
2 servo #set the target of servo 2
endif
repeat
The program above does not actually use a counter; instead it increments the servo target by a set amount (40 quarter microseconds) each time through the loop when the button is pressed. If you want the servo target to ramp up faster the longer the button is pressed, you would probably need some sort of counter. There are probably a few ways you could do this (e.g. using the get_ms command to time how long the button has been pressed), but using a counter that increases each time through the loop would probably work. After I modified my example above to use a counter, it looks like this:
0 #initialize counter value
begin
1 get_position 500 less_than if #check if the switch is pressed
dup 10 times #copy counter value and multiply it by a scaling factor
2 get_position plus #get the current position of the servo and add the scaled counter
2 servo #set the servo
1 plus #increase the counter on the stack by 1
100 delay #short delay
else
drop #drop the current counter
0 get_position # get the value of the pot, 0-1023
4 times 4000 plus # scale it to 4000-8092, approximately 1-2 ms
2 servo #set the target of servo 2
0 #reset the counter to zero
endif
repeat
Thank you very much for your help. I didn’t see your post and came up the the script below. Very similar to your first example, I think (no counter). I’ve tested it and it works as I want it to
One question though, as I’m increasing a value on the stack - what happens when a stack value reaches the largest number possible? Does the value just stop increasing? Or roll-through to 0? I guess to be thorough, I should probably add a test to stop adding if the stack has a value greater than 2000?
Cheers and thanks again,
Brendan.
Begin
swt_rampup #Goto Sub swt_rampup
0 get_position #Get position of Pot
4 times 4000 plus #Normalise for servo output
2 servo #Set servo (ESC) to value
Repeat
sub swt_rampup
0 get_position #Get position of Pot (again)
4 times 4000 plus #Normalise
begin
1 get_position 500 less_than #Test if button pressed
if #If button not pressed...
Drop #Drop the Pot value from Stack
return #Go back to main loop
else #If button is pressed...
100 plus #Start accumulating, add 100
Dup #Dup value to keep alive
2 servo #Set servo (ESC) to value
250 delay #Wait 1/4 second
endif
repeat #Back to the Test...
Since your counter is being used to set a servo target, there are two limits that would be important. The first value that will be reached is the maximum set target value for that servo channel. You can configure this value for each channel in the “Channel Settings” tab of the Maestro Control Center; please note that the values in the “Channel Settings” tab is in units of microseconds, while the value when sending a target in a script is in units of quarter microseconds, so you will need to convert the units appropriately. For example, since the default the max target value is 2000 microseconds, you can add some logic to prevent the counter from increasing beyond 8000 quarter microseconds. Sending target values above the configured maximum will send a target value equal to the configured maximum.
The next limit to be aware of is that values on the stack must be integers from -32768 to +32767. If you have a counter that exceeds 32767, it will roll over back to -32767.
I added a little test that stops the count accumulating if 8100 microseconds is reached (in bold below). I’ve bench tested this script and it works great (no one is more surprised by this than me!).
Begin
swt_rampup
0 get_position
4 times 4000 plus
2 servo
Repeat
sub swt_rampup
0 get_position
4 times 4000 plus
begin
1 get_position 500 less_than
if
Drop
return
else
**Dup**
**8100 less_than**
if
100 plus
endif
Dup
2 servo
250 delay
endif
repeat