View Full Version : At button push. Read axis value and send command.
thdees
18th August 2008, 10:08 PM
Hi,
Here is my problem and my solution, it's just that I can't seem to cut the code to get it to work. I believe it is quite simple.
I have segregated an axis for the cowl flaps command in IL2 which works really well. The problem I have is that if I forget to put the lever back to the closed position before I hit refly then the lever is out of sync with the actual radiator setting in the game which is always closed on refly. What this means is that I have to manually sync them by pulling the lever to the closed position then hitting the "r" key until the game shows the radiator is closed.
Here is my solution to this but I need help on the coding.
I'd like to set up a button that when pressed reads the position of the axis and sends the appropriate amount of key presses to the game to sync with the lever. For example. If I leave the lever in the open position I can press the button and the script will send 5 "r" presses to the game thereby opening the radiator and sync'ing the game with the lever postition.
In simple english.
Push button,
read axis value,
If axis value between x and y then send desired amount of key presses.
I couldn't find any other examples that used this so am looking for some help.
Thanks,
thdees
Bob Church
19th August 2008, 01:23 AM
Hi thdees,
Can you always send 5 "R"s and get there even if maybe it only needs three because it's already at some intermediat position? If you can, then the button would just have to always send 5 and that's easy enough to set up.
If you need to have it "track", maybe 1 "R" if you're near the end already, "3" if you're about halfway up, it's a little trickier but still not too difficult.
How exactly does it have to work?
Best regards,
- Bob
The StickWorks
http://www.stickworks.com
thdees
19th August 2008, 03:53 AM
Hi Bob,
Thanks for the quick response as usual.
It is the tricky one I'm afraid.
In IL2 they way the Radiator (Cowl Flaps) commands are implemented are a real pain.
You have to open the radiator all the way up and then the next button press closes it. The default key is an "r"
Press r once and you get radiator pos 2, a second time and you move to radiator pos 4 and so on through pos 6, pos 8 then open. Then once more to close. So to go from closed and back to closed again you have to press the "r" key 6 times.
I have this mapped to a segregated axis on the TQ so as I pass up through the range an "r null" is sent then when I pull it back to the bottom the release is sent and a single "r" sends the close signal.
When you refly the radiator is always set back to closed.
So what I would like is if I leave the lever in say position 4, then hit refly and I push my sync button the script detects that the axis is in the range for position 4 and sends 2 "r" presses. Likewise if I have the lever fully forward in the open postition and I push the button it detects the postition of the lever as fully open and sends 5 "r" presses. There are a couple of planes in the game that have different radiator settings and I am prepared to work around those but the majority use 5 "r"s to get to open and one more to close.
Does this make things a little clearer.
Here is my segregated axis and the ranges for your info.
cms.a10 = js4.a2
cms.b6 = [ cms.a10 < 215 ];
cms.b7 = [ cms.a10 < 170 ];
cms.b8 = [ cms.a10 < 130 ];
cms.b9 = [ cms.a10 < 85 ];
cms.b10 = [ cms.a10 < 43 ];
Regards,
thdees
Bob Church
21st August 2008, 03:24 AM
Hi thdees,
>> It is the tricky one I'm afraid. <<
You were right about that. :) Anway, I think I've got it. I made a map with just the TQ in it and I just copied the TQ axis 4 to CM Axis 10. I don't know how you're actually doing it, but that seemed to be all that mattered. You'll probably want to move the Refly button, I just hung it on the first TQ toggle. If the Refly button is already part of your map, you could just use that I suppose. Anyway, looking at what you were doing, I'm sure you can make whatever changes you need.
The CMS file looks like this:
script
// Copy js1.a4 to cms.a10.
//
cms.a10 = js1.a4;
// js1.b2 is the "refly button. Generate a 1 scan pulse when it's
// clicked. The d2 bit is set later and used do lock things out
// so it can't start a moving things again until it's done with the
// first on.
//
pulse( d1 ) = js1.b2 AND NOT d2;
// Set up the limit points for the cowl flap position. You might
// want more or less. This give a maximum of 4 pulses, I think that
// what you want but you can add more points if you need to.
//
if( d1 ) then
b1 = TRUE;
if([ cms.a10 < 215 ]) then // 215
a1 = 1;
endIf
if([ cms.a10 < 170 ]) then // 170
a1 = 2;
endIf
if([ cms.a10 < 130 ]) then // 130
a1 = 3;
endIf
if([ cms.a10 < 85 ]) then // 85
a1 = 4;
endIf
if([ cms.a10 < 43 ]) then // 43
a1 = 5;
endIf
endIf
// a1 holds the number of characters to send. It need to send a press
// and then a release to work, otherwise the key just sticks down. The
// PERIOD timer is set to generate a fixed width pulse that's twice
// as long as it will take to send the character so it sends one press
// and one release. The output of the first timer (d2) is use to run
// and interval timer just long enough to send the number of presses
// releases that a1 indicates.
//
// If you need to set longer character periods, you need to change the
// arithmetid to compensat. The PERIOD timer has to be just long enoug
// to send enough presses and release, so if the INTERVAL timer were
// set to 2, 2 for example, than the PERIOD timer would have to be set
// 4 * a1 to keep the interval timer running long enough.
//
timer( PERIOD, d2, ( 2 * a1 )) = [ a1 > 0 ];
timer( INTERVAL, d3, 1, 1 ) = d2;
// Each time we a character gets sent, reduce the count by one.
// when a1 makes it to 0, its done.
//
a1 = a1 - 1;
// Send a 1 character width pulse cms.b6. The cms.b6 button is
// programmed in the GUI to send "r NULL".
//
cms.b6 = d3;
endScript
Give it a try and see if it does what you want. If not, we can try something else. It looks good here, though, if I understood what you wanted in the first place.
Let me know how it goes!
Best regards,
- Bob
The StickWorks
http://www.stickworks.com
thdees
21st August 2008, 09:52 PM
Hi Bob,
Thanks for that. I'm having a few issues getting things to work at the moment. It is almost as if there is a conflict somewhere with something else in my map.
To test, I created a single map for the TQ like you and it works as expected but when I transfer the code to my existing map and have notepad open in the background, as soon as I download it it sends a string of 30+ r's to notepad then nothing. It doesn't matter where I position the axis I get nothing else.
I didn't have a lot of time to devote to it last night but will take another look this weekend.
I'll let you know how it goes.
Regards,
thdees
531_Ghost
21st August 2008, 10:09 PM
Is there a NULL after the r?
Bob Church
21st August 2008, 11:43 PM
Hi thdees,
I don't know. Ghost is right about the NULL but you mentioned that in your first post. Could you post the entire MAP, the CMS file, and a CMC file if you're using one? The "30+" doesn't sound like it's being "sent", it just sounds like the key isn't releasing. HID keyboards only send a report at press and a second report at release. The repeat is generated by Windows itself, but there is no real transition. The PS2 keyboards used to actually send repeated presses with a single release at the end. It looks the same in NotePad (for example) if you're actually typing, but if Notepad (Windows, really) were to just see the press and not the release, the key would act stuck like that until some other key came along to send a report that didn't include the "r" key. They don't really send press and release reports, the send a report that shows what keys are currently pressed. The "r" would be one of them. A release is really reported by sending the report without the "r" in it.
I only mention all that because I thought it might save you some trouble looking for a way that the CMS script could send 30+ "r"s when it's probably just seeing the "r" report but not the "no r" report.
Another thing to watch are things like other keys going down with ALT, SHF, or CTL modifiers. HID keyboards will send as many as 6 characters at a time, but any of the modifiers is just a flag and seems to get interpreted as applying to all the keys that are pressed. I don't know offhand, does "CTL r" or "ALT r" mean something to Notepad? It does the same with SHF, and you'll automatically get the SHF from the CM if you just enter the key as "R", the CM knows it needs shifting so sends "SHF r". There really is no "R" key.
Anyway, if you can't sort it out and want to post the maps, etc. I'd be glad to take a look.
Best regards,
- Bob
The StickWorks
http://www.stickworks.com
thdees
22nd August 2008, 12:36 AM
Hi,
Yes I have the NULL command after the r and I see where you are coming from Bob I've been caught with the SHFT thing in the past.
What confuses me is that it works as expected if I only have the TQ mapped, but once I combine that bit of code into my main map things go awry.
In order to combine it I have to change the cms axis to match my setup and the refly button is different. I've checked that cms.<x> is the same through the whole section.
I'll devote some time to it over the weekend, thanks for all your help so far.
Cheers,
thdees
Bob Church
22nd August 2008, 03:17 AM
Hi thdees,
Okay. I've never known the CM to collide with another program like that, but you can never be sure and I certainly ran into some odd things yesterday before I came up with what was there. Never a repeater, but it would send the "r" once and that was that, or it would send the "r" once per button click. This looked and felt stable, though.
You might try playing with the "Character Rate" setting on the "Program Settings" tab. It's controlling what "1 tick" is for the timers and things as well as how long the keys are held for. It's set to 50 probably, 25 is the fastest and 200 is the slowest. Maybe it's hitting NotePad too quickly, though that's kind of hard to imagine. You could adjust that or maybe use:
keys +r chardly -r chardly
You can put multiple chardly statements in:
keys +r chardly chardly chardly -r chardly
rather than the:
r Null
It has the same effect as the Character Rate, but you can adjust a single key that way. Usually a missed "release" report means the key down time is too short, but Character Rates out around 60+ (it's character time, actually) start to get a little sluggish. With chardly, you only have to slow down one key, and it won't play with the timers themselves, they're still locked to Character Rate.
Anyway, good hunting and the offer to look at the files is still there if you'd like someone else to look at it.
Let us know how it turns out!
Best regards,
- Bob
The StickWorks
http://www.stickworks.com
thdees
22nd August 2008, 07:54 AM
Hi Bob,
Just a quick update. It is working sort of.
Two anomolies.
When I first download the map and open up either a notepad or the keychecker in the CH manger I get 30 r's or 30 press and releases of the r. If I change the ( 2 * a1 ) to a 1 * a1 I get 15. Likewise if i up it to 4 and the intervals to 2 i get too many to count but I think it will be a multiple of 5
timer( PERIOD, d2, ( 2 * a1 )) = [ a1 > 0 ];
timer( INTERVAL, d3, 1, 1 ) = d2;
Now once that has finished I can press my refly button and the most it will send is 3 r's but I at least now I am getting a response from the refly and a change in the number of r's depending on the lever location.
The only thing I changed from last night was the cms axis from a6 to a9
Very strange indeed.
I'll keep looking.
Cheers,
thdees
Bob Church
22nd August 2008, 10:17 AM
Hi thdees,
The doubling of the timer period doubling the clocks does suggest that it's counting the character actually, and not just a stuck key. It would do that if it thought that it were a long way from where it should be, like a1 getting set to 30 somehow. It could happen if cms.a10 were greater then 215, the chain of "IF" statements would never preset A1 and if it had a random value in it for some reason, it would have to play out that many presses one time.
Try presetting a1 to maybe 5 before the chain of IF statements, then if cms.a10 is greater than 215, a1 would have a sane value in it and wouldn't send the long string of characters at least. As it is now, if a1 could contain any value up to around 2 trillion, and if cms.a10 were greater than 215 it would never get set to the 1..5 range.
Try it and see if it helps, If it does, we can probably work around it. At least we'll have a clue as to what's gone astray.
Edit: There's definitely a little bug there with the a1 variable and the refly switch logic. Try adding this to the top of the program immediately after the "cms.a10 = js1.a4;" statement:
if( NOT d2 ) then
a1 = 0;
endIf
The idea is to force a1 to 0 if d2 is FALSE and the thing hasn't been triggered. It's kind of hard to say for sure that that will stop it but it looks like it should. It's just kind of difficult to see what the interactions with d2 might be. If it works, it should lock the characters out entirely unless it's been triggered. Give it a try and let me know how it goes.
Best regards,
- Bob
The StickWorks
http://www.stickworks.com
thdees
23rd August 2008, 01:36 AM
Hi Bob,
Getting close now :)
That last couple of lines has fixed the extra letters at the start. It's still not getting the full range of r's though. will check my values for the ranges but I'm pretty sure they are correct. Here are the responses from the key check when I hit my sync (refly) button.
axis in pos for Rad 2 = 1 r
axis in pos for Rad 4 = 1 r
axis in pos for Rad 6 = 2 r's
axis in pos for Rad 8 = 2 r's
axis fully forward, pos for Rad Open = 3 r's
It should go 1, 2, 3, 4, 5
Thanks again for your continuing support.
Regards,
thdees
Bob Church
23rd August 2008, 03:59 AM
Hi thdees,
>> Getting close now. That last couple of lines has fixed the extra letters at the start. <<
:) Sometimes it's a "game of inches". You just need to experiment until things work to your satisfaction. There are so many things interacting it can be difficult to get it all lined up.
>> It's still not getting the full range of r's though. <<
Okay. Well, you've got 5 slots so you should be okay there. I'd play with the code down around the two timers:
timer( PERIOD, d2, ( 2 * a1 )) = [ a1 > 0 ];
timer( INTERVAL, d3, 1, 1 ) = d2;
The interval timer generates pulses so long as d2 is TRUE, effectively pressing and releasing cms.b6. The trick is to get d2 to stay TRUE for the right amount of time to generate however many pulses you need. The INTERVAL timer generates a press and release every two clock ticks, so for 5 pulses you'd need d2 to be TRUE for 10 clock ticks (5 pressed, 5 released). My first inclination would be to play with the arithmetic ( currently the "2 * a1" in the timer statement) and try to get it to hold longer so that the INTERVAL timer is able to send more pulses before the PERIOD timer times out and the INTERVAL timer stops running.
See if you can make any headway with that. Try "(4 * a1)" and see if you get more pulses, in theory that would double the number of press/release cycles and should give you more. It might need to be figured differently. The formula that figures the INTERVAL timer period can be most anything you can come up with, it just needs to hold d2 TRUE for the proper length of time. I don't see anything that simply wouldn't work (but I've been wrong beforel
Another possibility might be to just set a fixed value for the INTERVAL time based on what zone it's in, not try to calculate the period. Just figure out what it need to be and depending on the zone stuff it into the PERIOD timer.
I think we're almost there. Try playing around with the calculation there and let me know how it goes. Surely we can outsmart that bit of sand and tinfoil, it's not really all that smart that smart.
Best regards,
- Bob
The StickWorks
http://www.stickworks.com
thdees
23rd August 2008, 09:17 AM
Hi Bob,
You've cracked it! I increased 2 * a1 to 4 * a1 and it worked like a charm.
Once again thank you very much. :thumbsup:
I'm posting the working script for anyone else that might like to use it.
//---------------------------------------------------------------
//RADIATOR AXIS SEGREGATION
//---------------------------------------------------------------
cms.a9 = js4.a2;
cms.b6 = [ cms.a9 < 245 ];
cms.b7 = [ cms.a9 < 185 ];
cms.b8 = [ cms.a9 < 120 ];
cms.b9 = [ cms.a9 < 75 ];
cms.b10 = [ cms.a9 < 43 ];
// cms buttons set to r NULL for press on all and cms.b6 set to r on release
// the release is left blank on all the rest.
//---------------------------------------------------------------
//RADIATOR LEVER SYNC
//---------------------------------------------------------------
if( NOT d2 ) then
a1 = 0;
endIf
pulse( d1 ) = js4.b4 AND NOT d2;
if( d1 ) then
b1 = TRUE;
if([ cms.a9 < 245 ]) then
a1 = 1;
endIf
if([ cms.a9 < 185 ]) then
a1 = 2;
endIf
if([ cms.a9 < 120 ]) then
a1 = 3;
endIf
if([ cms.a9 < 75 ]) then
a1 = 4;
endIf
if([ cms.a9 < 43 ]) then
a1 = 5;
endIf
endIf
timer( PERIOD, d2, ( 4 * a1 )) = [ a1 > 0 ];
timer( INTERVAL, d3, 1, 1 ) = d2;
a1 = a1 - 1;
cms.b14 = d3;
//cms.b14 is set to r NULL
I can see this working for someone that might want to set up a salvo of some sort. Depending on the lever postition it would generate the number of presses required to fire a number of measured shots.
Thanks heaps,
Thdees
Bob Church
23rd August 2008, 09:48 PM
Hi thdees,
Great! I knew there had to be a way (probably 100 ways), sometimes it's hard to figure out what it is, but there wasn't anything there that I could see that was inherently not possible. Sometimes it's just hard to figure what's going to work.
Anyway you're quite welcome. It was an interesting little puzzle, I'm glad we could get it working!
Have fun with it!
Best regards,
- Bob
The StickWorks
http://www.stickworks.com
Powered by vBulletin® Version 4.1.4 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.