More functions for 1 momentary switch

Help creating logic scripts for Air Manager Instruments

Moderators: russ, Ralph

Message
Author
jedeen
Posts: 527
Joined: Fri Jan 13, 2017 5:41 pm

More functions for 1 momentary switch

#1 Post by jedeen »

Hello, I need some advise from experts :D
In a few weeks I need to assign different functions to one momentary button.
Normally that is done by using a counter to count the times that the button is pressed.
You use a variable and store that and every time you press the button, that variable is incremented by one and stored again, and so on.
BTW: the button is not a hardware button, just a button with a dataref. So no bouncing ??????
This is the code I use:

Code: Select all

function add()

local start = 0
local old_start = 0
local page1 = 0

		old_start = persist_get(ctr_begin)
		print("old_start is  " .. old_start)
		start = old_start + 1
		persist_put(ctr_begin, start)

--0 = mapmode....1 = ctr page ... 2 = ctr page with VSD
end

function pushbutton(ctr_pb)

		if ctr_pb == 1 then					--tested also with pb ~= 0
			my_timer = timer_start(1000, nil, add)
		end

end
xpl_dataref_subscribe("laminar/B738/EFIS_control/capt/push_button/ctr", "INT", pushbutton)		--ctr_pb
But every time I press that button, old_start gives me:
old start is 4
old start is 3
old start is 2
old start is 1
old start is 0
It seems as if here some bouncing is going on but again, it's not a hardware button and " old_start " always ends with 4.

Can someone explain to me where I am going wrong. :oops:
I use AM3.3 beta.

Have Fun
Jedeen

JackZ
Posts: 2262
Joined: Mon Feb 22, 2016 1:02 pm

Re: More functions for 1 momentary switch

#2 Post by JackZ »

Hi Jedeen

I'm lost: Why are you saying there is some bouncing?
Bouncing is when some additional push state is incorrectly recorded by the software, due to some shortcircuits between contacts when the hardware button is pressed/released (more frequent with poor quality pushbuttons). In your "software" button, that would mean that when you receive an input, more inputs are recorded.

