Mini Maestro 24: script for multiple digital Inputs?

Hello.
I’m (as you might understand) new to this kind of controllers. I’ve used Picaxe until now. But found them to be less good when using them mainly to controll servos…
I’m using the sample script from the tutorial to have the Controller move 3 servos when I close a switch on channel 23. This is working fine. But I want to have more switches (at least 3 more) and for each different switch I want a new “scenario” to take place. For example: Switch 1 (channel23) moves 3 servos to a given postion for 5 seconds and then back. Switch 2 (channel22) moves 1 on the 3 servos to a given postion for 10 seconds.

I do understand how to set up the movement, timing and so on. But I dont know how to get the controller to go to the different subroutines when the different switches are pressed.

Here is a link to my project: agathashus.se

Regards, Lars

begin
  4000 4000 4000 frame_1
  5000 5000 5000 frame_1
  6000 6000 6000 frame_1
  7000 7000 7000 frame_1
  repeat

sub frame_1
  wait_for_button_press
  2 servo 0 servo 1 servo
  return

sub button
  23 get_position 500 less_than
  return

# Waits for a button press, with debouncing.
# (Requires the BUTTON subroutine.)
sub wait_for_button_press
  wait_for_button_open_10ms
  wait_for_button_closed_10ms
  return

# wait for the button to be NOT pressed for at least 10 ms
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 drop return endif
    endif
  repeat

# wait for the button to be pressed for at least 10 ms
sub wait_for_button_closed_10ms
  get_ms
  begin
    # reset the time on the stack if it is pressed
    button
    if
      get_ms over minus 10 greater_than
      if drop return endif
    else
      drop get_ms
    endif
  repeat

Hello.

The way you would do this is to write a loop that checks each of your buttons in turn, and if it detects that a button is pressed then it executes the corresponding motion sequence. Below is a complete example script that does this. It has buttons on channels 0-2, and it uses servos on channels 3 and 4.

# When the Maestro script is not doing anything else,
# this loop will listen for button presses.  When a button
# is pressed it runs the corresponding sequence.
begin
  buttonA if sequenceA endif
  buttonB if sequenceB endif
  buttonC if sequenceC endif
repeat

# These subroutines each return 1 if the corresponding
# button is pressed, and return 0 otherwise.
# Currently buttonA is assigned to channel 0, 
# buttonB is assigned to channel 1, and
# buttonC is assigned to channel 2.
# These channels must be configured as Inputs in the
# Channel Settings tab.
sub buttonA
  0 get_position 500 less_than
  return

sub buttonB
  1 get_position 500 less_than
  return

sub buttonC
  2 get_position 500 less_than
  return

# These subroutines each perform an arbitrary sequence
# of servo movements.  You should change these to fit
# your application.
sub sequenceA
  4000 3 servo
  1000 delay
  6000 3 servo
  500 delay
  return
  
sub sequenceB
  8000 4 servo
  900 delay
  7000 4 servo
  900 delay
  6000 4 servo
  900 delay
  return

sub sequenceC
  10 4 speed
  7000 4 servo
  3000 delay
  6000 4 servo
  3000 delay
  return

Please note that this script does not do multi-tasking. If a sequence is running, the Maestro will not respond to other button presses until the sequence is done. If you want the buttons to operate independently, it can be done, but it would be a lot more complicated.

Thanks for asking a good question. I’m going to add this script to the Maestro Manual for future customers who want to do something similar.

–David

i suggest to change

less_than logical_not

to

greater_than

saves you a byte and makes the code a little easier to read. :smiley:

Thanks! I have edited my previous post and removed the “logical_not”. I had only put it in there for testing purposes and had forgotten to take it out before posting it. --David

Hi
Thank you for the answer(s). I now can go on with my project.
All the best from,
Lars Lindberg

if you want more sequences with less buttons. (pressing 2 buttons at the same time gives different sequence than each one by itself)
the script below takes inputs from 3 buttons. all the different combinations of presses give 8 sequences.

### MAIN LOOP ###


