Jump to content
The simFlight Network Forums

Recommended Posts

Posted

Hello,

My program try to used FSUIPC write data to P3D and read data from P3D in the same time. In my code, If I click disconnect button will show exception.

AccessViolationException was unhandled
An unhandled exception of type 'System.AccessViolationException' occurred in mscorlib.dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

this is Exception:

FSUIPCClientReadAndWriteQuickly.exe!FSUIPCClientReadAndWriteQuickly.MainWindow.ReadFSUIPC() Line 70
FSUIPCClientReadAndWriteQuickly.exe!FSUIPCClientReadAndWriteQuickly.MainWindow.Worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) Line 151
System.dll!System.ComponentModel.BackgroundWorker.OnDoWork(System.ComponentModel.DoWorkEventArgs e) Line 107
System.dll!System.ComponentModel.BackgroundWorker.WorkerThreadStart(object argument) Line 245
[Native to Managed Transition]	
[Managed to Native Transition]	
mscorlib.dll!System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage msg, System.Runtime.Remoting.Messaging.IMessageSink replySink) Line 298
mscorlib.dll!System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.ThreadPoolCallBack(object o) Line 753
mscorlib.dll!System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(object state) Line 1274
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 954
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 902
mscorlib.dll!System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() Line 1252
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Line 820
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() Line 1161

And this is my code:

using FSUIPC;
using System;
using System.ComponentModel;
using System.IO;
using System.IO.Ports;
using System.Text;
using System.Windows;
using System.Windows.Forms;