When I try use your code, the old_start value seems to be correctly incremented each time I pressed the button (had to add a button instead of subscription, since I don't use Xplane).
So if there is a problem of additionnal keypresses, that means that the subscription is sending multiple values?

The only difference on your test code is that I added the following line before to initialize the persistance value:

Code: Select all

ctr_begin=persist_add("p_ctr_begin", "INT",0)
Though I don't understand the use of persist/get the way you do it. It saves the start value, that gets incremented each time, so even when you stop/restart the instrument, you get the old start value (for example currently 14).
But maybe I didn't get what you intended to do?


Jacques
My YouTube Chanel on the A320 (Real SOPs by an Airline Pilot IRL):
https://www.youtube.com/playlist?list=P ... 0Q6SBASRqJ

JackZ
Posts: 2262
Joined: Mon Feb 22, 2016 1:02 pm

Re: More functions for 1 momentary switch

#3 Post by JackZ »

I also don't get why you are using timer to call the add() function.
Is it for resetting the start_value after a while if a button has not been pressed? If you don't press the button before 3 sec then the start_value is reset to 0?

I tried this code instead, don't know if it's useful for you:

Code: Select all

rst_time=3000 -- resets the start_value if the button has not been pressed after rst_time in msec
tmr_reset=true
ctr_begin=persist_add("p_ctr_begin", "INT",0)

function add()
local start = 0
local old_start = 0
local page1 = 0
		if tmr_reset==true then
			persist_put(ctr_begin, start)			
		end
		old_start = persist_get(ctr_begin)
		print("old_start is  " .. old_start)
		start = old_start + 1
		persist_put(ctr_begin, start)

--0 = mapmode....1 = ctr page ... 2 = ctr page with VSD
end

function reset()
	tmr_reset=true
end

function pushbutton_callback()
	pushbutton(1)
end

function pushbutton(ctr_pb)

		if ctr_pb == 1 then					--tested also with pb ~= 0
			--my_timer = timer_start(1000, nil, add)
			add()
			tmr_reset=false
			if timer_running(reset_timer) then timer_stop(reset_timer) end
			reset_timer=timer_start(rst_time,nil,reset)
			print("start")
		end
end

button_id = button_add("dialhsi.png","headingbug.png",100,100,50,50, pushbutton_callback)               -- button created to emulate pushbuttons
--xpl_dataref_subscribe("laminar/B738/EFIS_control/capt/push_button/ctr", "INT", pushbutton)		--ctr_pb
Jacques
My YouTube Chanel on the A320 (Real SOPs by an Airline Pilot IRL):
https://www.youtube.com/playlist?list=P ... 0Q6SBASRqJ

jedeen
Posts: 527
Joined: Fri Jan 13, 2017 5:41 pm

Re: More functions for 1 momentary switch

#4 Post by jedeen »

Hey Jacques,
thanks for the quick answer.
First of all.......of course I use " persist_add...." It's about 5000 lines higher up in my code.
Just to ensure that those mem places are reset to 0 when I start the instrument
And the timer, I was using that to see if there was some bouncing :P ...yeah one does strange things when debugging.

But this is maybe the reason for my troubles:
So if there is a problem of additionnal keypresses, that means that the subscription is sending multiple values?
I have indeed multiple subscriptions for the same dataref in my code, maybe that's the reason.
According to the data ref tool, the dataref itself is only transmitting a 1 on keypress and a 0 on release
I will do a test with just one function and 1 subscription.

I'll let you know what the results are
Have Fun
Derk

jedeen
Posts: 527
Joined: Fri Jan 13, 2017 5:41 pm

Re: More functions for 1 momentary switch

#5 Post by jedeen »

Well Jacques,
you put me on the right track.
The counter in one lonely function, works fine.
That means that I have a lot of changes to make in my code.
Thanks again for your help
Sometimes the obvious is not so visible :(
Have fun
Derk

User avatar
Sling
Posts: 5237
Joined: Mon Sep 11, 2017 2:37 pm
Contact:

Re: More functions for 1 momentary switch

#6 Post by Sling »

Derk,

You may of realised by now but it really is not a good idea to subscribe to a dataref more than once in your code. I can't think why you would want to. The best thing is just do it once and in the corresponding callback function make a global var of the dataref and then use it where you want in your code.

Code: Select all

function callback(dr)

    gbl_var = dr

end
Tony

User avatar
Ralph
Posts: 7878
Joined: Tue Oct 27, 2015 7:02 pm
Location: De Steeg
Contact:

Re: More functions for 1 momentary switch

#7 Post by Ralph »

Why not just let the timer always run, set a global variable to true if you press it and false when you let it go. Saves you all the start, stop and reset troubles.

The downside is that you might have to wait for it to respond, when you press it just after the callback has fired, then you have to wait a maximum of 999ms before it starts. That might be an issue actually...

Using the same dataref at multiple subscribes is not that bad. Sometimes it can be necessary when you need for example the altitude at multiple places. Saves you the global variable hassle, and you know for sure that the other function is being called as well.

User avatar
Sling
Posts: 5237
Joined: Mon Sep 11, 2017 2:37 pm
Contact:

Re: More functions for 1 momentary switch

#8 Post by Sling »

Just my opinion Ralph but I don't see what the hassle is with having the altitude global it's less code and it's available to any code that needs it. Also if I want to change the subscribe I only have to do it in one place. Am I missing something or is this just a difference of preferred method.

I normally call functions that I want to run when the dataref updates in the dataref subscribe callback loop so I am in control of the run order. If you multi subscribe what determines the run order?

Tony

jedeen
Posts: 527
Joined: Fri Jan 13, 2017 5:41 pm

Re: More functions for 1 momentary switch

#9 Post by jedeen »

Ralph...Tony.....you both are right, but I use an other method. :D
I have now about 6000 lines of codes and just 2 global variables and 1 global array......that's pretty good in my opinion 8-)
One of the global vars (ctr_var) I use for that counter I mentioned earlier.
When a certain value is reached, one can call the appropriate function with " blabla() "......but, when this function has for instance the instruction
ctr_wayp = string.len(ctr_waypoints) and ctr_waypoints is a dataref, then you get an error, because the function has not been updated
with the value of that dataref nor with all the other datarefs.
So what I am doing is, write a value to a not used dataref (for instance "load bombs" ), that dataref is part of the function I want to start
when a certain value of my counter is reached......and voila.
The function is started with all the data that is needed.

I haven't test it completely, because I deleted those multiple calls to the same dataref of that button and I am not yet finished with recoding.
The downside of this method is, when someone else is also using that non used dataref for other purposes, then I have a problem.
Maybe I can use those "inter instrument" variables ????? I did not work with them up to now, but I will try it. ;)

Have Fun
Derk

Update:
change of plans.....using a not used dataref works like a charm.....but I abandon it.
Now I let this dataref " laminar/B738/autopilot/blink " update/trigger my function, and it's ok now.
Working with "inter instrument" variables didn't work. A pity, i did like the color that Jacque did use for this statement....pink :lol:

User avatar
Ralph
Posts: 7878
Joined: Tue Oct 27, 2015 7:02 pm
Location: De Steeg
Contact:

Re: More functions for 1 momentary switch

#10 Post by Ralph »

Why didn't inter instrument variables work?

Post Reply