Synchronize switches with xplane not working

Support for Arduino in combination with Air Manager and Air Player

Moderators: russ, Ralph

Message
Author
xplanearg
Posts: 44
Joined: Mon May 04, 2020 10:37 am

Synchronize switches with xplane not working

#1 Post by xplanearg »

Hello, I've purchased airmanager with the purpose of using switches with xplane.
Ive read the api docs and tutorials, my switches are coded like so:

Code: Select all

function switch_battery_callback(position)
  print("The battery switch got changed to position " .. position)
  if position == 0 then
    xpl_command("sim/electrical/battery_1_off")
  elseif position == 1 then
    xpl_command("sim/electrical/battery_1_on")
  end
end
hw_switch_add("Battery", 2, switch_battery_callback)
This is the same method described in the examples:
http://siminnovations.com/wiki/index.ph ... n_tutorial

If i start airmanager after xplane is running it works fine, switches are synchronized. Xplane will adopt what ever position the switch is at.

However if i start first airmanager first and then xplane, when xplane loads, the switches positions are not synchronized. Meaning the physical position of the switch does not match the one in xplane.

The same happens if i change aircraft from xplane (loading a new plane), all my switches are not synchronized.

How can i force synchronization from the lua code when airmanager detects xplane is connected, or any change of situation?

Because of my sim structure airmanager lives on a separate computer that gets turned on before the main computer running xplane.
This problem is quite limiting, as not having the ability to sync switches positions defeats the purpose.

Would subscribing the callback to a dataref fix this?
Thanks

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

Re: Synchronize switches with xplane not working

#2 Post by Sling »

It’s quite simple to fix that behaviour. Follow these steps and you should be good.

Create a variable to store the hardware switch position at the head of your code and initialise it with the hardware switch position. You can get the position by using the hw_switch_get_position() function.

Update this variable with the switch position in the switch callback.

Subscribe to the dataref that relates to the switch in question and in the callback compare the subscribed data (sim switch position) to the previously stored hardware switch position. If they are different call the switch callback with the correct position data as the argument.

Let us know how you go.

Tony

User avatar
jph
Posts: 2846
Joined: Fri Apr 10, 2020 12:50 pm
Location: Somewhere over the rainbow..

Re: Synchronize switches with xplane not working

#3 Post by jph »

@Sling @xplanearg @Ralph

Hi guys and good morning from here.
Just a comment - thinking out loud again... :o :D

In the graphic in the example you mention Tony, I actually find the Sim Inno example for this both confusing and unnecessary ?
as in the example code and schematics - http://siminnovations.com/wiki/index.ph ... n_tutorial
image.png
:shock:

Given the switch examples shown, there is no need for 2 inputs to ever be used ?
Surely, there is absolutely no difference between 'two way switch' and 'one way switch' as per diagram ?
Each can be assigned one single port pin. The internal weak pullups make the input Logical 1 when the grounding is not present (Open circuit) - meaning a 'position' value of 0 returned.
When the input pin is grounded, then the pin logic level is 0, and the 'position value returned is 1.
Surely In both examples the switch(s) are actually a one way switch (for the purpose of the code example !) - either ON or OFF and no other state possible and only 1 port pin is ever needed. ? - In the 'two way switch' example image - and code - then all that is needed is to simply ignore one pin on the dual pin switch ? The 'two way' 3 pin is purely for electrical use - not coding.
- but, in the case of the example here - it is simply being used as a simple 2 STATE indication, which is exactly the same as a single ON/OFF to all intents and purposes - which IS a two state, yet single pin in both cases.
That would also simplify the code to a basic approximation of -

Code: Select all

function switch_battery_callback(position)
   if position == 1 then
     print("The battery switch got changed to ON ")   -- add any actions in this position
   else
     print("The battery switch got changed to OFF ")  -- add any actions in this position
   end
end
hw_switch_add("Battery", 1, switch_battery_callback)
FOR EITHER SWITCH - it is simply a case of connecting a single grounded wire to the switch and a single wire signal input to the Arduino.

Again, no need to use two pins at all.
Apologies if my brain is numb, it IS early haha .. :shock: - so that would not be too surprising.
and, of course, the on state determination is still needed as per what Tony said..
Joe. CISSP, MSc.

xplanearg
Posts: 44
Joined: Mon May 04, 2020 10:37 am

