dallas Posted November 19, 2007 Report Posted November 19, 2007 Is anyone able to correctly read 8 byte double (FLOAT64) values from FSUIPC [v. 3.75] using C sharp? Dallas
Paul Henty Posted November 20, 2007 Report Posted November 20, 2007 It depends how you are talking to FSUIPC. I suspect you are using the C# SDK from the official FSUIPC SDK download. That doesn't support Float64s which is one of the reasons I wrote my FSUIPC Client DLL for .NET programmers. You can read about it and download it in the sticky posting above: http://forums.simflight.com/viewtopic.php?f=54&t=53255 If you're too far down the road of development to switch all your code then let me know and I'll see if I can provide you with a workaround for the original SDK or add float64 support to it. I'll need to spend a bit of time on though so I'd prefer it if you use my DLL if at all possible. Paul
airlombadb Posted October 14, 2010 Report Posted October 14, 2010 Wooooooow!!!! Man I am disapointed!!! :( I have been working on a piece of software for some time. A lot has been developed and let to the end the reading of float64 values. Now that I am working on solving this last milestone, I find this topic, I find that I can't handle these values. Man, you can't imagine the words that came out of my mouth. Pfffffff... What can I do now? Start all over again and use phenty's DLL. That's an idea but I am really not into that, unless as a last resource. Phenty, can you help me? Privode some code or pseudo-code so I can resume my work? Thank you anyway. Best regards to all, LOMBA, Emmanuel.
Paul Henty Posted October 14, 2010 Report Posted October 14, 2010 Phenty, can you help me? Privode some code or pseudo-code so I can resume my work? Thank you anyway. 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
airlombadb Posted October 14, 2010 Report Posted October 14, 2010 Hello Paul, many many thanks for your help. I copied the four methods you provided in your last post, recompiled the code, but unfortunately nothing changed. So far, for testing purposes, I am trying to read the cowl flaps lever position value as follows (please take a look): //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 dwResult); cowl_flaps = dwResult; textBox4.Text = cowl_flaps.ToString(); This value should be between 0.0 and 1.0 (fully open and fully closed, respectively). However I always get a signed integer. For example, when in FSInterrogate I get 0,78, in my textbox I get -1889785610. What am I missing or doing wrong? Thank you very much for your help!!! Best regards, LOMBA, Emmanuel.
Paul Henty Posted October 14, 2010 Report Posted October 14, 2010 What am I missing or doing wrong? Thank you very much for your help!!! 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
airlombadb Posted October 14, 2010 Report Posted October 14, 2010 I can't thank you enough Paul. You solved my problem and a lot of time with it. And in the mentime I learnt something more about programming in C#. Thank you very much! Best regards, Emmanuel.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now