Jump to content
The simFlight Network Forums

Paul Henty

Members
  • Posts

    1,652
  • Joined

  • Days Won

    74

Everything posted by Paul Henty

  1. Hi Sean, Thanks for your kind words. Its always good to know that people are finding the DLL useful. Congratulations on your achievement, Paul
  2. Tinsukou, I've just PM'd you the latest 1.4 beta version of my Client DLL. This does all the hard work for you and just presents you with a collection of AITraffic objects. I haven't officially released it because I haven't written the documentation yet. If anyone else finds this thread and wants this version, please PM me and I'll send it to you with some example code. Paul
  3. Hi Raimund, I'm still not too clear what the problem is, but looking at the code I can see two potential problem areas: This second line could throw an exception with 109.50 because nav2bcdString will be "950". Then nav2bcdString.Substring(2, 2) will throw an exception because there is no character 4. To avoid this use the format code "X4" to make sure there are always 4 characters returned (it will pad leading 0s). Dim nav2bcdString As String = nav2bcd.Value.ToString("X4") In this section... You are calling the Process() BEFORE you've set the value. You should really set the value first, then call process. Or, if you are using a timer cycle that calls Process() regularly, you can even remove this process() call from here. Should be: If Me.txtNav1Input.Text > "" Then Try nav2bcd.Value = Short.Parse(txtNav1Input.Text, Globalization.NumberStyles.AllowHexSpecifier) FSUIPCConnection.Process() Catch ex As Exception MessageBox.Show(ex.Message, NavError, MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End If I hope this helps. If not, make a simple version of your project with just the relevant fields, buttons and code. Just enough to produce the error and post the complete code here. It'll be easier for me to see the problem than with sections of code taken out of context. Paul
  4. Do you mean VB isn't converting this value? You get an exception? Or do you mean that FSUIPC isn't responding to this value? There shouldn't be any problem on the VB side of things. I've just run this code and it's fine: Dim t As Short t = Short.Parse("0950", System.Globalization.NumberStyles.AllowHexSpecifier) MessageBox.Show(t.ToString()) I think we're going to need more details of the actual problem you're having in order to help. If you're getting a VB exception you really need to paste the exception text here. The exception box has a link to copy the details to the clipboard. Use that and paste it here. Paul
  5. You seem to be using the old C# SDK. Sadly, it doesn't support reading strings from FSUIPC (or floats or doubles either). If you haven't written too much code then I suggest you stop using this c# sdk; it really is awful. That's why I developed my .NET Client DLL which you can download on page 1 of this thread. My DLL supports all data types and it's much easier to understand and use. If you have too much invested in the old C# SDK then let me know. I might be able to add string support to the old SDK. It's not my code though. Paul
  6. [This reply is a copy of the one I gave in my DLL thread after the original poster asked the same question there the next day. Posted here for anyone finding this while searching for the same problem] Your code is using the wrong data types. Each data type (e.g. Integer, Short, Double) stores a different amount of data. If you don't use the correct data type then you are getting the wrong values from FSUIPC. This happens because you end up getting the values of two offsets mixed together. The "FSUIPC programmer's guide" clearly says this offset is 2 bytes long. You've used an Integer which is 4 bytes long. You need to use Short which is 2 bytes, like this: Public GRADOS_HDG As Offset (Of Short) = New FSUIPC.Offset (Of Short)(&H7CC) Public GRADOS_HDG_ant As Short All this is explained very clearly in the documentation that comes with my DLL. You need to read the "UserGuide.htm" document in the "Docs" folder in the zip you downloaded. Look at the section called "Registering your interest in an Offset". It has a table that tells you what variable type you need to use for each offset size and type. Following the rules laid out in that table your entire code should read: Public GRADOS_HDG As Offset (Of Short) = New FSUIPC.Offset (Of Short)(&H7CC) Public GRADOS_HDG_ant As Short Public ALTITUD As Offset (Of Integer) = New FSUIPC.Offset (Of Integer)(&H7D4) Public ALTITUD_ant As Integer Public AP_VS As Offset (Of Short) = New FSUIPC.Offset (Of Short)(&H7F2) Public AP_VS_ant As Short FSUIPCConnection.Process() GRADOS_HDG_ant = ((GRADOS_HDG.Value * 360) / 65536) ALTITUD_ant = ((ALTITUD.Value * 3.28084) / 65536) AP_VS_ant = AP_VS.Value Paul
  7. Pete has already given you the answer yesterday. Why are you posting this again here? I'm going to post this reply to both threads. Your code is using the wrong data types. Each data type (e.g. Integer, Short, Double) stores a different amount of data. If you don't use the correct data type then you are getting the wrong values from FSUIPC. This happens because you end up getting the values of two offsets mixed together. The "FSUIPC programmer's guide" clearly says this offset is 2 bytes long. You've used an Integer which is 4 bytes long. You need to use Short which is 2 bytes, like this: Public GRADOS_HDG As Offset (Of Short) = New FSUIPC.Offset (Of Short)(&H7CC) Public GRADOS_HDG_ant As Short All this is explained very clearly in the documentation that comes with my DLL. You need to read the "UserGuide.htm" document in the "Docs" folder in the zip you downloaded. Look at the section called "Registering your interest in an Offset". It has a table that tells you what variable type you need to use for each offset size and type. Following the rules laid out in that table your entire code should read: Public GRADOS_HDG As Offset (Of Short) = New FSUIPC.Offset (Of Short)(&H7CC) Public GRADOS_HDG_ant As Short Public ALTITUD As Offset (Of Integer) = New FSUIPC.Offset (Of Integer)(&H7D4) Public ALTITUD_ant As Integer Public AP_VS As Offset (Of Short) = New FSUIPC.Offset (Of Short)(&H7F2) Public AP_VS_ant As Short FSUIPCConnection.Process() GRADOS_HDG_ant = ((GRADOS_HDG.Value * 360) / 65536) ALTITUD_ant = ((ALTITUD.Value * 3.28084) / 65536) AP_VS_ant = AP_VS.Value Paul
  8. When you use the fsuipc_get() method, the 'result' parameter must be the same type as the data stored in the FSUIPC offset. In this case the data is stored as a FLOAT64, so you need to pass a double variable (cowl_flaps) as the 'result' (not dwResult which I suspect is an int or long). So your code should be this: //Global variables double cowl_flaps = 0.0; (...) //cowl flaps result = fsuipc.FSUIPC_Read(0x37F0, 8, ref token, ref dwResult); result = fsuipc.FSUIPC_Process(ref dwResult); result = fsuipc.FSUIPC_Get(ref token, ref cowl_flaps); textBox4.Text = cowl_flaps.ToString(); Paul
  9. Sure, just add these 4 methods to the Fsuipc class in the fsuipc.cs file. They will add read and write support for FLOAT64 ('double' in C#) and FLOAT32 ('float' in C#). You can use these just as you do for int, long, short etc. _get method for double (FLOAT64): ///<summary>Retrieve data read from FSUIPC using token passed during read request</summary> ///<param name="token">The unique identifier token returned from the Read call</param> ///<param name="result">Contains the "error-code" if method's boolean comes back false</param> ///<return>true if successful, false otherwise. If false, dwResult contains the "error-code"</return> public bool FSUIPC_Get(ref int Token, ref double Result) { int dwSize = 8; byte[] getBuffer = new byte[dwSize]; if ((Token < 0) || (Token > IPC_BUFFER_SIZE - (4 + dwSize))) { //Token out of range return false; } IntPtr heapbuf = Marshal.AllocHGlobal(4); Marshal.Copy(IPC, Token, heapbuf, 4); int Size = Marshal.ReadInt32(heapbuf); Marshal.FreeHGlobal(heapbuf); if (dwSize > Size) { dwSize = Size; //Max size of return block is size of block written } int idx = Token + 4; //go past size block while (idx < Token + 4 + dwSize) { getBuffer[idx - Token - 4] = IPC[idx]; idx = idx + 1; } if (IPCdr[Token]) { Result = BitConverter.ToDouble(getBuffer, 0); IPCdr[Token] = false; return true; } else { // if (data ready flag not set, function returns false and value found return false; } } _get method for float (FLOAT32): ///<summary>Retrieve data read from FSUIPC using token passed during read request</summary> ///<param name="token">The unique identifier token returned from the Read call</param> ///<param name="result">Contains the "error-code" if method's boolean comes back false</param> ///<return>true if successful, false otherwise. If false, dwResult contains the "error-code"</return> public bool FSUIPC_Get(ref int Token, ref float Result) { int dwSize = 4; byte[] getBuffer = new byte[dwSize]; if ((Token < 0) || (Token > IPC_BUFFER_SIZE - (4 + dwSize))) { //Token out of range return false; } IntPtr heapbuf = Marshal.AllocHGlobal(4); Marshal.Copy(IPC, Token, heapbuf, 4); int Size = Marshal.ReadInt32(heapbuf); Marshal.FreeHGlobal(heapbuf); if (dwSize > Size) { dwSize = Size; //Max size of return block is size of block written } int idx = Token + 4; //go past size block while (idx < Token + 4 + dwSize) { getBuffer[idx - Token - 4] = IPC[idx]; idx = idx + 1; } if (IPCdr[Token]) { Result = BitConverter.ToSingle(getBuffer, 0); IPCdr[Token] = false; return true; } else { // if (data ready flag not set, function returns false and value found return false; } } _write method for double (FLOAT64) ///<summary>Submits a write request</summary> ///<param name="dwOffset">The memory offset where the referenced value is located</param> ///<param name="param">The value to be written</param> ///<param name="token">Contains the unique identifier token used to Get the value</param> ///<param name="dwResult">Contains the "error-code" if method's boolean comes back false</param> ///<return>true if successful, false otherwise. If false, dwResult contains the "error-code"</return> public bool FSUIPC_Write(int dwOffset, double param, ref int Token, ref int dwResult) { int dwSize = 8; byte[] writeBuffer = new byte[dwSize]; writeBuffer = BitConverter.GetBytes(param); if ((IPCAlloc + dwSize + 4) >= (IPC_BUFFER_SIZE - 1)) { //Reset ptr to startbuf IPCAlloc = 0; } // Assign Token as index into IPC Buffer FifO, and clear data ready flags Token = IPCAlloc; int i; for (i = IPCAlloc; i < (IPCAlloc + 4 + dwSize - 1); i++) { // 4=size of int datablock size hdr IPC[i] = 0; IPCdr[i] = false; } IPCAlloc = IPCAlloc + 4 + dwSize; //first four bytes data block size (Int) plus data IntPtr heapbuf = Marshal.AllocHGlobal(4); Marshal.WriteInt32(heapbuf, dwSize); // Translate size Int32 to unmanaged byte stream Marshal.Copy(heapbuf, IPC, Token, 4); // Write size header to IPC array Marshal.FreeHGlobal(heapbuf); for (i = 0; i < dwSize; i++) { IPC[Token + 4 + i] = writeBuffer[i]; //xfer byte array to IPC managed FifO buffer } return FSUIPC_Write_Req(dwOffset, dwSize, Token, ref dwResult); } _write method for float (FLOAT32) ///<summary>Submits a write request</summary> ///<param name="dwOffset">The memory offset where the referenced value is located</param> ///<param name="param">The value to be written</param> ///<param name="token">Contains the unique identifier token used to Get the value</param> ///<param name="dwResult">Contains the "error-code" if method's boolean comes back false</param> ///<return>true if successful, false otherwise. If false, dwResult contains the "error-code"</return> public bool FSUIPC_Write(int dwOffset, float param, ref int Token, ref int dwResult) { int dwSize = 4; byte[] writeBuffer = new byte[dwSize]; writeBuffer = BitConverter.GetBytes(param); if ((IPCAlloc + dwSize + 4) >= (IPC_BUFFER_SIZE - 1)) { //Reset ptr to startbuf IPCAlloc = 0; } // Assign Token as index into IPC Buffer FifO, and clear data ready flags Token = IPCAlloc; int i; for (i = IPCAlloc; i < (IPCAlloc + 4 + dwSize - 1); i++) { // 4=size of int datablock size hdr IPC[i] = 0; IPCdr[i] = false; } IPCAlloc = IPCAlloc + 4 + dwSize; //first four bytes data block size (Int) plus data IntPtr heapbuf = Marshal.AllocHGlobal(4); Marshal.WriteInt32(heapbuf, dwSize); // Translate size Int32 to unmanaged byte stream Marshal.Copy(heapbuf, IPC, Token, 4); // Write size header to IPC array Marshal.FreeHGlobal(heapbuf); for (i = 0; i < dwSize; i++) { IPC[Token + 4 + i] = writeBuffer[i]; //xfer byte array to IPC managed FifO buffer } return FSUIPC_Write_Req(dwOffset, dwSize, Token, ref dwResult); } Let me know if you need any help using them or they don't work as expected. Paul
  10. Not with my DLL. There are no events built into it. You just need to keep checking to offset and wait for it to change. Events are possible in the LUA scripting facility supplied with FSUIPC. See the LUA documentation provided with FSUIPC. If you need more information or help with LUA please start a new topic for Pete. Thanks, Paul
  11. Hi Joris, This error is thrown when the request to FSUIPC fails to get through. The most likely cause on Windows 7 is that your program (or VS2008) is running "As Administrator" but Flight Sim isn't. Or the other way around. Either run both "As Administrator" or neither. If that's not the problem or doesn't sort it out can you re-post this problem as a new topic. This thread is a bit long and we may need Pete's help for this. Thanks, Paul
  12. Hi, The altitude is stored in FSUIPC as an 8-byte integer, not a double so you need to declare the offset as a long: Offset agl = new Offset(0x0570); To convert this to a feet you need to divide by (65536.0 * 65536.0) and then multiply by 3.28084 for feet. So your PHP should probably look more like this: $altitude=round(substr(mysql_real_escape_string($_GET['altitude']),0,8)); $altitude = $altitude / (65536.0 * 65536.0) * 3.28084; See if that works... Paul
  13. Hi Matthias, You don't specify what format your MCP output is in. The fist thing you need to do is get it into a string if it's not already. My code below assumes it is the format "0000,0". That is, it always has 4 digits before the , and one digit after. For example if it's a float you're going to need to do this: float ADFFromMCP = 1234.5f; string ADFFromMCPString = ADFFromMCP.ToString("f1"); // pad the string with leading 0s if it's not long enough ADFFromMCPString = new string('0',6-ADFFromMCPString.Length); If you can get it into that string format somehow then you can proceed as follows: First you need to add this to the top of your file as we'll need to access this namespace: using System.Globalization; Next you need to build the values to go into the two offsets. These are BCD encoded so we're going to be building hex strings that represent the parts of the frequency. We'll use the .Substring() method of the String class to pull out the correct groups of digits. The first digit in the string is referenced as 0, not 1. string main = ADFFromMCPString.Substring(1, 3); // Extract 3 characters starting at position 2 ("234") string hi = ADFFromMCPString.Substring(0, 1); // Extract 1 character stating as position 1 ("1") string lo = ADFFromMCPString.Substring(5, 1); // Extract 1 character stating as position 6 ("5") string hilo = hi + "0" + lo; // ("105") Now it's just a matter of turning these hex strings into shorts (int16) to write into the offsets. Once again the .NET framework makes this easy. The Int16 class has a static method that translates strings to Int16s. Normally it expects the string to be in decimal format, but we can use an override to tell it to accept hex strings: ADFMain.Value = Int16.Parse(main, NumberStyles.AllowHexSpecifier); ADFExtended.Value = Int16.Parse(hilo, NumberStyles.AllowHexSpecifier); That's it. Let me know if you need anymore help, especially if you're stuck getting your value from the MCP into the required string format (0000,0). Paul
  14. You're almost there except you're viewing the data as decimal numbers. The data is actually encoded in BCD which is effectively the hexadecimal string representation of the value (not the decimal representation) so you need to convert them. The offset for COM1 etc is specified as 2 bytes in the programmer’s documentation so we declare it as a 16 bit integer: Either "Int16" or "short" in C#, or "Short" in VB: So for Com2 we'd declare: VB: Dim com2bcd As Offset(Of Short) = New FSUIPC.Offset(Of Short)(&H3118) C#: Offset com2bcd = new Offset(0x3118); After processing, the value of this offset will be a number with the frequency encoded in BCD format. Each group of 4 bits specifies a single digit in the frequency. To get this into a string representing the frequency we need to convert each group of 4 bits into a digit representing the value stored in those 4 bits. This is the same as converting the number into a string using Hexadecimal. Fortunately the .NET framework can do this for us. We use one of the overloads of the ToString method. We pass in "X" to request the number to be formatted in Hex: VB: Dim com2String As String = com2bcd.Value.ToString("X") C#: string com2String = com2bcd.Value.ToString("X"); What we now have is a four digit string where the first two are before the decimal point and the last two are after. For example if the frequency is 119.45 what we will have now is "1945". All we need to do now is put the missing 1 on the front and insert the decimal point thus: VB: com2String = "1" & com2String.Substring(0, 2) & "." & com2String.Substring(2, 2) C#: com2String = "1" + com2String.Substring(0, 2) + "." + com2String.Substring(2, 2); Regards, Paul
  15. Hi, SimConnect only works with FSX. If that's the only version of Flight Sim you want your application to work with then SimConnect is probably what you'd want to use. There are a few esoteric things that you can do with SimConnect that can't be done with FSUIPC like creating AI aircraft. You'll need to check the available functionality against what your application needs to do. If you want your program to work with older versions of Flight Sim as well (FS2000, FS2004 etc) then you must use FSUIPC. The version of FSUIPC that runs with FSX actually uses SimConnect to get most of the data. It just adds a compatibility layer over the top so that existing FSUIPC applications work with FSX. I can't say if the SimConnect API is any easier than FSUIPC as I've not used SimConnect. Paul
  16. Hi Andrew, Yes, these sound like application access keys which used to be used in older version of FSUIPC but they don't apply anymore. These add-ons should just work, you don't need a registered copy of FSUIPC. Paul
  17. Hi Russell, Yes you need to use currency as that's actually a 64bit integer in VB6. The code at the top of the following thread shows how to read the lon and lat in VB6. You just need to reverse the process to write them. http://forums.simflight.com/viewtopic.php?f=54&t=72968&start=0&st=0&sk=t&sd=a Paul
  18. Pete's away at for a week. The FSUIPC interface is free for freeware use. Your freeware app will work on an unregistered FSUIPC. As a software developer you only need a licence if your application is Payware. Users only need to register if they want to use the extra facilities that FSUIPC provides, like control calibration. I think older versions of FSUIPC used to use 'application keys' but that feature was removed. Paul
  19. It's just occurred to me that you're probably using the wrong offset. 0B4C looks to be the altitude of the ground not the altitude of your plane. You probably need 0570 instead: Dim altitude as Double Dim FakeAlt As Currency Dim dwResult As Long Call FSUIPC_Read(&H570 , 8, VarPtr(FakeAlt), dwResult) Call FSUIPC_Process(dwResult) altitude = FakeLat * 10000# altitude = altitude * 3.28084 / (65536# * 65536#) Paul
  20. Hi, Offset 0B4C is only 2 bytes long according to the documentation. So you need to use a variable type of Integer in VB6 and set the length of the FSUIPC_Read to 2 not 4. So your code would look like this: Dim dwResult As Long Dim fs_speed As Long Dim fs_gear As Long Dim fs_alt As Integer Dim alt_tmp As Double Dim speed_int As Long Dim booResult As Boolean 'read gear booResult = FSUIPC_Read(&HBE8, 4, VarPtr(fs_gear), dwResult) 'Read Speed booResult = FSUIPC_Read(&H2B8, 4, VarPtr(fs_speed), dwResult) 'Read Altitude booResult = FSUIPC_Read(&HB4C, 2, VarPtr(fs_alt), dwResult) booResult = FSUIPC_Process(dwResult) 'Action section Label5.Caption = fs_gear 'printer ut Gear statur Label4.Caption = fs_speed \ 128 alt_tmp = fs_alt * 3.2 'gir resultat i feet Label6.Caption = alt_tmp End Sub I can't test this because I don't have VB6 but I'm pretty sure that will work now. Paul
  21. It's just 'long' or Int64 in C#. double valagl = agl.Value * 3.28084 / (65536 * 65536); It's good practice to write constants in the variable type you want rather than let the compiler convert them. Here your 65536's are 'int's and your 3.28084 is a single (float). It would be better to write these as doubles and also to cast your agl.value. The compiler may not always do what you'd expect in these situations if you force it to convert these different types. So your code would look something like this... //Getting values from FSUIPC Offset agl = new Offset(0x0570); [...] //Transforming in feets double valagl = (double)agl.Value * 3.28084D / (65536D * 65536D); Paul
  22. Hi Mitch, The documentation for 030C says it's the same data as 02C8. The documentation for 02C8 says: So all you need to do is use the formula given like this: ' Declare the offset Dim tdRateOffset As Offset(Of Integer) = New FSUIPC.Offset(Of Integer)(&H30C) ' Convert to ft/min Dim touchDownRate As Double touchDownRate = tdRateOffset.Value * 60D * 3.28084D / 256D / 256 turns the raw data into metres/sec * 3.28084 turns it into feet/sec (3.28084 feet in a metre) * 60 turns it into feet/min (60 seconds in a minute) Paul
  23. You can run the TrafficLook program. You can download it from the 'Updates and Goodies' sticky here: http://forums.simflight.com/viewtopic.php?f=54&t=74352 It'll give you a raw list of the FSUIPC TCAS tables. Also, make sure you are using the latest version of FSUIPC4. The TCAS injection was broken in FSUIPC4 until late last year. Paul
  24. I've just tried from the website and the readme.txt states the 28th Release March 2008. The same with the 'beta' SDK link in the "updates and other goodies" sticky, so it looks to me like 28 is the latest. I think it's a typo on the website but we'll have to wait for Pete to get back to know for sure. Paul
  25. EDIT: Pete is also up late and beat me to it! Hi Mitch, These three offsets are only 1 byte long (as specified in the FSUIPC programmer's guide). You have declared them as type Integer which is 4 bytes long. My documentation supplied with the DLL (UserGuide.htm) tells you that for 1 byte offsets you need to use type 'Byte' in Visual Basic , e.g. Dim hour As Offset(Of Byte) = New FSUIPC.Offset(Of Byte)(&H238) ' Hour - For total hour caculation Let me know if you have more questions about this. Paul
×
×
  • 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.