Re: Synchronize switches with xplane not working

#4 Post by xplanearg »

Sling wrote: Sat Apr 10, 2021 4:35 am It’s quite simple to fix that behaviour. Follow these steps and you should be good.

Create a variable to store the hardware switch position at the head of your code and initialise it with the hardware switch position. You can get the position by using the hw_switch_get_position() function.

Update this variable with the switch position in the switch callback.

Subscribe to the dataref that relates to the switch in question and in the callback compare the subscribed data (sim switch position) to the previously stored hardware switch position. If they are different call the switch callback with the correct position data as the argument.

Let us know how you go.

Tony
hi, thanks for the answer however its problematic for me to convert your explanation into actual code.
can you please provide a code example?

ive done it this way, with success. im still testing it to see if in some case this does not work, but so far i have sucess:

Code: Select all

function switch_49_callback(position)
  local position = hw_switch_get_position(switch_49_id)
  print("The switch landing lights got changed to position " .. position)
  if position == 0 then
    xpl_command("sim/lights/landing_lights_off")
  elseif position == 1 then
    xpl_command("sim/lights/landing_lights_on")
  end
end
switch_49_id = hw_switch_add("ARDUINO_MEGA2560_A_D49", switch_49_callback)
xpl_dataref_subscribe("sim/cockpit2/switches/landing_lights_on", "INT", switch_49_callback)

User avatar
jph
Posts: 2846
Joined: Fri Apr 10, 2020 12:50 pm
Location: Somewhere over the rainbow..

Re: Synchronize switches with xplane not working

#5 Post by jph »

Also,
IF you wanted an ON/ON switch then there is no difference in hardware at all. - you simply use the on / off switch. All you need is a simple signal of the two states.
In the code, the is a tiny change - and even that is entirely up to what YOU decide to do - nothing at all to do with the hardware.
The 'position' of the switch returns either 0 or 1. (in this case)

Hence, if you wanted ON/ON you could do -

Code: Select all

function switch_battery_callback(position)
   if position == 1 then
     print("The switch got changed to ON 1 ")   -- add any actions in this position
   else
     print("The switch got changed to ON 2 ")  -- add any actions in this position
   end
end
hw_switch_add("Battery", 1, switch_battery_callback)
Exactly the same hardware - nothing else needed - hence - 'two way' switch..... which if you think about it - IS a one way switch.. either on or off electrically - but, in CODE - YOU select what it does... simple binary 0 or 1 that you create an action for. The fact that the return is 0 or 1 doesn't mean it remains as such. The 'return' value is simply use to trigger whatever you want.

You could also use exactly the same wiring / switch to create anything you want - as in - for example - let's create a value of 66 or 102 depending on the 'position' return - which = 0 or 1 initially.

Code: Select all

function switch_some_action_callback(position)   
   if position == 1 then
      position = 66 -- make an ice cream
    print (position)   
   else
      position = 102 -- make a cake
    print (position)
   end
end
hw_switch_add("Battery", 1, switch_some_action_callback)
Hopefully, it can be seen that the 'return' value from the switch can be translated to do anything you want.
Joe. CISSP, MSc.

User avatar
jph
Posts: 2846
Joined: Fri Apr 10, 2020 12:50 pm
Location: Somewhere over the rainbow..

Re: Synchronize switches with xplane not working

#6 Post by jph »

@Sling
Hi Tony,
Please advise ?
I am totally baffled by the hw_switch_get_position function ?
Please can you offer some input ?
I attempted, miserably, to perform the following with absolutely no result.
I get - ERROR - logic.lua:19: Argument 'id(1)' in function 'hw_switch_get_position' is not a valid reference, which is not allowed
It is all a learning exercise. But the weights for this one are more than I can lift ;) :D
Everything else is fine - but this ? .. yikes. :o

Joe


Code: Select all

function switchid(position)
 print(position)
end


function switch_landing_lights_callback(position)
  print("The switch landing lights got changed to position " .. position)
  if position == 0 then
    --xpl_command("sim/lights/landing_lights_off")
  print("The switch landing lights got changed to position OFF " .. position)
  else 
   -- xpl_command("sim/lights/landing_lights_on")
  print("The switch landing lights got changed to position ON " .. position)
  end