start:
digi1 if
		  digi2 if
				digi3 if
					movement1 goto start
					else 
					movement2 goto start
					endif
			  else
				digi3 if
					movement3 goto start
					else 
					movement4 goto start
					endif	
			  endif
		else		
		  digi2 if
				digi3 if
					movement5 goto start
					else 
					movement6 goto start
					endif
			  else
				digi3 if
					movement7 goto start
					else 
					movement8 goto start
					endif
			  endif	
		endif


### Input: ###


# digi1,2,3 are the digital inputs. 5v gives 1 as an output!
 sub digi1
0 get_position 512 greater_than
return

 sub digi2
1 get_position 512 greater_than
return
 
 sub digi3
2 get_position 512 greater_than
return

### Movements: ###  


   sub movement1 
  1000 3000 3000 3000 servos
     return  
   sub movement2 
  1000 7000 3000 3000 servos
     return  
   sub movement3
  1000 7000 3000 3000 servos
     return     
   sub movement4 
  1000 7000 3000 3000 servos
     return  
   sub movement5 
  1000 7000 3000 3000 servos
     return  
   sub movement6 
  1000 7000 3000 3000 servos
     return  
   sub movement7  
  1000 7000 3000 3000 servos
     return
   sub movement8  
  1000 3000 7000 3000 servos
     return    

### MISC subroutines ###
   sub servos  
     5 servo 4 servo 3 servo delay  
     return  

Is it possible to make inputs be not the channels on the controller, but specific signals from the computer connected to it with the usb?

How do i write this as input in the script, and how do i make a specific key-combination on the computer to send this special signal to the controller?

(i guess this last question means i have to have a script on the computer that searchers for keycombinations and if it finds these special ones sends special signals (signals being bytes that i have to define, how do i know which are empty of meaning/effect and in that way open for me to use?) to the controller… im totally new to programming as you can guess, but this is probably also relevant questions for me;

  1. how do i find which combination of bits that is neutral and that i can use?
  2. how do i send them to the microcontroller?
  3. how do i make the microcontroller interpret them as input, so that i can make a script about them?
  4. How do i make my windows vista pc to send these bytes to the controller when i make a certain keycombination or push a certain button on the keyboard?)

Kind regards

/Orbert

If you have extra channels on your Maestro you can configure them to be Servo channels and then send Set Target commands from the computer to set their values, and read those values from your script with the “get_position” command. This is one way to send data from a PC to a running Maestro script. The Set Target command can either be sent using native usb or through a virtual COM port: see the Writing PC Software to Control the Maestro section of the user’s guide for more details. The Maestro Control Center and UscCmd (the command line utility that comes with it) both can send Set Target commands via native USB.

You should figure out how to send the right signals to the controller using UscCmd, then use Autohotkey to automatically run UscCmd when a specific key combination is detected. See this post by RyanTM for info on how to set that up.

I don’t understand this question at all. What you mean by “combination of bits”? What do you mean by “neutral”?

Which microcontroller? Are we still talking about the Maestro Servo Controller or do you have another programmable microcontroller?

Use Autohotkey.

–David

I felt that i already got an answer, and even a more direct solution that i imagined, from you and Ryan.

But anyway, to clarify what i thought, i could answer you. I guess my choice of words is bewildering cause i dont know the right terms and dont fully grasp the processes im talking about.

I understand that data is sent to the microcontroller (yes, its the micro maestro im referring to as microcontroller) in form of variations in an electric current, and that these variations is interpreted as logical 1 or logical 0. These ones and zeros, or on and offs, are called bits when they are arranged in series of 8 that would make up a kind of expressive unit called byte. They are arranged so that the recieving processor notices when a byte start and ends. The order of the bits in the sequence gives the unique identity of a byte, and the ordering of bytes gives a even bigger multiplicity of unique combinations.
This ordering of ones and zeros in a series or string is what i call combination, and a byte could be broken down in its combination of bits, each bit being either 1 or 0.

