'Vielen Dank an Andreas Karg für die Vorarbeit auf TCP-Seite 'Vielen Dank an F. Schn. für die Übersetzung von c# nach VB Syntax 'Dieses Projekt geht auf den Diskussionsthread http://forum.zusi.de/viewtopic.php?f=25&t=10781 zurück Imports System Imports System.IO.Ports Imports System.Threading Imports System.Collections.Generic Imports System.ComponentModel Imports System.Drawing Imports System.Text Imports System.Windows.Forms Imports Zusi_Datenausgabe ' ZusiTCPDemoApp ' This example shows basic usage of Andreas Karg's Zusi TCP interface for .Net. ' It is published under the GNU General Public License v3.0. Base your own work on it, play around, do what you want. :-) ' ' ' Using the interface requires three steps: ' - Write one or more handler methods ' - Create a ZusiTcpConn object, passing basic parameters ' - Tell your ZusiTcpConn object what measures you want to receive ' ' Everything else is explained below. ' ZusiTCPDemoAppVBA ' Translated C#-Project into VisualBasic. Public Class CMainWindow Dim LmPzb1000 As Byte Dim LmPzbU As Byte Dim LmPzbO As Byte Dim LmHS As Byte Dim LmTuer As Byte Dim LmElBr As Byte Dim ElBr As Integer Dim HLsoll As Integer Dim HList As Integer Dim Motorstrom As Integer Dim Fbv As Integer Dim Fs As Integer Dim Differenz As Integer Dim Abspiel As Integer Dim Abspiell As Integer Dim Abspiellos As Integer Dim Lm1 As Byte Dim zeitdiff As Integer Dim OutChar(2) As Byte Dim tastendruck As Integer Dim letztestunde As Integer Dim INa As Byte Dim INax As Byte Dim INb As Byte Dim INbx As Byte Dim INc As Byte Dim INd As Byte Dim Regler As Integer Dim Cnt As Integer Dim Zugkraft As Integer Dim FSsoll As Integer Dim FSist As Integer ' We do want to have a ZusiTcpConn object, so here's the declaration Private MyTCPConnection As ZusiTcpConn Public CMainWindow() Public Sub New() InitializeComponent() ' When the application window is created, we create our new connection class as well. ' ReceiveEvent is a generic delegate type for you to use. See the Object Browser for details. */ MyTCPConnection = New ZusiTcpConn( _ "Zusi TCP for .NET Demo (VBA)", _ ClientPriority.High, _ New ReceiveEvent(Of Single)(AddressOf HandleIncomingData), _ Nothing, _ Nothing _ ) ' The name of this application (Shows up on the server's list) ' The priority with which the server should treat you ' A delegate method for the connection class to call when it receives float data (may be null) ' A delegate method for the connection class to call when it receives string data (may be null) ' A delegate method for the connection class to call when it receives byte[] data (may be null) ' Now we need to tell our connection object what measures to request from Zusi. ' You may either use Zusi's native ID code or plain text as listed in the server's commandset.ini MyTCPConnection.RequestData(2561) 'Geschwindigkeit MyTCPConnection.RequestData(2562) 'Druck Hauptluftleitung MyTCPConnection.RequestData(2563) 'Druck Bremszylinder MyTCPConnection.RequestData(2564) 'Druck HL Behälter MyTCPConnection.RequestData(2565) 'Zugkraft gesamt MyTCPConnection.RequestData(2567) 'Strom MyTCPConnection.RequestData(2570) 'Stunde MyTCPConnection.RequestData(2571) 'Minute MyTCPConnection.RequestData(2580) 'LM PZB 1000Hz MyTCPConnection.RequestData(2581) 'LM PZB 500Hz MyTCPConnection.RequestData(2585) 'M PZB Zugart O MyTCPConnection.RequestData(2597) 'LM Hauptschalter MyTCPConnection.RequestData(2607) 'LM Türen MyTCPConnection.RequestData(2611) 'Fahrschalter MyTCPConnection.RequestData(2612) 'Fbv End Sub ' This is what happens when the user clicks the "Connect" button. Private Declare Sub keybd_event Lib "user32" ( _ ByVal bVk As Byte, _ ByVal bScan As Byte, _ ByVal dwFlags As Long, _ ByVal dwExtraInfo As Long _ ) Private Sub BtnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnConnect.Click ' If we're currently disconnected... If (MyTCPConnection.ConnectionState = Zusi_Datenausgabe.ConnectionState.Disconnected) Then ' ... try to ... Try ' ... establish a connection using the hostname and port number from the main window. MyTCPConnection.Connect(TbServer.Text, Convert.ToInt32(TbPort.Text)) ' When successful, change the button label to "Disconnect". BtnConnect.Text = "Trennen" ' If something goes wrong... Catch ex As ZusiTcpException ' ... show the user what the connection object has to say. MessageBox.Show(String.Format("An error occured when trying to connect: {0}", ex.Message)) End Try ' If we're currently connected or the connection fell into an error state... Else ' ... reset the connection by explicitly calling Disconnect(); MyTCPConnection.Disconnnect() ' ... and then change the button label to "Connect". BtnConnect.Text = "Verbinden" End If End Sub ' We told the interface object to call this method when data arrives. ' You can do whatever you want in there. In this example we show the new values in the main window. Private Sub HandleIncomingData(ByVal dataSet As DataSet(Of Single)) Select Case dataSet.Id Case 2612 'Fbv Fbv = CByte(Math.Round(dataSet.Value, 0)) Label5.Text = Fbv End Select If +Serial.IsOpen Then Select Case dataSet.Id Case 2561 'Geschwindigkeit3 OutChar(0) = 86 'V OutChar(1) = CByte(Math.Round(0.5 * dataSet.Value, 0)) Serial.Write(OutChar, 0, 2) Case 2562 'HL HList = Math.Round(100 * dataSet.Value, 0) + 1 OutChar(0) = 76 'L OutChar(1) = CByte(Math.Round(8.8 * dataSet.Value, 0)) Serial.Write(OutChar, 0, 2) Case 2563 'Druck Bremszylinder OutChar(0) = 46 'B OutChar(1) = CByte(Math.Round(10 * dataSet.Value, 0)) Serial.Write(OutChar, 0, 2) Case 2564 'HB OutChar(0) = 72 'H OutChar(1) = CByte(Math.Round(5.31 * dataSet.Value, 0)) Serial.Write(OutChar, 0, 2) Case 2565 'Zugkraft/Motorstrom If Math.Round(dataSet.Value, 0) > 1 Then OutChar(0) = 77 'M OutChar(1) = CByte(Math.Round(0.15 * dataSet.Value, 0)) Motorstromsig.Value = Math.Round(dataSet.Value, 0) Else OutChar(0) = 77 'M OutChar(1) = CByte(Math.Round(0)) End If Serial.Write(OutChar, 0, 2) Case 2567 'Primaerstrom If Math.Round(dataSet.Value, 0) > 1 Then OutChar(0) = 78 'N OutChar(1) = CByte(Math.Round(0.07 * dataSet.Value, 0)) Primstromsig.Value = Math.Round(dataSet.Value, 0) Else OutChar(0) = 78 OutChar(1) = CByte(Math.Round(1)) Primstromsig.Value = Math.Round(dataSet.Value, 0) End If Serial.Write(OutChar, 0, 2) Case 2570 'Stunde OutChar(0) = 88 'X OutChar(1) = CByte(Math.Round(zeitdiff + dataSet.Value, 0)) Serial.Write(OutChar, 0, 2) If CheckBox1.Checked = True Then zeitdiff = 11.5 Else zeitdiff = -0.5 End If Label4.Text = CByte(Math.Round(zeitdiff + dataSet.Value, 0)) If letztestunde > CByte(Math.Round(dataSet.Value, 0)) Then CheckBox1.Checked = True End If letztestunde = CByte(Math.Round(dataSet.Value, 0)) Case 2571 'Minute OutChar(0) = 89 'Y OutChar(1) = CByte(Math.Round(5 * dataSet.Value, 0)) Serial.Write(OutChar, 0, 2) Label3.Text = CByte(Math.Round(5 * dataSet.Value, 0)) Case 2585 'M PZB Zugart O lmpsig.Checked = dataSet.Value LmPzbO = CByte(dataSet.Value) Case 2583 'LM PZB Zugart U lmgsig.Checked = dataSet.Value LmPzbU = CByte(dataSet.Value) << 1 Case 2580 'LM PZB 1000Hz lm1000sig.Checked = dataSet.Value LmPzb1000 = CByte(dataSet.Value) << 2 Case 2597 'Lm Hauptschalter lmHSsig.Checked = 1 - dataSet.Value LmHS = 1 - CByte(dataSet.Value) << 3 Case 2607 'Lm Türen LmTuer = CByte(dataSet.Value) << 4 Case 2611 'Fahrstufe FSist = Math.Round(dataSet.Value, 0) Fsig.Text = FSist If CByte(Math.Round(dataSet.Value, 0)) < 15 Then ElBr = 1 Else ElBr = 0 End If LmElBr = CByte(ElBr) << 5 End Select Lm1 = LmPzbO Or LmPzbU Or LmPzb1000 Or LmHS Or LmTuer Or LmElBr OutChar(0) = 80 'P OutChar(1) = Lm1 Serial.Write(OutChar, 0, 2) End If End Sub 'Das Form_Load-Ereignis Private Sub CMainWindow_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load AddCom2Combo(CbCom) End Sub 'Hier wird eine Liste der vorhandennen COM-Ports erstellt Sub AddCom2Combo(ByVal cbPort As ComboBox) ' Get a list of serial port names. Dim ports As String() = SerialPort.GetPortNames() ' Show a label with Action information on it cbPort.Text = "The following serial ports were found:" ' Put each port name Into a comboBox control. Dim port As String For Each port In ports cbPort.Items.Add(port) Next port ' Select the first item in the combo control cbPort.SelectedIndex = 0 End Sub 'Hier wird die Verbindung zu unserer Ausgabehardware hergestellt. Private Sub ComCon_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComCon.Click If Not Serial.IsOpen Then Serial.PortName = CbCom.SelectedItem Serial.Open() ComCon.Text = "Trennen" Serial.WriteLine("ww") System.Threading.Thread.Sleep(500) If Serial.BytesToRead > 0 Then If Not Serial.ReadLine() = "I am a drivers desk" & System.Text.Encoding.UTF8.GetString({13}) Then MessageBox.Show("An dem gewählten Port scheint das falsche Gerät angeschlossen zu sein!") Serial.Close() ComCon.Text = "Verbinden" End If Else MessageBox.Show("An dem gewählten Port scheint kein Gerät angeschlossen zu sein!") Serial.Close() ComCon.Text = "Verbinden" End If Else Serial.Close() ComCon.Text = "Verbinden" End If End Sub Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick If Serial.IsOpen Serial.WriteLine("rr") 'Werte vom Arduino anfordern If Serial.ReadLine() = "readytosend" & System.Text.Encoding.UTF8.GetString({13}) Then INa = Serial.ReadByte() INb = Serial.ReadByte() INc = Serial.ReadByte() INd = Serial.ReadByte() zwei.Text = INc eins.Text = INd readsig.Checked = 1 'Hier werden die digitalen Inputs an Zusi weitergeleitet: 'Bei Zusi - Tastern wird bei einem Zustandswechsel von 0 auf 1 gesendet, bei Schaltern auch bei 1 auf 0. 'Länger gedrückte Taster müssen über die Funktion "keabd_event" abgewickelt werden. If INa = 1 Then If INax <> 1 Then SendKeys.Send("R") 'Lüfter 0=>1, Key "R" lueftersig.Checked = 1 End If End If If INa <> 1 Then If INax = 1 Then SendKeys.Send("R") 'Lüfter 1=>0 lueftersig.Checked = 0 End If End If If INa / 2 = 1 Then If INax / 2 <> 1 Then SendKeys.Send("G") 'Befehl 0=>1, Key "G" befehlsig.Checked = 1 End If End If If INa / 2 <> 1 Then If INax / 2 = 1 Then SendKeys.Send("G") 'Befehl 1=>0 befehlsig.Checked = 0 End If End If If INa / 4 = 1 Then If INax / 4 <> 1 Then keybd_event(&H46, 0, 0, 0) 'Frei 0=>1 - Key "F" freisig.Checked = 1 End If End If If INa / 4 <> 1 Then If INax / 4 = 1 Then keybd_event(&H46, 0, &H2, 0) 'Frei 1=> 0 freisig.Checked = 0 End If End If If INa / 8 = 1 Then If INax / 8 <> 1 Then keybd_event(&H45, 0, 0, 0) 'Wachsam 0=>1 - Key "E" wachsamsig.Checked = 1 End If End If If INa / 8 <> 1 Then If INax / 8 = 1 Then keybd_event(&H45, 0, &H2, 0) 'Wachsam 1=> 0 wachsamsig.Checked = 0 End If End If If INa / 16 = 1 Then If INax / 16 <> 1 Then SendKeys.Send("H") 'HSein If INa / 32 = 1 Then If INax / 32 <> 1 Then SendKeys.Send("H") 'HSaus If INa / 64 = 1 Then If INax / 64 <> 1 Then keybd_event(&H4A, 0, 0, 0) 'Horn 0=>1 - Key "J" hornsig.Checked = 1 End If End If If INa / 64 <> 1 Then If INax / 64 = 1 Then keybd_event(&H4A, 0, &H2, 0) 'Horn 1=>0 hornsig.Checked = 0 End If End If If INa / 128 = 1 Then If INax / 128 <> 1 Then SendKeys.Send("H") 'Sifa 0=>1 Key "I" sandsig.Checked = 1 End If End If If INa / 128 <> 1 Then If INax / 128 = 1 Then SendKeys.Send("H") 'Sifa 0=>1 Key "I" sandsig.Checked = 0 End If End If If INb = 1 Then If INbx <> 1 Then SendKeys.SendWait("H") 'Sifa If INb / 2 = 1 Then If INbx / 2 <> 1 Then SendKeys.Send("P") 'Strom If INb / 4 = 1 Then If INbx / 4 <> 1 Then SendKeys.Send("H") 'Sifa If INb / 8 = 1 Then If INbx / 8 <> 1 Then SendKeys.Send("C") 'Schnellaus If INb / 16 = 1 Then If INbx / 16 <> 1 Then SendKeys.Send("{F11}") 'Zeitsprung If INb / 32 = 1 Then If INbx / 32 <> 1 Then SendKeys.Send("{F2}") 'Pause If INb / 64 = 1 Then If INbx / 64 <> 1 Then SendKeys.Send("{F9}") 'Zeitraffer ' If INb / 128 = 1 Then If INbx / 64 <> 1 Then SendKeys.Send("I") 'Stromabnehmer If INd > 50 Then INd = 0 INax = INa INbx = INb Bremsventilsig.Value = INc Fahrschaltersig.Value = INd readsig.Checked = 0 hlistsig.Value = HList 'Die Steuerung des FbVs HLsoll = INc * 4 hlsollsig.Value = HLsoll Differenz = HLsoll - HList Label16.Text = Differenz If Differenz > 5 And Fbv <> 1 Then SendKeys.Send("6") ElseIf Differenz < (-5) And Fbv <> 4 Then SendKeys.Send("8") ElseIf Differenz < 5 And Differenz > (-5) And Fbv <> 3 Then SendKeys.Send("7") Abspiel = 0 Abspiell = 0 End If If FSist < INd Then 'Fahrschalter SendKeys.Send("V") End If If FSist > INd Then SendKeys.Send("B") End If If Differenz < -8 And Abspiel = 0 Then 'Soundausgabee für das FbV My.Computer.Audio.Play("C:\Daten\zugbr_an_2.wav") Abspiel = 1 End If If Differenz < -40 And Abspiell = 0 Then My.Computer.Audio.Play("C:\Daten\zugbr_an_1.wav") Abspiell = 1 End If If Differenz > 40 And Abspiel = 0 Then My.Computer.Audio.Play("C:\Daten\zugbr_lose_2.wav") Abspiel = 1 End If If HLsoll > 500 And Abspiellos = 0 Then My.Computer.Audio.Play("C:\Daten\zugbr_lose_1.wav") Abspiellos = 1 End If If HLsoll < 495 Then Abspiellos = 0 End If End If End Sub Private Sub Fahrschaltersig_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Fahrschaltersig.Click End Sub Private Sub Motorstromsig_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Motorstromsig.Click End Sub End Class