Jump to content
The simFlight Network Forums

Some newbie questions


rfresh

Recommended Posts

I'm new to using your great .DLL - thanks for writing it.

 

I'm using VS 2013 Express C#.

 

I have installed FSUIPC and it registered OK with FSX when I started FSX up.

 

I started with you sample code from your userGuide:

 

 

            try
            {
                FSUIPCConnection.Open();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "FSX Connetion Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
 
My questions are:
 
(1) When I run this code I get the MsgBox display inside my VS 2013 IDE. I am not sure if I have to run FSUIPC on its own or if that happens when I start up FSX?
 
(2) I couldn't see a way to run FSUIPC by itself so I guess I have to be running FSX to get it loaded and running, right?
 
(3) How does one get FSX to sleep? When I have FSX running, my VS 2013 IDE doesn't respond very well. Is this the way the development cycle works: you have FSX running and your VS IDE? How do you test your C# code changes in FSX if the IDE isn't responsive? It's like FSX is hogging all the resources. I'm not sure how the dev cycle is supposed to work.
 
Thanks for any help to get me on my way...
 

 

Link to comment
Share on other sites

Hi Ralph,

 

1) FSUIPC should be loaded by FSX. If the FSUIPC menu is in the 'Addons' menu in FSX then it's running and the DLL should connect. If you continue to have problems connecting then the text in the message box might help diagnose the problem.

 

2) Yes, FSX (or WideClient.exe) needs to be running on the same machine.

 

3) If your PC/Laptop is fast enough and has enough memory it shouldn't be a problem running VS and FSX at the same time. My development laptop is an i7 running at 1.6 ghz and has 8gb of memory and runs both at the same time with no problem (although I have set FSX to low settings - see next paragraph). If your computer doesn't have much memory or has a slow processor then that could be the cause of your problems.

 

You can try to improve things by turning down all the scenery options in FSX to very low settings and avoiding third-party scenery and aircraft. Also running in a very small sized window might help. I see you've got the PMDG 737 in your signature - that will not be helping matters if you have that loaded. Of course if this is essential for your application then there's not much you can do.

 