namespace FSUIPCClientReadAndWriteQuickly
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // Private Static Members
        private static readonly string AppTitle = "FSUIPCClientApplication_CSharp";

        // Create the Offsets we're interested in for this Application
        private Offset<Double> Elevator_Read_Rad = new Offset<Double>(0x2E98);  // Basic integer read and write example
        private Offset<Int16> Elevator_Read = new Offset<Int16>(0x0BB2);  // Basic integer read and write example
        private Offset<Int16> Elevator_Write = new Offset<Int16>(0x0BB2);  // Basic integer read and write example
        private Offset<Double> Aileron_Read_Rad = new Offset<Double>(0x2EA8);  // Basic integer read and write example
        private Offset<Int16> Aileron_Read = new Offset<Int16>(0x0BB6);  // Basic integer read and write example
        private Offset<Int16> Aileron_Write = new Offset<Int16>(0x0BB6);  // Basic integer read and write example
        private Offset<Double> Rudder_Read_Rad = new Offset<Double>(0x2EB8);  // Basic integer read and write example
        private Offset<Int16> Rudder_Read = new Offset<Int16>(0x0BBA);  // Basic integer read and write example
        private Offset<Int16> Rudder_Write = new Offset<Int16>(0x0BBA);  // Basic integer read and write example
        private Offset<Int32> AutoPilot_Read = new Offset<Int32>(0x07BC);  // Basic integer read and write example
        private Offset<Int32> AutoPilot_Write = new Offset<Int32>(0x07BC);  // Basic integer read and write example

        private readonly BackgroundWorker Worker = new BackgroundWorker();
        private SerialPort port = null;
        private delegate void UIControl();
        private double[] a = new double[4] { 0, 13000, -16383, 16383 };
        string FSUIPCClientReadAndWriteQuicklyfilePath = AppDomain.CurrentDomain.BaseDirectory + "/FSUIPCClientReadAndWriteQuickly" + ".txt";
        string DebugLogfilePath = AppDomain.CurrentDomain.BaseDirectory + "/DebugLog" + ".txt";

        public MainWindow()
        {
            InitializeComponent();
            Workerfunction();

            ConnectButton.Click += Connect;
            DisconnectButton.Click += Disconnect;
        }

        private void OpenFSUIPC()
        {
            try
            {
                // Attempt to open a connection to FSUIPC (running on any version of Flight Sim)
                FSUIPCConnection.Open();
            }
            catch (Exception ex)
            {
                // Badness occurred - show the error message
                System.Windows.Forms.MessageBox.Show(ex.Message, AppTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
                FSUIPCConnection.Close();
                WriteFile(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffffff") + "\n" + ex.Message + "\n", DebugLogfilePath);
            }
        }

        private void ReadFSUIPC()
        {
            try
            {
                //Thread.Sleep(50);
                FSUIPCConnection.Process();
                double Elevator_Deg = SignificantBit(Elevator_Read_Rad.Value * 180 / Math.PI, 2);
                int Elevator = Elevator_Read.Value;
                double Aileron_Deg = SignificantBit(Aileron_Read_Rad.Value * 180 / Math.PI, 2);
                int Aileron = Aileron_Read.Value;
                double Rudder_Deg = SignificantBit(Rudder_Read_Rad.Value * 180 / Math.PI, 2);
                int Rudder = Rudder_Read.Value;
                int AutoPilot = AutoPilot_Read.Value;

                UIControl receiveDatafromTarget = delegate ()
                {
                    ElevatorRadReadTextBox.Text = Elevator_Deg.ToString();
                    ElevatorReadTextBox.Text = Elevator.ToString();
                    AileronRadReadTextBox.Text = Aileron_Deg.ToString();
                    AileronReadTextBox.Text = Aileron.ToString();
                    RudderRadReadTextBox.Text = Rudder_Deg.ToString();
                    RudderReadTextBox.Text = Rudder.ToString();
                    AutoPilotReadTextBox.Text = AutoPilot.ToString();
                };
                this.Dispatcher.Invoke(receiveDatafromTarget);
                WriteFile(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffffff") + "\n" +
                          "Rudder(Read): " + Rudder + ",\t" +
                          "Rudder Degree(Read): " + Rudder_Deg + ",\t" +
                          "Aileron(Read): " + Aileron + ",\t" +
                          "Aileron Degree(Read): " + Aileron_Deg + ",\t" +
                          "Elevator(Read): " + Elevator + ",\t" +
                          "Elevator Degree(Read): " + Elevator_Deg + ",\t" +
                          "AutoPilot(Read): " + AutoPilot + "\n", FSUIPCClientReadAndWriteQuicklyfilePath);
            }
            catch (FSUIPCException ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message, AppTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
                FSUIPCConnection.Close();
                WriteFile(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffffff") + "\n" + ex.Message + "\n", DebugLogfilePath);
            }
            catch (Exception ex)
            {
                // Sometime when the connection is lost, bad data gets returned 
                // and causes problems with some of the other lines.  
                // This catch block just makes sure the user doesn't see any
                // other Exceptions apart from FSUIPCExceptions.
                System.Windows.Forms.MessageBox.Show(ex.Message, AppTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
                WriteFile(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffffff") + "\n" + ex.Message + "\n", DebugLogfilePath);
            }
        }

        private void WriteFSUIPC(string value)
        {
            Rudder_Write.Value = (Int16)Map(a, double.Parse(value), 0);
            WriteFile(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffffff") + "\n" +
                      "Rudder(write): " + Map(a, double.Parse(value), 0) + "\n", FSUIPCClientReadAndWriteQuicklyfilePath);
        }

        private void Connect(object sender, RoutedEventArgs e)
        {
            OpenFSUIPC();
            InitialSerialPort();
            if (!Worker.IsBusy)
            {
                /// Starts execution of a background operation.
                Worker.RunWorkerAsync();
            }
        }

        private void Disconnect(object sender, RoutedEventArgs e)
        {
            FSUIPCConnection.Close();
            DisposeSerialPort();
            Worker.CancelAsync();
        }

        private void Workerfunction()
        {
            Worker.DoWork += Worker_DoWork;
            Worker.WorkerSupportsCancellation = true;
        }

        private void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            while (port.IsOpen)
            {
                ReadFSUIPC();
                this.DataReceived();
            }
        }

        private void InitialSerialPort()
        {
            try
            {
                string portName = "COM3";
                port = new SerialPort(portName, 115200);
                port.Encoding = Encoding.ASCII;
                port.Open();
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show("Error! When initialization serial port!" + ex.Message, "Prompt information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                WriteFile(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffffff") + "\n" + ex.Message + "\n", DebugLogfilePath);
            }
        }

        private void DisposeSerialPort()
        {
            if (port != null)
            {
                try
                {
                    if (port.IsOpen)
                    {
                        port.Close();
                    }
                    port.Dispose();
                }
                catch (Exception ex)
                {
                    System.Windows.Forms.MessageBox.Show("Error! When close the serials." + ex.Message, "Prompt information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    WriteFile(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffffff") + "\n" + ex.Message + "\n", DebugLogfilePath);
                }
            }
        }

        private void DataReceived()
        {
            if (port != null)
            {
                if (port.IsOpen)
                {
                    //Thread.Sleep(50);
                    string value = port.ReadLine();
                    if (value.Length == 14 && value.Substring(0, 7) == "Arduino")
                    {
                        string temp = value.Substring(8, 5);
                        UIControl receiveDatafromTarget = delegate ()
                        {
                            RudderWriteTextBox.Text = temp;
                        };
                        this.Dispatcher.Invoke(receiveDatafromTarget);
                        WriteFSUIPC(temp);
                    }
                }
            }
        }

        private double Map(double[] coordinate, double x, int significantBit)
        {
            double y = (coordinate[3] - coordinate[2]) * (x - coordinate[0]) / (coordinate[1] - coordinate[0]) + coordinate[2];

            return SignificantBit(y, significantBit);
        }

        private double SignificantBit(double value, int significantBit)
        {
            return ((value >= 0 ? Math.Round(value + 5 / Math.Pow(10, 1 + significantBit), significantBit, MidpointRounding.AwayFromZero) :
                                  Math.Round(value, significantBit, MidpointRounding.AwayFromZero)));
        }

        private void WriteFile(string msg, string filePath)
        {
            if (!System.IO.File.Exists(filePath))
            {
                FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write);
                StreamWriter sw = new StreamWriter(fs);
                sw.WriteLine(msg);
                sw.Close();
                fs.Close();
            }
            else
            {
                FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
                StreamWriter sw = new StreamWriter(fs);
                sw.WriteLine(msg);
                sw.Close();
                fs.Close();
            }
        }
    }
}