Thats how i understand the basic of computer signals.
What i meant by neutral is that a string of bits (a byte) doesnt create any respons from the micro maestro, it isnt interpreted as anything, doesnt trigger anything, is just nonsense.
So i though that if i find i way to design and send bytes to the micro maestro i wouldnt want to send something that already makes sense to it, that trigger something, something that is already a command of sorts. I would want to be sure to send a byte, or a series (a combination) of bytes, that does nothing.

Then i thought i could make a hotkey that sends this unique string of nonsense to micro maestro, and i could in the maestro control-center make a script that says that if the micro-maestro recieves this unique string of nonsense it would run a sequence.

First i would find several combinations of 0 and 1 that doesnt have sense or function, and send it to micro maestro, then i would script the micromaestro to notice these combinations as “empty somethings” and by that establish a code which to communicate with it through, and then by making it run specific sequences when it notices these “empty somethings” the “somethings (the combinations)” would no longer be “empty (without effect)” and the micromaestro would “make sense” of them.

Thats my phantasy about how this computer-communicationprocess would work, put in my laguage.

Anyway, the solution you put forward with direct communication via UscCmd (and combinations that already makes sense) seems to be much simpler.
And im not sure that my phantasy is close to how it works in reality, anyway:)
But as u notice i enjoyed thinking about it. But maybe computers is learned better by empirical studies than speculation:)

Best Regards!

/Orbert

Hi again. I’ve started this thread some time ago. I now have learned some more but I got stuck on a propably simple issue:

I have 2 input channels ( 16 and 17). Both are connected to a simple microswith. (one swith for each channel).
I need both these activated before I call a subroutine. The code below works fine when I activate one switch at the time, but I want to be sure that both switches are actived before it jumps to pointed sequence. Does this make any sense?

Thanks,
Lars

begin
button1 if sequence1 endif
button2 if sequence2 endif
button3 if sequence3 endif
sub button1
15 get_position 500 greater_than
return

sub button2
16 get_position 500 greater_than
return

sub button3
17 get_position 500 greater_than
return
repeat

Hello. I don’t think the code you posted will work fine. You really want to move the “repeat” statement to be before the “sub button1”, right? Otherwise the flow of your program will be such that it falls through into “sub button1” and starts executing the code inside that subroutine even though the subroutine was not called.

If you want to make sure that two buttons are pressed before going into a sequence, you could use logical_and. You would add a line that looks like this to your main loop:

button4 button5 logical_and if sequence4 endif

–David

Hello.
I made a ‘Copy and Paste’ error in the code, thats why the Repeat is in the wrong place. Sorry.

I tried the line you suggested but it doesnt give me exactly what I need. As you might seen in this thread I am building a R2D2 robot. Yes. its weird…
http://www.agathashus.se
The issue is very hard for me to explain, but let me try:
I have one remote reciever connected to the Pololu as Input. Its a relay, normaly open. This is connected to Input channel “22”.
The remote control signal activates Servo1 to open a door. (when I press the remote, the relay closes). This part is ok.

Then I have a microswith connected to Input channel “23”.
This microswitch is ‘open’ when the door is closed, and when Servo1 opens this door, the switch gets activated/pushed and it is ‘closed’

What I need is a toggling (?) script/effect that only allows Servo1 to open if the switch is ‘open’. And Servo1 can only close the door (return the servo) if the switch is ‘closed’. And this using the same remote controll button.

I’ve tried to make an explanation here: http://www.agathashus.se/open.htm

Regards,
Lars

Hello, Lars.

If I understand correctly, you have a signal from a remote receiver connected to channel 22. Occasionally, the user will press a button on the transmitter, which results in a pulse being sent to the Maestro. When this happens, you want the Maestro to toggle the state of a door between open and closed. There is a sensor that lets the Maestro tell if the door is currently open or closed.

In that case, your Maestro code should look something like this:

button22 if
  door_is_closed if
    door_open
  else
    door_close
  endif
  1000 delay
endif

The subroutines button22 and door_is_closed need to return 0 or 1. The subroutines door_open and door_close need to perform the specified action. I added the delay in there to make sure that the door doesn’t get toggled multiple times in quick succession, but it might not be necessary depending on what you do in the door_open and door_closed subroutines.

–David