View Full Version : Sequential commands on a single button
Revvin
29th December 2003, 04:52 PM
It is sometimes desireable to have one button cycle through two or more commands, for example view control or to switch between radar modes. To do this you can use the 'SEQUENCE' command in the Control Manager CMS. In the example below joystick button 1 (JS1.B1) will cycle through three commands (CMS.B1, CMS.B2 and CMS.B3) This script will operate these CMS buttons to execute the commands defined in the CMS control window so in our example I've used the letters 'a' (CMS.B1) 'b' (CMS.B2) and 'c' (CMS.B3). On the first press of joystick button 1 we will generate an 'a' then another press will generate a 'b' and a third press will generate a 'c'. Pressing joystick button 1 again will take us back through the cycle starting by generating an 'a'. Cut and paste this script into your profile or download the attached file and modify it as needed.
//
script
SEQUENCE
Â*// First Command Operates on the first press of Joystick 1 Button 1
Â*WHILE( JS1.B1 );
Â*CMS.B1 = TRUE;
Â*DELAY( 2 );
Â*CMS.B1 = FALSE;
Â*DELAY( 2 );
Â*// Second Command Operates on the second press of Joystick 1 Button 1
Â*WHILE( JS1.B1 );
Â*CMS.B2 = TRUE;
Â*DELAY( 2 );
Â*CMS.B2 = FALSE;
Â*DELAY( 2 );
Â*// Third Command Operates on the third press of Joystick 1 Button 1
Â*WHILE( JS1.B1 );
Â*CMS.B3 = TRUE;
Â*DELAY( 2 );
Â*CMS.B3 = FALSE;
Â*DELAY( 2 );
ENDSEQUENCE
endScript
JNOV
10th January 2004, 12:03 AM
I do this all of the time, except that sometimes there are a sufficient number of commands in the list that I like to set it up so that I have one button to cycle forwards and one to cycle backwards (e.g., I do this in IL-2 to cycle forward and backward through its ten (?) discrete zoom levels). I haven't figured out how to get SEQUENCE to work in that context, so what I've done is to define a "state" variable, i.e., a1, to represent the last-sent command. When the forward or reverse button is pressed, I increment or decrement the state variable as apprpriate. After updating the state variable, I use it to control a SELECT block or series of IF-THEN blocks to actually issue the selected command. There is probably a cleaner way to do this, so if anyone knows how, please reply :)
I can post an example if anyone's interested.
- JNOV
Revvin
10th January 2004, 12:32 AM
Yeah I had'nt got that far but it's been something in the back of my mind since postign that example, I'd be interested to see your script <s>
JNOV
11th January 2004, 12:52 AM
Here is part of my IL-2:FB script that sequences forwards and backwards through the zoom levels. The variable a1 can take on any value from 1 to 13, each of which represents a different zoom level. There are two buttons (defined above as d2 and d4 and whose presses turn on d10 and d11 for one cycle) for sequencing forwards and backwards through the zoom levels. Also, there are three buttons that allow the user to directly select the three "standard" levels (i.e., a1=1, 9, or 13). Some of this (like the "and not js1.b4") may not make sense, because it's part of a self-defined four-way shift system that I use in CMS. Just think of d10 and d11 as corresponding to the forward and reverse keys.
I hope this is useful!
- JNOV
================================================== =
pulse(d10) = d2 and not js1.b4;
pulse(d11) = d4 and not js1.b3;
if (d10) then
a11 = a11 + 1;
if ([a11 > 13]) then
a11 = 13;
endif
endif
if (d11) then
a11 = a11 - 1;
if ([a11 < 1]) then
a11 = 1;
endif
endif
if (js1.b9) then // directly choose "wide"
a11 = 13;
endif
if (js1.b10) then // directly choose "gunsight"
a11 = 1;
endif
if (js1.b12) then // directly choose "normal"
a11 = 9;
endif
sequence
wait((d10 or d11) and [a11==1]);
cms.b50 = TRUE;
delay(3);
cms.b50 = FALSE;
endsequence
sequence
wait((d10 or d11) and [a11==2]);
cms.b51 = TRUE;
delay(3);
cms.b51 = FALSE;
endsequence
sequence
wait((d10 or d11) and [a11==3]);
cms.b52 = TRUE;
delay(3);
cms.b52 = FALSE;
endsequence
sequence
wait((d10 or d11) and [a11==4]);
cms.b53 = TRUE;
delay(3);
cms.b53 = FALSE;
endsequence
sequence
wait((d10 or d11) and [a11==5]);
cms.b54 = TRUE;
delay(3);
cms.b54 = FALSE;
endsequence
sequence
wait((d10 or d11) and [a11==6]);
cms.b55 = TRUE;
delay(3);
cms.b55 = FALSE;
endsequence
sequence
wait((d10 or d11) and [a11==7]);
cms.b56 = TRUE;
delay(3);
cms.b56 = FALSE;
endsequence
sequence
wait((d10 or d11) and [a11==8]);
cms.b57 = TRUE;
delay(3);
cms.b57 = FALSE;
endsequence
sequence
wait((d10 or d11) and [a11==9]);
cms.b58 = TRUE;
delay(3);
cms.b58 = FALSE;
endsequence
sequence
wait((d10 or d11) and [a11==10]);
cms.b59 = TRUE;
delay(3);
cms.b59 = FALSE;
endsequence
sequence
wait((d10 or d11) and [a11==11]);
cms.b60 = TRUE;
delay(3);
cms.b60 = FALSE;
endsequence
sequence
wait((d10 or d11) and [a11==12]);
cms.b61 = TRUE;
delay(3);
cms.b61 = FALSE;
endsequence
sequence
wait((d10 or d11) and [a11==13]);
cms.b62 = TRUE;
delay(3);
cms.b62 = FALSE;
endsequence
Bob Church
12th January 2004, 10:35 AM
This one seems to come up a lot so I've put together an article and a couple of CMS files that show how to set it up with a SELECT block, how to avoid the delay instructions, how to make direct CASE settings repeatable, etc. Both of the sample CMS files are tested for basic operation. One is for simple command sequencing, the second is a more elaborate version with bidirection sequencing, repeatable direct settings, both continuous and pulsed outputs, etc.
Anyway, if you're interested I've posted the file on my web sit. Lookd for CMNOTE01.ZIP on the "Files" page.
- Bob
The StickWorks
http://www.stickworks.com
JNOV
12th January 2004, 05:22 PM
Thanks, Bob! I knew there had to be a better way :)
I looked at your scripts and they are, as usual, very clean. I wonder, however, about the "dummy state" workaround for the problem that a1 must change in order for the SELECT statement to execute the "reset" case. It seems to me that after pressing and releasing js1.b4, a1 is left with a value of 4 when the user thinks that it has been reset to 0.
For example, after resetting the sequence, the user expects the next press of js1.b2 to increment a1 to 1 from 0, but what seems to happen is that the "else" portion of the increment sequence block sets it to 0. Thus, after resetting, the user has to press js1.b2 twice to get to 1. Couldn't this be avoided by inserting a delay followed by a1 = 0 at the end of the reset sequence block? Or am I missing something?
I'd test it but I don't have access to my setup right now. When I get a chance to test it, I'll reply.
Thanks -- great work as always!
Bob Church
13th January 2004, 01:07 AM
Thanks JNOV! You do make an excellent point, one that I hadn't considered (not uncommon<g>). You could reset it like you suggest, but there's a problem with that in that if you send it back to State 0, it would see it as a new entry into State 0 and so execute that code again. I gave it a quick try with:
sequence
wait( js1.b4 ); // Wait until our Direct Set button is pushed
a1 = 0; // then just stick the value into a1
wait( not js1.b4 ); // Wait until it opens
a1 = 4;
delay( 1 );
a1 = 0;
endSequence
(I think that's what you meant) and it only cycled once. After that, State 0 stuck ON and you had to push it out of State 0 then back to State 0 to get it to execute again. Repeating the Direct Set button only worked one time as near as I could tell.
What does work, though, is to do something similar in the Increment block. Pick up State 4 as a special case and send it to State 1 (not 0) rather than taking the normal increment action:
sequence
wait( js1.b2 ); // Wait for the increment signal
if( [ a1 < 3 ] ) then // If it's less than 3, increment
a1 = a1 + 1;
else
if( [ a1 == 4 ] ) then
a1 = 1;
else
a1 = 0; // Otherwise, start over at 0
endIf
endIf
endSequence
It just simulates the increment from 0 to 1 by doing a direct set out of 4 into 1. The only anomaly is that State 0 is continuous normally and pulsed if you use the Direct Set, but if you need to be able to repeat the Direct Set, it shouldn't matter. You have to lose State 0 before you can re-execute it anyway.
The Decrement loop is fine since it normally goes from State 0 to State 3 on the "roll under", the transitions from State 4 to State 3 looks completely normal.
Anyway, thanks for pointing it out! Time for Rev. 1 of the CM Note<g>.
- Bob
The StickWorks
http://www.stickworks.com
JNOV
13th January 2004, 03:06 AM
Good point. Thanks!
531_Ghost
1st November 2005, 07:22 PM
And "List Mode" is born B)
Dirk98
26th December 2005, 11:26 PM
Guys, I'm still on CMv3.6 (sorry, Ghost :)) and am using the following simple script to have 2 functions on sequential press of the single button.
SEQUENCE
// First Command Operates on the first press of Joystick 1 Button 1
WHILE( JS1.B1 );
CMS.B1 = TRUE;
DELAY( 2 );
CMS.B1 = FALSE;
DELAY( 2 );
// Second Command Operates on the second press of Joystick 1 Button 1
WHILE( JS1.B1 );
CMS.B2 = TRUE;
DELAY( 2 );
CMS.B2 = FALSE;
DELAY( 2 );
ENDSEQUENCE
endScript
Now I want to add 2 more functions to the sequential press of the same button in the shifted state. How should this script look like in this case?
Thanks.
Dirk98
26th December 2005, 11:38 PM
I guess I'll need just to add + JS1.B4 (SHIFT) cases in the script. It works, but I dont know if it is the best solution here. Thanks. :)
Bob Church
26th December 2005, 11:55 PM
Hi Dirk,
Actually, you should probably use "WAIT" and not "WHILE" for that:
sequence
Â*Â*wait( js1.b1 );
Â*Â*...
Â*Â*wait( js1.b1 );
Â*Â*...
endSequence
I'm not sure that trying to put a shift button on there really makes any sense, at least not with a sequence. It's going to stop at the first WAIT and, well, wait. :) When you click it, then it will run through the code and stop at the second WAIT. Adding more steps is just a matter of adding more WAITs, and I'm not sure I understand what the shift button would do unless maybe you needed to use JS1.B1 for other things after the second WAIT and just didn't want the sequence to continue. Then maybe "WAIT( JS1.B1 AND JS1.B4)" (B4 being the shift in this example) would lock the sequence up at that point. If that's not the case, though, you might as well just click JS1.B1 again.
Anyway, I've probably missed the point. You might explain a bit more what you're trying to accomplish and maybe we could be more help.
Best regards,
- Bob
The StickWorks
http://www.stickworks.com
Dirk98
27th December 2005, 08:48 AM
Hi Dirk,
Actually, you should probably use "WAIT" and not "WHILE" for that:
sequence
Â*Â*wait( js1.b1 );
Â*Â*...
Â*Â*wait( js1.b1 );
Â*Â*...
endSequence
I'm not sure that trying to put a shift button on there really makes any sense, at least not with a sequence. It's going to stop at the first WAIT and, well, wait. :) When you click it, then it will run through the code and stop at the second WAIT. Adding more steps is just a matter of adding more WAITs, and I'm not sure I understand what the shift button would do unless maybe you needed to use JS1.B1 for other things after the second WAIT and just didn't want the sequence to continue. Then maybe "WAIT( JS1.B1 AND JS1.B4)" (B4 being the shift in this example) would lock the sequence up at that point. If that's not the case, though, you might as well just click JS1.B1 again.
Anyway, I've probably missed the point. You might explain a bit more what you're trying to accomplish and maybe we could be more help.
Best regards,
- Bob
The StickWorks
http://www.stickworks.com
[/b]
Thanks Bob,
I don't know, initially I found this part of sequence in your first post here.
// First Command Operates on the first press of Joystick 1 Button 1
SEQUENCE
WHILE( JS1.B1 );
CMS.B1 = TRUE;
DELAY( 2 );
CMS.B1 = FALSE;
DELAY( 2 );
// Second Command Operates on the second press of Joystick 1 Button 1
WHILE( JS1.B1 );
CMS.B2 = TRUE;
DELAY( 2 );
CMS.B2 = FALSE;
DELAY( 2 );
ENDSEQUENCE
On the fist press of JS1.B1 it produces CMS.B1 and on the second press of JS1.B1 it gives me CMS.B2. Then I wanted to add more functions in the shifted state of JS1.B1 so that it would produce CMS.B3 and CMS.B4 sequentially. Since my shift button is JS1.B4 I added the following lines:
SEQUENCE
WHILE( JS1.B1 + JS1.B4 );
CMS.B3 = TRUE;
DELAY( 2 );
CMS.B3 = FALSE;
DELAY( 2 );
// Second Command Operates on the second press of Joystick 1 Button 1
WHILE( JS1.B1 + JS1.B4 );
CMS.B4 = TRUE;
DELAY( 2 );
CMS.B4 = FALSE;
DELAY( 2 );
ENDSEQUENCE
I set DELAY to ( 10 ).
It works ok, but as I said I don't know if it is the most elegant solution for my task. Also, which delay time works best for simple macros?
Thanks.
Bob Church
27th December 2005, 09:11 AM
Hi Dirk,
>> I don't know, initially I found this part of sequence in your first post here. <<
Actually, that was Revvin's post. It really does work about the same so long as you click the buttonand release it before the next WHILE. If you were to press it and hold it, the WHILE won't pause and wait for the button to release and then press again. It will run the whole sequence over and over if you hold the button down. The WAIT requires that the button be released and then pressed again. There's really just usually not much reason to use a WHILE unless it's the only conditional in the sequence. Once you start it, you probably want it to finish anyway.
>> It works ok, but as I said I don't know if it is the most elegant solution for my task. Also, which delay time works best for simple macros? <<
It just depends on what you want to do. A delay time of "1" is the time you set on the Program Settings tab for the Character Rate. It keeps it sync'd with any characters that are going out that way. Beyond that you just need to figure out how often you need to make something happen. A delay time of 1 or 2 is usually enough to cover a button click, e.g. you'll have enough time to release the trigger without a repeat. You really just need to plug in a value and then sort things out from there. I usually plug a long time in initially for the delay I'm working with. That way I can tell when it happens and get a feel for how long it should be, then I shorten it until it does what I want. For slow delays, I'll just tie it to a DX button so I can watch it in the test screen at first even if I'm eventually going to send a character with it.
Best regards,
- Bob
The StickWorks
http://www.stickworks.com
Dirk98
27th December 2005, 12:37 PM
Thanks, Bob! Excellent explanation, thank you very much. (Do you ever sleep btw? :) [unless you are in Europe]) < see, unquoted properly :rofl:
Bob Church
28th December 2005, 03:21 AM
Hi Dirk,
>> Thanks, Bob! Excellent explanation, thank you very much. <<
You're quite welcome!
>> (Do you ever sleep btw? [unless you are in Europe]) <<
Oh, on occasion. :) Mostly I just keep rather odd hours.
>> < see, unquoted properly <<
:)
Good luck with the map! If you need any more help just ask!
Best regards,
- Bob
The StickWorks
http://www.stickworks.com
Powered by vBulletin® Version 4.1.4 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.