Anyone can help me?

Posted
2 hours ago, Primo said:

Anyone can help me?

I don't know what language you are using. If it is related to Paul Henty's .Net DLL you need to post in his support Sub-Forum above.

Generally, to find bugs in an accessory program you need to use the debugger appropriate to the language, and which is provided as part of your compilation system.

Pete

 

Posted
On ‎03‎/‎01‎/‎2018 at 5:57 PM, Pete Dowson said:

I don't know what language you are using. If it is related to Paul Henty's .Net DLL you need to post in his support Sub-Forum above.

Generally, to find bugs in an accessory program you need to use the debugger appropriate to the language, and which is provided as part of your compilation system.

Pete

 

Hi Pete,

At first, in my code, I used this class to read and write.

http://forum.simflight.com/topic/84657-systemargumentoutofrangeexception-on-fsuipcfsuipc_process/?do=findComment&comment=511822

And Now, I used FSUIPCClient.dll do work, but it have same problem. I also have found the same problem on this web, but I can't solve it.

Can you help me?

 

Posted
4 hours ago, Primo said:

Can you help me?

No. You either need to decode the error to determine what is wrong with your program, or, more productively perhaps, ask in Paul Henty's subforum above (he is the author of FSUIPCclient.DLL). I did advise this before!

Pete

 

Posted

Ouch. The Forum software won't let me. I can move it to other SimFlight forums, but not to any subForums. Seems the MOVE facility is only from Subforums to others or to the main Forum, of from Forum to Forum, but not Forum to SubForum. Which is very odd and restrictive. I'll ask the "powers that be" about that!

Pete

 

Posted

Hi Primo,

I can't run this code because I don't have a serial port with anything connected.

I see you're using a background worker thread. It's likely that this is causing the problem. I'm not sure exactly how.

If you can give me some example code that I can run that shows the problem I might be able to find what's going wrong and offer a solution.

Just one comment about your code... you should not have separate offsets for reading and writing. You can use the same offset.

Paul

Posted
9 hours ago, Paul Henty said:

I see you're using a background worker thread. It's likely that this is causing the problem. I'm not sure exactly how.

Yes, I agree with you!

I also have another code, in this code, i used MATLAB real time pc to send UDP and my code receive and write value to P3D, if this way you also can't ..., I will try to another way.

You can download my code.

Thanks for your help!

Primo

FSUIPCClientReadAndWriteQuickly.rar

Posted

Hi Primo,