end
 hw_switch_add("landing_lights",1, switch_landing_lights_callback)
 hw_switch_get_position(switchid)
an image may hep ?? dunno ???
hw switch get.jpg
Joe. CISSP, MSc.

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

Re: Synchronize switches with xplane not working

#7 Post by Sling »

Ok here’s a couple of things going on here’s it probably would of been better to start a new thread. But anyways I’ll try and answer both in 2 separate posts so as not to get them mixed up.

First up @jph

To use the get position function with a switch you need to tell it what switch it is getting the position for. To do this it needs the switch Id. You’ve given it switch_id but you haven’t actually created switch_id. The switch_add needs switch_id = at the beginning. Also do not get confused by the way it’s being used in xplanearg’s code because that’s un-conventional.

Tony

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

Re: Synchronize switches with xplane not working

#8 Post by Sling »

@xplanearg Let me explain. First up what you have come up with will work but it has flaws in that you are sharing the same callback for the switch and the subscribe. The switch callback and subscribe callback can and often do have different arguments that are given to the callback to perform its function. In this case you have stumbled across a working solution because you are only using a single argument for each and it happens to be the valid data for both sources.
Let me show the conventional way to do this as per my instructions.

Create a variable to store the hardware switch position at the head of your code and initialise it with the hardware switch position. You can get the position by using the hw_switch_get_position() function.
I made a little error here. It should go after the switch add because it can’t get the position until the switch has been added. See below.

Update this variable with the switch position in the switch callback.

Code: Select all

function switch_49_callback(position)
 
    if position == 0 then
        xpl_command("sim/lights/landing_lights_off")
    else
        xpl_command("sim/lights/landing_lights_on")
    end
    hw_sw_pos = position —update hw switch position var
    
end
switch_49_id = hw_switch_add("ARDUINO_MEGA2560_A_D49", switch_49_callback)

local hw_sw_pos = hw_switch_get_position(switch_49_id) —this is the var create and initialise
Subscribe to the dataref that relates to the switch in question and in the callback compare the subscribed data (sim switch position) to the previously stored hardware switch position. If they are different call the switch callback with the correct position data as the argument.

Code: Select all

function subscribe_callback(pos)
    —if sim switch position does not match the hardware switch position then
    —call the switch callback to send the correct command to the sim
    If pos ~= hw_sw_pos then
        switch_49_callback(hw_sw_pos)
    end
end
xpl_dataref_subscribe("sim/cockpit2/switches/landing_lights_on", "INT", subscribe_callback)
Like I said at the start, your code will work but for the reasons given this is the more conventional method.

Hopefully this explains how to do it and what is happening in each step. A slightly different method would not use a variable to store the hw switch position but just use the hw_switch_get_position() function within the subscribe callback to get the hw switch position just before doing the comparison.

I hope this helps.

Tony
Last edited by Sling on Wed Apr 14, 2021 7:58 am, edited 1 time in total.

xplanearg
Posts: 44
Joined: Mon May 04, 2020 10:37 am

Re: Synchronize switches with xplane not working

#9 Post by xplanearg »

Hi Tony, thanks for your answer. Finally i can get my hands into actual code.
I will test your method, however i think this example should be added into the airmanager API website and WIKI examples, to avoid confusion for other people as using the hw_switch_add function is only half of the story to get the actual switch working properly.

thanks again.

User avatar
jph
Posts: 2846
Joined: Fri Apr 10, 2020 12:50 pm
Location: Somewhere over the rainbow..

Re: Synchronize switches with xplane not working

#10 Post by jph »

Sling wrote: Sat Apr 10, 2021 3:23 pm Ok here’s a couple of things going on here’s it probably would of been better to start a new thread. But anyways I’ll try and answer both in 2 separate posts so as not to get them mixed up.

First up @jph

To use the get position function with a switch you need to tell it what switch it is getting the position for. To do this it needs the switch Id. You’ve given it switch_id but you haven’t actually created switch_id. The switch_add needs switch_id = at the beginning. Also do not get confused by the way it’s being used in xplanearg’s code because that’s un-conventional.

Tony
Thanks Tony,
Wood for the trees etc ;)
Much appreciated, A silly oversight by me but hey :D -
Still experimenting with permutations on the theme as it is very interesting and a great learning exercise.
Joe
Joe. CISSP, MSc.

Post Reply