本帖最后由 prius0304 于 2013-9-30 22:25 编辑
菜鸟谈谈FSX外设程序(一)
由于特别想做一些外设,于是就误打误撞的开始DIY。
高三真的相当的苦逼,两周放一天假,今天终于放假了,能好好调调FSX读取数据的问题了。
以前一直在看FSUIPC导出FSX数据的方法,但苦于国内网络的问题,用爪机上国外的论坛实在是苦不堪言。好不容易看了几天的FSUIPC手册,大概了解了流程,于是找到了Peter(FSUIPC的开发者。其实我也叫Peter蛤蛤!)下载了一份Sample,又在临睡前扫了一遍,无奈写的实在是太乱,我无从下手修改或者重写。又找到一个台湾朋友,写的C读取NAV数据,直接串口给Arduino,觉得不错,想改,但效果并不理想,于是开始从新搜索。
外国的月亮总比中国的圆?Google搜了一下,就找到了Jim的程序,打开看了一下,豁然开朗。
由于本人是NOIP退役狗,所以面向对象基本还停留在凑活抄抄看看能写水平,所以暂且都用VB.NET做测试。
测试了一下,完全没有问题,但这个代码就写的简单多了,很容易理解。后来看了一下SimConnect,其实它的功能一点也不少,简单的外设靠它完全足以使用,譬如做一个MCP,做一个头瞄,都是完全没有问题的。由于原来的UI很丑(大概程序猿们都不怎么会写界面),再加上没有办法手动输入我们的NAV和应答机的值,我就稍稍的修改了一下代码。下面是测试。
这样子我们的读取程序就有了最直接的接口给我们的上位机做串口通信,如果是MCP的话只需要从Arduino发送出字串我们读取一下就可以直接修改textbox的值做到同步了。
当然,我现在没时间做MCP,做MCP东西比较多,高三狗晚上十点多才到家,不可能有时间做这个,所以想试试看做头瞄,开始研究MPU6050陀螺仪,这个比较小,比较好藏蛤蛤。
说实话,因为6050出来时间不长,网上根本找不到比较直接的资料,很头大,但最终还是找到了上面这个用Processing做互动的测试程序,好歹也是能够抄袭一下算法,把姿态给算出来。这几天抽空的话尽量用VB实现姿态的读取,然后给上位机做传输,当然数据的读写也是写完的了。
其他的只要把三样整合到一起,头瞄就能做完了。这样算下来,一个头瞄才九十块钱左右,一个MCP的价格么(还是不说的好,毕竟可爱的SINO出售MCP的,但亚克力的面板真的很便宜蛤蛤)……
说了半天,贴源码,这种东西我也不想藏着掖着,好歹我也是开源支持者。。。
读取FSX数据(VB.NET):
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
Imports Microsoft.FlightSimulator.SimConnect
Imports System.Runtime.InteropServices
Imports System.Net.Sockets
Imports System.Net
'Date 24-11-11 all going fine
Partial Public Class Form1
Inherits Form
Dim fsx_simconnect As SimConnect
Const WM_USER_SIMCONNECT As Integer = &H402
Public Enum hSimconnect
group1
End Enum
Private Enum EVENT_ID
EVENT_FLAPSup
EVENT_FLAPSdn
EVENT_COM1co
EVENT_COM1SBset
EVENT_XPONDer
EVENT_NAV1OBS
EVENT_APon
EVENT_APoff
EVENT_LIGHTSset
End Enum
Private Enum DEFINITIONS
Struct1
End Enum
Private Enum DATA_REQUESTS
REQUEST_1
End Enum
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=1)> _
Structure Struct1
Public flapsx As Single
Public altitudex As Single
Public IASx As Single
Public com1x As Single
Public com1sbx As Single
Public xponderx As Single
Public nav1obsx As Single
Public aponoffx As Single
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> Public Titlex As String
End Structure
Public Sub New()
InitializeComponent()
End Sub
Protected Overrides Sub DefWndProc(ByRef m As Message)
If m.Msg = WM_USER_SIMCONNECT Then
If fsx_simconnect IsNot Nothing Then
fsx_simconnect.ReceiveMessage()
End If
Else
MyBase.DefWndProc(m)
End If
End Sub
Dim hr As Long
Dim flaps As String
Dim altitude As String
Dim ias As String
Dim com1 As String
Dim com1sb As String
Dim xponder As String
Dim nav1obs As String
Dim freq As String
Dim aponoff As String
Dim titleout As String
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If fsx_simconnect Is Nothing Then
Try
fsx_simconnect = New SimConnect("jims8buttons", Me.Handle, WM_USER_SIMCONNECT, Nothing, 0)
AddHandler fsx_simconnect.OnRecvOpen, New SimConnect.RecvOpenEventHandler(AddressOf simconnect_OnRecvOpen)
AddHandler fsx_simconnect.OnRecvQuit, New SimConnect.RecvQuitEventHandler(AddressOf simconnect_OnRecvQuit)
fsx_simconnect.MapClientEventToSimEvent(EVENT_ID.EVENT_FLAPSup, "FLAPS_UP")
fsx_simconnect.MapClientEventToSimEvent(EVENT_ID.EVENT_APon, "AUTOPILOT_ON")
fsx_simconnect.MapClientEventToSimEvent(EVENT_ID.EVENT_APoff, "AUTOPILOT_OFF")
fsx_simconnect.MapClientEventToSimEvent(EVENT_ID.EVENT_LIGHTSset, "ALL_LIGHTS_TOGGLE")
fsx_simconnect.MapClientEventToSimEvent(EVENT_ID.EVENT_FLAPSdn, "FLAPS_DOWN")
fsx_simconnect.MapClientEventToSimEvent(EVENT_ID.EVENT_COM1co, "COM_STBY_RADIO_SWAP")
fsx_simconnect.MapClientEventToSimEvent(EVENT_ID.EVENT_COM1SBset, "COM_STBY_RADIO_SET")
fsx_simconnect.MapClientEventToSimEvent(EVENT_ID.EVENT_XPONDer, "XPNDR_SET")
fsx_simconnect.MapClientEventToSimEvent(EVENT_ID.EVENT_NAV1OBS, "VOR1_SET")
fsx_simconnect.AddToDataDefinition(DEFINITIONS.Struct1, "TRAILING EDGE FLAPS LEFT PERCENT", "degrees", SIMCONNECT_DATATYPE.FLOAT32, 0, 0)
fsx_simconnect.AddToDataDefinition(DEFINITIONS.Struct1, "Indicated Altitude", "feet", SIMCONNECT_DATATYPE.FLOAT32, 0, 1)
fsx_simconnect.AddToDataDefinition(DEFINITIONS.Struct1, "Airspeed Indicated", "knots", SIMCONNECT_DATATYPE.FLOAT32, 0, 2)
fsx_simconnect.AddToDataDefinition(DEFINITIONS.Struct1, "COM ACTIVE FREQUENCY:1", "MHz", SIMCONNECT_DATATYPE.FLOAT32, 0, 3)
fsx_simconnect.AddToDataDefinition(DEFINITIONS.Struct1, "COM STANDBY FREQUENCY:1", "MHz", SIMCONNECT_DATATYPE.FLOAT32, 0, 4)
fsx_simconnect.AddToDataDefinition(DEFINITIONS.Struct1, "TRANSPONDER CODE:1", "Enum", SIMCONNECT_DATATYPE.FLOAT32, 0, 5)
fsx_simconnect.AddToDataDefinition(DEFINITIONS.Struct1, "NAV OBS:1", "degrees", SIMCONNECT_DATATYPE.FLOAT32, 0, 6)
fsx_simconnect.AddToDataDefinition(DEFINITIONS.Struct1, "AUTOPILOT MASTER", "Bool", SIMCONNECT_DATATYPE.FLOAT32, 0, 7)
fsx_simconnect.AddToDataDefinition(DEFINITIONS.Struct1, "Title", "", SIMCONNECT_DATATYPE.STRING256, 0, 8)
fsx_simconnect.RegisterDataDefineStruct(Of Struct1)(DEFINITIONS.Struct1)
AddHandler fsx_simconnect.OnRecvSimobjectData, New SimConnect.RecvSimobjectDataEventHandler(AddressOf simconnect_OnRecvSimobjectData)
fsx_simconnect.RequestDataOnSimObject(DATA_REQUESTS.REQUEST_1, DEFINITIONS.Struct1, SimConnect.SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD.VISUAL_FRAME, 0, 0, 0, 0)
Button1.Text = "Disconnect"
Catch ex As COMException
TextBox1.Text = "Unable to Connect"
End Try
Else
Button1.Text = "Connect"
TextBox1.Text = "Disconnected"
TextBox2.Text = ""
TextBox3.Text = ""
TextBox4.Text = ""
TextBox5.Text = ""
TextBox6.Text = ""
TextBox7.Text = ""
TextBox8.Text = ""
TextBox9.Text = ""
fsx_simconnect.Dispose()
fsx_simconnect = Nothing
End If
End Sub
Private Sub simconnect_OnRecvSimobjectData(ByVal sender As SimConnect, ByVal data As SIMCONNECT_RECV_SIMOBJECT_DATA)
Select Case CType(data.dwRequestID, DATA_REQUESTS)
Case DATA_REQUESTS.REQUEST_1
Dim s1 As Struct1 = CType(data.dwData(0), Struct1)
flaps = [String].Format("{0:000}", s1.flapsx)
altitude = [String].Format("{0:00000}", s1.altitudex)
ias = [String].Format("{0:000}", s1.IASx)
com1 = [String].Format("{0:00.000}", s1.com1x)
com1sb = [String].Format("{0:00.000}", s1.com1sbx)
xponder = [String].Format("{0:0000}", s1.xponderx)
nav1obs = [String].Format("{0:000}", s1.nav1obsx)
aponoff = [String].Format("{0:0}", s1.aponoffx)
titleout = s1.Titlex
TextBox2.Text = flaps
TextBox3.Text = altitude
TextBox4.Text = ias
TextBox5.Text = com1
TextBox6.Text = com1sb
TextBox7.Text = xponder
TextBox8.Text = nav1obs
TextBox9.Text = titleout
If aponoff = 1 Then Button3.Text = "Autopilot ON" Else Button3.Text = "Autopilot OFF"
Exit Select
Case Else
TextBox1.Text = "Unknown request ID: " & Convert.ToString(data.dwRequestID)
Exit Select
End Select
End Sub
Private Sub simconnect_OnRecvException(ByVal sender As SimConnect, ByVal data As SIMCONNECT_RECV_EXCEPTION)
TextBox1.Text = "Exception received:"
End Sub
Private Sub simconnect_OnRecvQuit(ByVal sender As SimConnect, ByVal data As SIMCONNECT_RECV)
TextBox1.Text = "Disconnected from FSX"
button1.Text = "Connect"
fsx_simconnect.Dispose()
fsx_simconnect = Nothing
End Sub
Private Sub simconnect_OnRecvOpen(ByVal sender As SimConnect, ByVal data As SIMCONNECT_RECV_OPEN)
TextBox1.Text = "Connected to FSX"
button1.Text = "Disconnect"
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
On Error Resume Next
If flaps > 20 Then fsx_simconnect.TransmitClientEvent(DEFINITIONS.Struct1, EVENT_ID.EVENT_FLAPSup, 0, hSimconnect.group1, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY)
If flaps < 20 Then fsx_simconnect.TransmitClientEvent(DEFINITIONS.Struct1, EVENT_ID.EVENT_FLAPSdn, 0, hSimconnect.group1, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY)
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
On Error Resume Next
If aponoff = 0 Then fsx_simconnect.TransmitClientEvent(DEFINITIONS.Struct1, EVENT_ID.EVENT_APon, 0, hSimconnect.group1, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY)
If aponoff = 1 Then fsx_simconnect.TransmitClientEvent(DEFINITIONS.Struct1, EVENT_ID.EVENT_APoff, 0, hSimconnect.group1, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY)
End Sub
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
On Error Resume Next
fsx_simconnect.TransmitClientEvent(DEFINITIONS.Struct1, EVENT_ID.EVENT_LIGHTSset, 0, hSimconnect.group1, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY)
End Sub
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
On Error Resume Next
fsx_simconnect.TransmitClientEvent(DEFINITIONS.Struct1, EVENT_ID.EVENT_COM1co, 0, hSimconnect.group1, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY)
End Sub
Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
On Error Resume Next
Dim tempCom As String
tempCom = TextBox10.Text
tempCom = Replace(tempCom, ".", "")
fsx_simconnect.TransmitClientEvent(DEFINITIONS.Struct1, EVENT_ID.EVENT_COM1SBset, "&H" & tempCom, hSimconnect.group1, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY)
End Sub
Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click
On Error Resume Next
Dim tempTransMitClientEvent As String
tempTransMitClientEvent = TextBox11.Text
fsx_simconnect.TransmitClientEvent(DEFINITIONS.Struct1, EVENT_ID.EVENT_XPONDer, "&H" & tempTransMitClientEvent, hSimconnect.group1, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY)
End Sub
Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click
On Error Resume Next
Dim tempTransMit As String
tempTransMit = TextBox12.Text
fsx_simconnect.TransmitClientEvent(DEFINITIONS.Struct1, EVENT_ID.EVENT_NAV1OBS, tempTransMit, hSimconnect.group1, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY)
End Sub
Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
If fsx_simconnect IsNot Nothing Then
fsx_simconnect.Dispose()
fsx_simconnect = Nothing
MsgBox("SimConnect has been closed.")
End If
End Sub
Private Sub TextBox10_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles TextBox10.MouseClick
TextBox10.Text = ""
End Sub
Private Sub TextBox11_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles TextBox11.MouseClick
TextBox11.Text = ""
End Sub
Private Sub TextBox12_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles TextBox12.MouseClick
TextBox12.Text = ""
End Sub
End Class
UI看视频了,我就不发了。
如果要6050读取姿态的程序,大家可以去网上搜一下弘毅的Processing姿态读取,按照这个理念改一下很好做的,还有问题可以找我,QQ(常年不在,高三狗):631136257
这是菜鸟谈谈上位机程序(一),如果头瞄做完的话,我会贴二给大家看的。
|