If you have another PC on your home network that can run Visual Studio then you could invest in Pete's WideFS program. You'll need to buy a licence for WideFS (make sure it's version 7) and register it on the FSX PC. Then on the Visual Studio PC you can run WideClient.exe which is tiny in comparison to FSX. This will act like FSUIPC on the VS pc and will talk to the FSX PC over the network to get all your values, but it hardly uses any resources.

 

So, yes, it sounds like you're doing everything right, it's just that your PC doesn't sound like it's up to the job of running two large programs like FSX and VS2013.

 

Paul

Link to comment
Share on other sites

I guess it was my 2nd monitor. I unhooked it from my main PC and I can now run FSX and VS 2013 Express C# together OK. I'll continue to fiddle with the 2nd monitor as having to go back to working with just one monitor is a pain.

Link to comment
Share on other sites

Well, I'm back on one monitor for now.

 

I can Open the connection OK.

I was trying to read the fuel level in my PMDG 737NGX center fuel tank but I don't think I'm getting the right return value.

Pete's offset table shows 0B74 as the offset for the center tank level.

 

            try
            {
                FSUIPCConnection.Open();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "FSUIPC Connetion Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
 
            Offset<int> centerFuelTankLevel = new Offset<int>(0x0B74);
            FSUIPCConnection.Process();
            this.Text = centerFuelTankLevel.ToString();
 
The title bar displays: FSUIPC.Offset 1 [system.Int32]
Link to comment
Share on other sites

Firstly you're declaring an offset in the method. This is not good practice as you run the risk of creating duplicate offsets. I recommend you always create the offsets at class (form) level. See the C# sample application (the top of the main form code) to see the correct place to put all the offset declarations.

 

Turning to the main problem.... the centerFuelTankLevel is a variable representing the Offset<int> class. That's why ToString() is giving you that class name back.

 

To get the value from the offset you need to use the Value property:

this.Text = centerFuelTankLevel.Value.ToString();

Now, this will give you a large number which won't mean much. In the documentation Pete says the value here is scaled like this:
 

 

% * 128 * 65536

 

 

 

So you need to reverse this scaling to get a value that's useful to you.

double centerFuelPercent = (double)centerFuelTankLevel.Value / 128d / 65536d * 100d;
this.Text = centerFuel.ToString("F0") + "%";

The (double) is a cast to convert the integer to a double so we can do floating point maths on it.

The 'd' after the literal numbers is to define these as doubles instead of integers.

The "F0" in the ToString() method is to format the number with 0 decimal places.

 

Having said all of that, there is much easier way of working with payloads and fuel in my DLL. You need version 2.4 if you've not already got that. You can get it from the link below. At the bottom of the same thread is example code in C# of reading the fuel tanks with the "PayloadServices". With this method everything is converted to the various units for you (lbs, kg, percentages etc) and you don't need to worry about any conversions or scaling.

 

http://forum.simflight.com/topic/74848-fsuipc-client-dll-for-net-version-24/

 

You code would become:

            try
            {
                FSUIPCConnection.Open();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "FSUIPC Connetion Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            // Get a reference to save so much typing later...
            PayloadServices ps = FSUIPCConnection.PayloadServices;
            // Get the latest data from FSUIPC
            ps.RefreshData();
            // Display centre tank percentage
            this.Text = ps.GetFuelTank(FSFuelTanks.Centre_Main).LevelPercentage.ToString("F0") + "%";

If you need any more help with this let me know.

 

Paul

Link to comment
Share on other sites

I do have 2.4 zip but the user guide doc says ver 2.0 and I don't see anything in this doc re PayLoadServices ???

 

I see the doc update further down on the webpage.

 

Below I get the center tank fuel level in pounds and that displays correctly.

Then I set it to 5000 pounds and do another read and correctly get back 5000 pounds...however, my center tank gauge (737NGX) in the center engine display does not show 5000 pounds...it still shows the original load.

 

            // Get a reference to save so much typing later...
            PayloadServices ps = FSUIPCConnection.PayloadServices;
            // Get the latest data from FSUIPC
            ps.RefreshData();
            // Display centre tank percentage
            string str1 = ps.GetFuelTank(FSFuelTanks.Centre_Main).WeightLbs.ToString("F0");
            ps.GetFuelTank(FSFuelTanks.Centre_Main).WeightLbs = 5000;
            string str2 = ps.GetFuelTank(FSFuelTanks.Centre_Main).WeightLbs.ToString("F0");
            this.Text = str1 + " " + str2;
            ps.WriteChanges();
Link to comment
Share on other sites

The documentation hasn't been updated since 2.0. The documentation for the new 2.4 features (which includes the payload services) is in the thread I linked you to.

 

Please see the section in the user guide pdf called 'licence' (page 3) for details about donations.

 

Paul

Link to comment
Share on other sites

If you write fuel tank levels with WriteChanges() then these should show up instantly in the sim.

 

To really make sure the new level is being written, do another ps.RefreshData() after the WriteChanges() and then get the value again. At the moment your check is just reading the local (pending) value you've set as it's before the WriteChanges() call.

 

If that comes back okay then here are some other thoughts:

 

1. If you just read the centre tank without changing it, does it match the gauge on the 737?

 

2. Is the change from your program reflected in the FSX Fuel dialog from the Aircraft menu?

 

3. Have you tried the code with the default 737? It may be that PDMG don't use the FSX fuel tanks at all, but use their own code. This sort of thing is common with complex add-on aircraft.

 

4. Maybe they are using one of the other centre tanks - try Centre_2 and Centre_3.

 

I'm not sure about the nested menus - I'll look in to that tomorrow.

 

Paul

Link to comment
Share on other sites

If you write fuel tank levels with WriteChanges() then these should show up instantly in the sim.

 

To really make sure the new level is being written, do another ps.RefreshData() after the WriteChanges() and then get the value again. At the moment your check is just reading the local (pending) value you've set as it's before the WriteChanges() call.

 

If that comes back okay then here are some other thoughts:

 

1. If you just read the centre tank without changing it, does it match the gauge on the 737?

 

2. Is the change from your program reflected in the FSX Fuel dialog from the Aircraft menu?

 

3. Have you tried the code with the default 737? It may be that PDMG don't use the FSX fuel tanks at all, but use their own code. This sort of thing is common with complex add-on aircraft.

 

4. Maybe they are using one of the other centre tanks - try Centre_2 and Centre_3.

 

I'm not sure about the nested menus - I'll look in to that tomorrow.

 

Paul

 

>1. If you just read the centre tank without changing it, does it match the gauge on the 737?

 

Yes. Both the PMDG 737NGX and the MS Default 737NGX center tank reads the correct fuel load in pounds.

 

>2. Is the change from your program reflected in the FSX Fuel dialog from the Aircraft menu?

 

MS Default 737NGX: Yes. PMDG 737NGX: No.

Even with the MS Default 737NGX, my setting of 8000 pounds in the center tank shows up in the cockpit but not in str2 in my form title.

 

>. Maybe they are using one of the other centre tanks - try Centre_2 and Centre_3.

I tried all of these on the PMDG model and they returned 0.

So, PMDG must be using their own tank codes eh?

For the Default MS 737NGX, I can read and set the center tank values but my pull into str2 doesn't work for some reason.

 

And BTW, this line:

            ps.GetFuelTank(FSFuelTanks.Left_Main).WeightLbs = 8000;

This is a Get method, but we use it to also Set a value?

 

            // Get a reference to save so much typing later...
            PayloadServices ps = FSUIPCConnection.PayloadServices;
            // Get the latest data from FSUIPC
            ps.RefreshData();
            // Display centre tank percentage
            string str1 = ps.GetFuelTank(FSFuelTanks.Centre_Main).WeightLbs.ToString("F0");
            ps.GetFuelTank(FSFuelTanks.Centre_Main).WeightLbs = 8000;
            ps.WriteChanges();
            ps.RefreshData();
            string str2 = ps.GetFuelTank(FSFuelTanks.Centre_Main).WeightLbs.ToString("F0");
            this.Text = str1 + " " + str2;
Link to comment
Share on other sites

Thanks for the information.

 

I've just run your code here and the reason you're not reading back the new fuel level is that the refresh is too soon. It seems that FSX or FSUIPC needs a bit of time to adjust to the new values in the fuel tank. If you put a pause between them then it works as expected.

            // Get a reference to save so much typing later...
            PayloadServices ps = FSUIPCConnection.PayloadServices;
            // Get the latest data from FSUIPC
            ps.RefreshData();
            // Display centre tank percentage
            string str1 = ps.GetFuelTank(FSFuelTanks.Centre_Main).WeightLbs.ToString("F0");
            ps.GetFuelTank(FSFuelTanks.Centre_Main).WeightLbs = 16000;
            ps.WriteChanges();
            Thread.Sleep(2000); // Wait 2 seconds for everything to catch up
            ps.RefreshData();
            string str2 = ps.GetFuelTank(FSFuelTanks.Centre_Main).WeightLbs.ToString("F0");
            this.Text = str1 + " " + str2;

You probably don't need to wait a full 2 seconds, that's just what I used to test this.

 

And BTW, this line:

            ps.GetFuelTank(FSFuelTanks.Left_Main).WeightLbs = 8000;

This is a Get method, but we use it to also Set a value?

 

 

 

The 'get' part is getting the fuel tank object. Once you have got the fuel tank object you set the WeightLbs property on that object. If I break it into two steps you can see it makes more sense.

FsFuelTank leftTank = ps.GetFuelTank(FSFuelTanks.Left_Main);
leftTank.WeightLbs = 8000;

Putting it all in one line just saves typing and creating a variable. You might want to break it out though if you need to do more work on the single tank. This will save running the GetFuelTank method over and over. So imagine some code like this:

FsFuelTank leftTank = ps.GetFuelTank(FSFuelTanks.Left_Main);
if (leftTank.WeightLbs < 1000 && automaticRefuelActive)
{
   leftTank.LevelPercentage = 100;
   ps.WriteChanges();
}

This makes more sense than calling GetFuelTank twice and also makes the code cleaner and easier to read.

 

 

So now to the main problem of the PDMG737 not respecting the fuel level changes. What's probably happening is that the PMDG code is constantly updating the fuel levels in the FSX tanks, So when you write your level it's soon overwritten again by the PMDG code. The reason for this is so they can more accurately simulate fuel consumption and feeding fuel betweens tanks.

 

There are special offsets in FSUIPC for the PMDG 737ngx which allow access to areas of the aircraft that are modelled outside of FSX. These would normally not be available to FSUIPC but Pete has integrated FSUIPC with PDMG's SDK. For details of how to enable this interface and the extra offsets available see the document called "Offset Mapping for PMDG 737NGX.pdf" in the FSUIPC Documents folder under your FSX modules folder.

 

This will not help with your fuel however as they are all read-only. The document does however mention that certain aspects of the 737NGX can be changed by sending 'controls' via FSUIPC. These are listed in the PMDG 737 SDK documentation. I don't have this aircraft so I can't look myself, but there might be controls to set fuel levels.

 

Another place you can look for help is the 'User Contributions' forum under Pete's main support forum. Someone may have already solved this problem. Also if PMDG have forums then you could also try asking there.

 

Paul

Link to comment
Share on other sites

Thanks Paul for that info.

 

I realize that you and Pete know a hell of a lot more about this than I do, but I wanted to mention some add-ons can create nested menus. I use the Opus Software camera utility and they create nested FSX menus. Obviously I don't know how after what you have stated. They must be doing something different with their software.

Link to comment
Share on other sites

So I have a small form that I'm entering fuel load values into textboxes and writing the changes to the aircraft.

 

The line

            leftTank.WeightLbs = Convert.ToDouble(textBoxLeftTank.Text.ToString());

has leftTank as null and gives a runtime error.

I can't see why this should not work?

Even

            leftTank.WeightLbs = 8000;

gives the same null error.

 

            PayloadServices ps = FSUIPCConnection.PayloadServices;
            FsFuelTank leftTank = ps.GetFuelTank(FSFuelTanks.Left_Main);
            FsFuelTank centerTank = ps.GetFuelTank(FSFuelTanks.Centre_Main);
            FsFuelTank rightTank = ps.GetFuelTank(FSFuelTanks.Right_Main);
 
            leftTank.WeightLbs = Convert.ToDouble(textBoxLeftTank.Text.ToString());
 
            centerTank.WeightLbs = Convert.ToDouble(textBoxCenterTank.Text.ToString());
            rightTank.WeightLbs = Convert.ToDouble(textBoxRightTank.Text.ToString());
            ps.WriteChanges();
            ps.RefreshData();
Link to comment
Share on other sites

Hi Paul

 

Here I'm trying to fetch the aircraft name but this.Text doesn't display the name.

 

    public partial class FSXFuelConfigForm : Form
    {
        private Offset<string> aircraftName = new Offset<string>("info", 0x3D00, 24);
 
        public FSXFuelConfigForm()
        {
            InitializeComponent();
        }
 
        private Offset<string> aircraftName = new Offset<string>("info", 0x3D00, 24);
        
        private void FSXFuelConfigForm_Load(object sender, EventArgs e)
        {
            try
            {
                FSUIPCConnection.Open();
            }
            catch (FSUIPCException ex)
            {
                if (ex.FSUIPCErrorCode == FSUIPCError.FSUIPC_ERR_SENDMSG)
                {
                    // Send message error - connection to FSUIPC lost.
                    // Show message, relight the
                    // connection button:
                    // Also Close the broken connection.
                    FSUIPCConnection.Close();
                    MessageBox.Show("Unable to connect to FSX.");
                }
                else
                {
                    // not the disonnect error so some other baddness occured.
                    // just rethrow to halt the application throw ex; }
                }
            }
            PayloadServices ps = FSUIPCConnection.PayloadServices;
            FSUIPCConnection.Process();
            ps.RefreshData();
            this.Text = aircraftName.Value.ToString();
        }
}
Link to comment
Share on other sites

I saw from one of the examples I needed to do this:

 

            FSUIPCConnection.Process("info");

 

to get the aircraftName to populate.

 

I also see that "info" can be any name I want to use to identify this specific Group. I can use "acName" or "info2" if I wanted and it will still work.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.