I got it to run. I had to comment out the UDP receive code because I don't have Matlab or time to write a UDP server program. However, the multi-threaded code was still active.

I stopped the code waiting for receive from UDP and just had this instead:
 

        private void XpcValueDataProcessing()
        {
            if (commDataFSUIPC.airPlaneAutoPilot_Read == "1")
            {
                commDataFSUIPC.WriteFSUIPC(0);
            }
        }

It ran fine for a good few minutes. Every time I turned the autopilot on, your program turned it off again instantly.

I wonder if it's the version of the DLL you are using. I've attached the latest version (the one that I tested with). Maybe this will fix things. (Note that it targets the full 4.0 framework).

If you still have problems, I think you'll need to get some simpler code that shows the problem so I can reproduce it here.

Paul

FSUIPCClient3.0_RC7.zip

Posted
10 minutes ago, Paul Henty said:

I wonder if it's the version of the DLL you are using. I've attached the latest version (the one that I tested with). Maybe this will fix things. (Note that it targets the full 4.0 framework).

If you still have problems, I think you'll need to get some simpler code that shows the problem so I can reproduce it here.

Paul

FSUIPCClient3.0_RC7.zip

Thank you for your reply. I also have test the latest version, but it have the same problem.

change autopilot status it no problem.

In my code, if you have click start UDP button and never click stop UDP button, when you try to click engage and disengage again and again, will show my problem.

Posted
Quote

In my code, if you have click start UDP button and never click stop UDP button, when you try to click engage and disengage again and again, will show my problem.

I think that's what I did:

1. I pressed Connect

2. I pressed Start UDP

Then in the cockpit of the plane in FSX I switched the autoplot on.

Your program turned it off.

I clicked the Autopilot button quickly and it still worked with no problems.

I can't make it error. Is there anything else I should do?

Can you check the DLL being used with: FSUIPC.FSUIPCConnection.DLLVersion.ToString(); in the code. Make sure it returns 3.0.18004.210

Paul

Posted
1 hour ago, Paul Henty said:

I think that's what I did:

1. I pressed Connect

2. I pressed Start UDP

Maybe you need to do like this:

1.  pressed Connect;

2.  pressed Start UDP;

3.  pressed Disconnect;

4.  pressed Connect;

5.  pressed Disconnect;

...

4.

5.

Posted
1 hour ago, Paul Henty said:

I think that's what I did:

1. I pressed Connect

2. I pressed Start UDP

Then in the cockpit of the plane in FSX I switched the autoplot on.

Your program turned it off.

I clicked the Autopilot button quickly and it still worked with no problems.

I can't make it error. Is there anything else I should do?

Can you check the DLL being used with: FSUIPC.FSUIPCConnection.DLLVersion.ToString(); in the code. Make sure it returns 3.0.18004.210

Paul

Hi Paul

I have create a new code, I think you can download and have a try.

In this code, I add the latest version(FSUIPCConnection.DLLVersion.ToString() == "3.0.18004.210")

And you can do like this:

1.  pressed Connect;

2.  pressed Disconnect;

1.

2.

...

...

1.

2.

FSUIPCClientReadAndWriteQuickly.rar

Run project FSUIPCClientReadAndWriteQuickly_Internal, please!

Posted

Thanks for the project.

I found the problem.

The FSUIPCConnection.Close() method was not synchronised with the Process() method.

So, while Process() was running on one thread, another thread sometimes ran Close() at the same time and unallocated the memory Process() was using.

I've ran your example, connecting and disconnecting many times, and I couldn't get the error any more.

Attached is version 3.0.18009.241

Let me know how it goes...

Paul

FSUIPCClient3.0_RC7.zip

Posted
11 hours ago, Paul Henty said:

Thanks for the project.

I found the problem.

The FSUIPCConnection.Close() method was not synchronised with the Process() method.

So, while Process() was running on one thread, another thread sometimes ran Close() at the same time and unallocated the memory Process() was using.

I've ran your example, connecting and disconnecting many times, and I couldn't get the error any more.

Attached is version 3.0.18009.241

Let me know how it goes...

Paul

FSUIPCClient3.0_RC7.zip

Hi Paul,

I also have test it, and couldn't get the error any more.

Thank you very much!

Primo

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.