Jump to content
The simFlight Network Forums

Paul Henty

Members
  • Posts

    1,724
  • Joined

  • Days Won

    77

Everything posted by Paul Henty

  1. There is an example application in the main download package that has real-time updates. If you haven't got this please download it from the following link. The zip also contains a user manual. http://forum.simflight.com/topic/74848-fsuipc-client-dll-for-net-version-24/ About your code: 1. You must declare all the offsets at the class (form) level. Not in methods. Every time you declare an offset you are making a new copy of it. Eventually your program will run out of FSUIPC memory space. 2. To get realtime updates you need to do the following: 2.1 Drag a timer onto your form. (For the examples we assume it's called 'timer1' 2.2 Set the timer running after you open the connection to FSUIPC. Stop the timer before you close the connection. 2.3 In the form designer, go to the timer and create an event method for the 'Tick' event. This 'tick' method will run at the specified Interval. In this method you need to process() the offsets and then update your text boxes. The whole thing should be something like this: public partial class Form1 : MetroForm public string AppTitle { get; set; } private Offset<int> airspeed = new Offset<int>(0x02BC); private Offset<int> GroundSpeed = new Offset<int>(0x02B4); private Offset<int> ZeroFuelWeight = new Offset<int>(0x3BFC); private Offset<int> verticalSpeed = new Offset<int>(0x02C8); private Offset<int> gearPositionNose = new Offset<int>(0x0BEC); private Offset<int> Flapscontrol = new Offset<int>(0x0BDC); private Offset<double> agl = new Offset<double>(0x0020); public Form1() { InitializeComponent(); } private void metroButton1_Click(object sender, EventArgs e) { try { // Attempt to open a connection to FSUIPC (running on any version of Flight Sim) FSUIPCConnection.Open(); // start the timer timer1.Interval = 250; // in milliseconds (i.e. 4 times per second.) Adjust for your needs. timer1.Start(); // Opened OK } catch (Exception ex) { // Badness occurred - show the error message MessageBox.Show(ex.Message, AppTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void metroButton2_Click(object sender, EventArgs e) { // stop the timer timer1.Stop(); FSUIPCConnection.Close(); } private void timer1_Tick(object sender, EventArgs e) { // get data from FSUIPC FSUIPCConnection.Process(); // show data in the text boxes // Airspeed double airpeedKnots = (double)airspeed.Value / 128d; this.textBox1.Text = airpeedKnots.ToString("f0"); // Ground speed double GroundSpeedKnots = (double)GroundSpeed.Value / 65536d; this.textBox5.Text = GroundSpeedKnots.ToString("f0"); // altitude string altitude = agl.Value.ToString(); // ZFW double ZeroFuelWeightlbs = (double)ZeroFuelWeight.Value / 256; this.textBox12.Text = ZeroFuelWeightlbs.ToString("f0"); // VS double verticalSpeed_FeetPerMinute = (double)verticalSpeed.Value * 60d * 3.28084d / 256d; this.textBox2.Text = verticalSpeed_FeetPerMinute.ToString(""); // Gear if (gearPositionNose.Value == 0) { this.textBox4.Text = "Gear Up"; } else if (gearPositionNose.Value == 16383) { this.textBox4.Text = "Gear Down"; } else { this.textBox4.Text = "Gear In Transit"; } } } Paul
  2. Yes you need an open connection. Paul
  3. You need to have FSX running on the same PC. Or, if you have a WideFS licence, you can run WideClient.exe instead. This will connect to the FSX computer and is a tiny program compared to FSX. You cannot get a payload station by name because Flight Sim allows duplicate names for payload stations. For example the stock Cessna C172 has two payload stations called 'Rear Passenger'. If you want to load (update) all the payload stations at once, use a 'select' statement. This example loads the station weights from text boxes on the form. I've only shown two stations to keep it short. Dim ps As PayloadServices = FSUIPCConnection.PayloadServices ps.RefreshData() For Each payloadStation As FsPayloadStation In ps.PayloadStations Select Case payloadStation.Name Case "Cabin 0A" payloadStation.WeightKgs = txtCabinA.Text Case "Crew1" payloadStation.WeightKgs = txtCrew1.Text End Select Dim weight As Double = payloadStation.WeightLbs Next payloadStation ps.WriteChanges() If you want to access payload stations individually then you use the index, not the name. This example updates the Crew1 station - the index of this station is 10: station_load.10 ="0, 28.5715924813225, 0.0, 0.0, Crew1" ps.RefreshData() ps.PayloadStations(10).WeightKgs = txtCrew1.Text ps.WriteChanges() Process() is on the FSUIPCConnection class. This will read or write the data in all the offsets you have declared in your application. It does nothing for PayloadServices. WriteChanges() is on the PayloadServices() class. This will write any changed to payload information you have made. It does not write any offsets you have declared. When you use PayloadServices you don't need to use Process(). Paul
  4. transponder.Length.ToString will not work. Ah yes. I did not see that there is another variable being declared call transponder: Dim transponder As String = DateTime.UtcNow.ToString("[HH:mm]") & Chr(32) & "Transponder set to " & txtTransponder.Text & vbCrLf This is bad because it's the same name as the offset called transponder. If you change the name of this new variable then it will work. I changed it to transponderMsg: Private Sub tmrtrans_Tick(sender As Object, e As EventArgs) Handles tmrtrans.Tick If transponder.Value <> lastTransponder Then Dim transponderMsg As String = DateTime.UtcNow.ToString("[HH:mm]") & Chr(32) & "Transponder set to " & txtTransponder.Text & vbCrLf My.Computer.FileSystem.WriteAllText(logname, transponderMsg, True) Dim xml As String = DateTime.UtcNow.ToString("[HH:mm]") & Chr(32) & "Transponder set to " & txtTransponder.Text & "*" My.Computer.FileSystem.WriteAllText(reportname, xml, True) lastTransponder = transponder.Value End If tmrtrans.Stop() End Sub This should do the same thing without timers. I renamed the timer tick event and removed the timers start/stop calls. Private Sub logTransponder() If transponder.Value <> lastTransponder Then Dim transponderMSg As String = DateTime.UtcNow.ToString("[HH:mm]") & Chr(32) & "Transponder set to " & txtTransponder.Text & vbCrLf My.Computer.FileSystem.WriteAllText(logname, transponderMSg, True) Dim xml As String = DateTime.UtcNow.ToString("[HH:mm]") & Chr(32) & "Transponder set to " & txtTransponder.Text & "*" My.Computer.FileSystem.WriteAllText(reportname, xml, True) lastTransponder = transponder.Value End If End Sub Private Sub txtTransponder_TextChanged(sender As Object, e As EventArgs) Handles txtTransponder.TextChanged If txtTransponder.Text.Length = 1 Then txtTransponder.Text = "000" & txtTransponder.Text End If If txtTransponder.Text.Length = 2 Then txtTransponder.Text = "00" & txtTransponder.Text End If If txtTransponder.Text.Length = 3 Then txtTransponder.Text = "0" & txtTransponder.Text End If logTransponder() End Sub
  5. I think FSUIPC4 should work with any version or P3D up to 2.5. I'm running 4.939t here without any problems. You don't say if you're using 2.4 of my DLL or one of the many 3.0 Beta builds that are posted in various threads. You could try using the latest 3.0 build. I've attached it here. If that doesn't work then it sounds like you have something wrong with the FSUIPC installation and it's returning 0 for all offsets (therefore failing the version test because it's reporting version 0). Can you try using another FSUIPC application to see if that works, for example FSInterrogator (available in the FSUIPC SDK), If that works then it's something to do with my dll. If it doesn't work either then something is wrong with your FSUIPC installation or registration. Paul FSUIPCClient3.0_BETA.zip
  6. The timers don't make any sense to me. They seem to be started, run one tick and then stop again. I don't know if you want to sort that out. It could lead to more problems. Yes they all have the same problem. They all compare the value with the text. It's the same solution: store the last value and compare against that. Paul
  7. Hi Fred, This line in tmrtrans_tick() is wrong: If transponder.Value = txtTransponder.Text Then It's trying to catch the same value so the log line does not appear. But, it's testing the integer value against the converted hex string. They will never be the same. The easiest way to fix this with the code you have is: 1. Create a form level private variable to hold the last value written: (Make it the same type as the offset (i.e. Integer)) Private lastTransponder as Integer 2. Change the tmrtrans_tick() to test against this value. When you write a new value, update the 'lastTransponder' variable: (I also rewrote the 'If = then else' as 'if <> then') Private Sub tmrtrans_Tick(sender As Object, e As EventArgs) Handles tmrtrans.Tick If transponder.Value <> lastTransponder Then Dim transponder As String = DateTime.UtcNow.ToString("[HH:mm]") & Chr(32) & "Transponder set to " & txtTransponder.Text & vbCrLf My.Computer.FileSystem.WriteAllText(logname, transponder, True) Dim xml As String = DateTime.UtcNow.ToString("[HH:mm]") & Chr(32) & "Transponder set to " & txtTransponder.Text & "*" My.Computer.FileSystem.WriteAllText(reportname, xml, True) lastTransponder = transponder.Value End If tmrtrans.Stop() End Sub Try that. Paul
  8. I forgot to say that you probably don't need to do the 'luakill' control on the button release. The script will automatically die when it's finished executing (i.e. it gets to the bottom).
  9. The parameter set in the FSUIPC dialog comes through in lua as a variable called ipcPARAM. You just set up some if statements to test the value... You can use any numbering scheme you want. Maybe you'll want to match the parameter number with the number in your filenames. I've just used 1 to 3 here. sound.path("C:\\") if ipcPARAM == 1 then sound.play("5-0firebell.wav") elseif ipcPARAM == 2 then sound.play("5-4safety_brief") elseif ipcPARAM == 3 then sound.play("5-5another_file") end Just stack as many elseif blocks as you need. Paul
  10. No, it gets sent immediately. The process() is done by the dll internally. Paul
  11. There are no Lua errors reported in the log and your screenshot of the GUI also looks okay. I can only offer two suggestions now... 1. You have a few sound devices listed. You could try specifying the number of the device you are using as the second parameter. Without this you are leaving up to windows to decide on the 'primary' device. For example if you are using the 5.1 speaker output then use: sound.play("firebell.wav", 4) 2. Try using one of the sounds that comes with flight sim in case your firebell.wav is in an unsupported bit-depth or sample rate. I used sound.play("INNERMK.WAV") but I have FSX, so check this is in FS9 or chose another one. Pete is back on Thursday if you have no luck with these. Paul
  12. Have a look in the FSUIPC.log file (in the modules folder). It might have a error message that will explain why it's not working. Paste the contents here if you want me to take a look. Paul
  13. Two problems I can see: 1. sound should start with a lower case s sound.play() 2. The parameter should be the name of the sound file, not a path. The default path according to the documentation is the 'sound' folder under the main FS folder. If you want to play sounds from a different folder, you can call sound.path() with the new folder. Try this: sound.path("D:\\")sound.play("firebell.wav") Paul
  14. Yes, this works if the plane is using the built-in FS autopilot. This may not work on Third-party payware where they have coded their own autopilot. You can also send the Autopilot off control as follows (Must be using Version 3.0 of my DLL. It's attached to a previous reply in this thread.) FSUIPCConnection.SendControlToFS(FsControl.AUTOPILOT_OFF, 0) Yes it's 0x2F80. Again, this will not work where aircraft developers have coded their own autobrake system. Paul
  15. Hi Fred, Offset 0x0330 is only 2 bytes. You've declared the offset as 'Integer' which is a 4 bytes in VB. The type tells the DLL how many bytes to read. A 2-Byte integer is a Short. This value is also unsigned so it's best to use UShort like this: Public qnh As Offset(Of UShort) = New FSUIPC.Offset(Of UShort)(&H330) My userguide.pdf explains which VB types to use. See the table on page 7. Regards, Paul
  16. Hi Philipp, I don't have P3D so I can't test anything here. To receive key presses, FSX or P3D must have focus. When you send keys with FSUIPCConnection.SendKeyToFS, the DLL brings the sim into focus using an FSUIPC control called 'Key focus restore'. It may be that this doesn't work for P3D. Can you just try this out for me and report back? All you need to do is run this line of code from a button or similar: FSUIPCConnection.SendControlToFS(FSUIPCControl.Key_focus_restore, 0) If it's working then your application will lose focus and FSX/P3D will get the focus. Depending on the results I'll see if there's anything that can be done. Regards, Paul
  17. 1. The number of passengers on board is not recorded in FS. Each plane, depending on how it's written, has a different number of payload stations. For example, the default 737 has playload stations representing rows of seats: e.g. First Class, Coach 3-10. All you can do is read and write the total weight for all these passengers. Some complex payware aircraft have a payload station per seat. 1a. The Max Takeoff Weight is not available in FS. You can get the Max Gross Weight which is usually close. I've added this to the PayloadServices (new DLL attached). Either use the Max Gross Weight or you can just hold the real-world information in a table in your application. Dim ps As PayloadServices = FSUIPCConnection.PayloadServices ps.RefreshData() MsgBox(ps.MaxGrossWeightKgs.ToString("F0") & "Kg") 2. You can get back a weather structure from the weather services. You can then construct your string from the various properties. There is full Intellisense documentation to help with this. For example, making a temperature string: Dim ws As WeatherServices = FSUIPCConnection.WeatherServices Dim weather As FsWeather = ws.GetWeatherAtAircraft() Dim message As String = "Temperature " & weather.TemperatureLayers(0).DayCelsius & "°C" MsgBox(message) 3. The QNH can be set at offset 0x0330. The altitude above ground can be calculated by subtracting the height of the terrain (0x0020) from the altitude above sea level (0x6020). 4. Dual autopilots are not supported in FS. The main autopilot switch is at 0x07BC. Some payware aircraft may have dual autopilots, but you'll need to find out if/how you can access this information. Each aircraft will be different. 5. See offsets 0x0C48 and 0x0C49 to get the position of the ILS/Glideslope indicators. 6. Offset 0x0D06, bit 6. See this thread on how to use a bitarray to make it easier. http://forum.simflight.com/topic/79536-little-understanding-problem-reading-from-project-magenta-offset/ 7. Offset 0x31F4 controls the pushback. I cannot see anywhere in your application that this is declared or used. Looks like to need to add this. Paul FSUIPCClient3.0_BETA.zip
  18. I don't think so. Lua is the only way I know of accessing L:VARs. If Aerosoft have an SDK you might be able to access that directly from your program. However, this may be difficult with VB as most SDKs are intended for C. Paul
  19. No. Users of FSUIPC can change the text to white using the tick box for 'non-scrolling FS msgs to be in white' on the 'miscellaneous' tab. But I don't believe the colour cannot be set via code. Paul
  20. Problem 1 - Message not disappearing after 5 seconds This code is in a sub called 'mess()' which is called from drivestarttmr(). drivestarttmr() runs every 0.5 seconds, called from TmrGetDataFromFs_Tick(). So the problem is the message is being displayed every 0.5 seconds. Every time it is called the message timer gets reset. It will never reach 5 seconds. Solution: Move the mess() call from drivestarttmr() to a more suitable place so it's only called once after the connection is made. Problem 2 - Losing Connection This is because you are declaring offsets in the main sub: Dim msgcontrol As Offset(Of Short) = New FSUIPC.Offset(Of Short)("msg", &H32FA) '<---- Very bad Dim msg As Offset(Of String) = New FSUIPC.Offset(Of String)("msg", &H3380, 128) '<---- Very bad msg.Value = "SKYDreamTracker is Connected to SIM !!! Have a nice flight;)" msgcontrol.Value = 5 FSUIPCConnection.Process("msg") Each time this code runs (2 times a second) you create two new offsets in the 'msg' group. Eventually there are too many for FSUIPC to handle. Solution: You must move these two lines to the top of the class (FSUIPCData.vb) with all the other offset declarations. Paul
  21. The easiest way is to set the type as a BitArray: (You also need to add the offset length as the second parameter.) Public LED As Offset(Of BitArray) = New FSUIPC.Offset(Of BitArray)(&H4F0, 2) To read the state of a particular light just use an array index with the bit number you need. For example this is how you know if the LNAV light is on or off: FSUIPCConnection.Process() Dim lnav As Boolean = LED.Value(6) Paul
  22. This is probably because the arrival airport is too far away. The weather is not loaded until the player (aircraft) is close to the airport. I've tried my test form with the sim paused and there was no problem. It must be some other part of your application. It would also help with your first problem. If you have access to the metar this might be a better way of doing it. Here is a function to get the wind direction from a metar string.... Private Function getWindDirectionFromMETAR(metar As String) As Double Dim heading As Double = 0 Dim endPos As Integer = metar.IndexOf("KT") If endPos >= 0 Then Dim startPos As Double = metar.LastIndexOf(" ", endPos) If startPos >= 0 Then heading = metar.Substring(startPos + 1, 3) End If End If Return heading End Function Here a modified version of the getRunways function that takes in the wind direction and the ICAO... Public Function getActiveRunway(ByVal ICAOcode As String, ByVal WindDirection As Double) As String Dim runwayReturn As String = "" ' Now get the runways at the airport ' For each one we test how far they are from the wind direction ' We keep the closest one. Dim pathto As String = My.Application.Info.DirectoryPath Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser(pathto & "\runways.csv") MyReader.TextFieldType = FileIO.FieldType.Delimited MyReader.SetDelimiters(",") Dim runwayst As String Dim runwaynum As String Dim runwaydes1 As String Dim runwaydes2 As String = "" Dim currentRow As String() Dim smallestDifference As Double = 360 While Not MyReader.EndOfData Try currentRow = MyReader.ReadFields() If currentRow(0) = ICAOcode Then runwayst = currentRow(1) runwaynum = runwayst.Substring(1, 2) runwaydes1 = runwayst.Substring(3, 1) If runwaydes1 = "0" Then runwaydes2 = "" If runwaydes1 = "1" Then runwaydes2 = "L" If runwaydes1 = "2" Then runwaydes2 = "R" If runwaydes1 = "3" Then runwaydes2 = "C" If runwaydes1 = "4" Then runwaydes2 = "W" Dim rwyMagHeading As Double = CDbl(currentRow(5)) Dim rwyMagVariation As Double = 0 ' I think winds are magnetic. If not we must use true heading instead (second line) Dim rwyHeading As Double = rwyMagHeading ' Dim rwyHeading As Double = rwyMagHeading + rwyMagVariation ' Calculate the difference between the wind heading and the runway heading ' You might need to expand this to ignore short runways Dim difference As Double = 180D - Math.Abs(Math.Abs(WindDirection - rwyHeading) - 180D) If difference < smallestDifference Then smallestDifference = difference runwayReturn = runwaynum & runwaydes2 End If End If Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException 'MsgBox("Line " & ex.Message & "is not valid and will be skipped.") End Try End While MyReader.Close() MyReader.Dispose() End Using Return runwayReturn End Function Yes but arrival may not work as explained above. 5) Howto check FSUIPC.dll version in "SIMroot\modules" and paste the result to the label and make an action if sim_fsuipc < actual_version I've added a new property to the DLL to get the FSUIPC Version number (new DLL attached). You need to be connected to FSUIPC first: FSUIPCConnection.FSUIPCVersion I don't know how you would get the version directly from the fsuipc.dll file on the disk. This is something you'll have to sort out yourself. It is confusing source code and would take me too long to reorganise everything. Regards, Paul FSUIPCClient3.0_BETA.zip
  23. Okay, sorry I did misunderstand. So, my function using the wind direction does not give the same results as the function using AI? Is that what you mean? Paul
  24. I've written the entire function for you. You just need to paste it in to your code, call it, and use the output however you want. Presumably adding it to the list box. I can help you use the DLL and give you example code, but I cannot do all your work for you or teach VB programming here. You will only get one runway at each airport. If you want different take-off and landing runways where there are Left and Right runways, you'll need to adjust the code for whatever logic you want. I added a comment that you might also need to add code to exclude runways under a certain length. Paul
  25. I've modified one of the functions in your code that reads the runways.csv file. This new function will get the wind direction from the weather service and then find the runway closest to that heading. You should be able to paste it under the others. Public Function getActiveRunway(ByVal ICAOcode As String) As String Dim runwayReturn As String = "" ' Get the weather for the airport - might take some time so we set the timout to 30 seconds Dim ws As WeatherServices = FSUIPCConnection.WeatherServices ws.LocationReadTimeout = 30000 Dim weather As FsWeather = ws.GetWeatherAtLocation(ICAOcode) ' now get wind direction Dim windDirection As Double = 0 If weather.WindLayers.Count > 0 Then windDirection = weather.WindLayers(0).Direction End If ' Now get the runways at the airport ' For each one we test how far they are from the wind direction ' We keep the closest one. Dim pathto As String = My.Application.Info.DirectoryPath Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser(pathto & "\runways.csv") MyReader.TextFieldType = FileIO.FieldType.Delimited MyReader.SetDelimiters(",") Dim runwayst As String Dim runwaynum As String Dim runwaydes1 As String Dim runwaydes2 As String = "" Dim currentRow As String() Dim smallestDifference As Double = 360 While Not MyReader.EndOfData Try currentRow = MyReader.ReadFields() If currentRow(0) = ICAOcode Then runwayst = currentRow(1) runwaynum = runwayst.Substring(1, 2) runwaydes1 = runwayst.Substring(3, 1) If runwaydes1 = "0" Then runwaydes2 = "" If runwaydes1 = "1" Then runwaydes2 = "L" If runwaydes1 = "2" Then runwaydes2 = "R" If runwaydes1 = "3" Then runwaydes2 = "C" If runwaydes1 = "4" Then runwaydes2 = "W" Dim rwyMagHeading As Double = CDbl(currentRow(5)) Dim rwyMagVariation As Double = 0 ' I think winds are magnetic. If not we must use true heading instead (second line) Dim rwyHeading As Double = rwyMagHeading ' Dim rwyHeading As Double = rwyMagHeading + rwyMagVariation ' Calculate the difference between the wind heading and the runway heading ' You might need to expand this to ignore short runways Dim difference As Double = 180D - Math.Abs(Math.Abs(windDirection - rwyHeading) - 180D) If difference < smallestDifference Then smallestDifference = difference runwayReturn = runwaynum & runwaydes2 End If End If Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException 'MsgBox("Line " & ex.Message & "is not valid and will be skipped.") End Try End While MyReader.Close() MyReader.Dispose() End Using Return runwayReturn End Function 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.