Hallo Gemeinde, ich habe ein Interface ( iSMIF von der Fa. EMIS ) um eine Schrittmotorkarte (SMC 800) anzusteuern. Die Befehle werden in ASCII über die serielle Schnittstelle übermittelt. Das Senden und Empfangen funktioniert einwandfrei. Das Interface sendet eine 6 zurück, wenn es bereit ist den nächsten Befehl zu empfangen. Die Zeit dazu ist unterschiedlich, da es ja länger dauert 10.000 Schritte zu fahren als z.B. nur 500 Schritte. Das Empfangen habe ich nach langem Googeln über das SerialPort.DataReceived Ereignis hinbekommen und lasse es mir in einer ListBox anzeigen. Soweit so prima. Nun zu meinem Problem ; ich will ja mehr als nur einmal verschiedene Schritte fahren ( mein Ziel ist sowas in Richtung Plotter bzw ganz einfache CNC Steuerung ). Wenn ich mehrere Schritte, z.B. mit einer Schleife, an das Interface schicke wird das SerialPort.DataReceived Ereignis nicht bei jedem Durchlauf ausgelöst, sondern erst am Ende. Ich muss aber vor jedem Schritt warten bis das Interface mit der 6 meldet das es bereit für den nächsten Befehl ist. Wie kann ich erreichen das bei jedem Schleifendurchlauf das SerialPort.DataReceived Ereignis ausgelöst wird. Vielen Dank an alle die Interesse und vielleicht eine Lösung zu meinem Problemchen haben. LG Tommy G. hier mein bisheriger Code oder in der angehängten Datei Option Strict On Option Explicit On Imports System Imports System.IO Imports System.Windows.Forms Imports Microsoft.VisualBasic Imports System.Drawing Imports System.IO.Ports Public Class Rückantwort_Test_DataReceived Dim PufferString As String Private Delegate Sub DelegateSub() Private Datenanzeigen As New DelegateSub(AddressOf Anzeigen) Private Sub btnVerbinden_Click(sender As Object, e As System.EventArgs) Handles btnVerbinden.Click SerialPort1.PortName = "COM3" SerialPort1.Parity = Parity.None SerialPort1.BaudRate = 115200 SerialPort1.DataBits = 8 SerialPort1.StopBits = StopBits.One SerialPort1.Open() liboTHG.Items.Add("Verbunden mit COM 3") btnVerbinden.Enabled = False btnTrennen.Enabled = True End Sub Private Sub btnTrennen_Click(sender As Object, e As System.EventArgs) Handles btnTrennen.Click SerialPort1.Close() liboTHG.Items.Add("COM 3 getrennt") End Sub Private Sub Rückantwort_Test_Load(sender As Object, e As System.EventArgs) Handles Me.Load btnTrennen.Enabled = False End Sub Private Sub Rückantwort_Test_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing SerialPort1.Close() End Sub Private Sub btnLeeren_Click(sender As Object, e As System.EventArgs) Handles btnLeeren.Click liboTHG.Items.Clear() End Sub Private Sub btnVor_Click(sender As Object, e As System.EventArgs) Handles btnVor.Click Dim Takt As String = txtTakt.Text For i = 1 To 3 Step 1 SerialPort1.Write("T0," & vbCr) SerialPort1.Write("L1,x" & Takt & vbCr) liboTHG.Items.Add("L1,x" & Takt) liboTHG.Items.Add("----------------------") Next End Sub Private Sub btnZurück_Click(sender As Object, e As System.EventArgs) Handles btnZurück.Click Dim Takt As String = txtTakt.Text SerialPort1.Write("T0," & vbCr) SerialPort1.Write("L1,x-" & Takt & vbCr) liboTHG.Items.Add("L1,x-" & Takt) liboTHG.Items.Add("----------------------") End Sub Private Sub SerialPort1_DataReceived(ByVal sender As Object, _ ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _ Handles SerialPort1.DataReceived Dim enc As System.Text.Encoding = New System.Text.ASCIIEncoding() With SerialPort1 Try ' Alle Bytes einzeln lesen For I As Integer = 1 To .BytesToRead ' 1 Byte lesen Dim ByteArray() As Byte = {CByte(.BaseStream.ReadByte)} ' Array in String PufferString = enc.GetString(ByteArray) ' Delegaten aufrufen Me.Invoke(Datenanzeigen) Next Catch ex As Exception MessageBox.Show(ex.Message, "Fehler beim Empfangen ...") End Try End With End Sub Private Sub Anzeigen() ' Text am Ende hinzufügen liboTHG.Items.Add(Asc(PufferString)) liboTHG.Items.Add("----------------------") End Sub
Thomas G. schrieb: > Wie kann ich erreichen das bei jedem Schleifendurchlauf das > SerialPort.DataReceived Ereignis ausgelöst wird. Gar nicht. Du stellst deine Strategie um. Du hast eine Liste von Befehlen. Und jedesmal wenn dein DataReceived anschlägt und du eine 6 empfängst, siehst du in dieser Tabelle nach, ob ein weiterer Befehl zur Steuerung zu schicken ist. Wenn ja, dann machst du das. D.h. man könnte das ganze auch so auffassen. Die Steuerung fordert mit ihrer 'Fertig'-Meldung den jeweils nächsten Befehl an. Den allerersten Befehl schickst du konventionell auf die Reise und durch das Rücksenden der '6' triggert die Steuerung selber das Senden des nächsten Befehls (falls es noch einen gibt)
Erst einmal vielen Dank für die schnelle Antwort. In die Richtung hatte ich auch schon gedacht, aber noch nichts ausprobiert. Könntest du mir bitte deine Idee näher erklären? Ich wüsste im Moment nicht wie und wo ich da ansetzen sollte. Das Programm habe ich mit VB.net Studio 2010 unter WIN XP geschrieben. Es würde reichen wenn du mir einen ungefähren Weg unterbreiten könntest und ich dann versuche den umzusetzen. Ein Code - Schnipsel währe natürlich ein Sahnehäubchen. Vielen Dank im Voraus für deine Bemühungen. LG Tommy G.
Was gibts da grossartig schwieriges dim Befehle(100) as string dim AnzahlBefehle as integer dim AktuellerBefehl as integer irgendwo stellst du deine Befehlslisten zusammen (ich kenn ja deine Befehle nicht, also nehm ich einfach was aus dem was du vorgegeben hast Befehle(1) = "L1,x" & Takt & vbCr Befehle(2) = "L1,x" & Takt & vbCr Befehle(3) = "L1,x-" & Takt & vbCr Befehle(4) = "L1,x" & Takt & vbCr AnzahlBefehle = 4 AktuellerBefehl = 1 und den ersten Befehl setzt du direkt ab SerialPort1.Write("T0," & vbCr) Wird die DataReceived aufgerufen, dann weißt du, dass der letzte Befehl (bei positiver Rückmeldung) fertig abgearbeitet wurde Private Sub SerialPort1_DataReceived(ByVal sender As Object, _ ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _ Handles SerialPort1.DataReceived Dim enc As System.Text.Encoding = New System.Text.ASCIIEncoding() With SerialPort1 Try ' Alle Bytes einzeln lesen For I As Integer = 1 To .BytesToRead ' 1 Byte lesen Dim ByteArray() As Byte = {CByte(.BaseStream.ReadByte)} ' Array in String PufferString = enc.GetString(ByteArray) ' Delegaten aufrufen Me.Invoke(Datenanzeigen) if AktuellerBefehl < AnzahlBefehle then SerialPort1.Write( Befehle(AktuellerBefehl) ) AktuellerBefehl = AktuellerBefehl + 1 end if Next Catch ex As Exception MessageBox.Show(ex.Message, "Fehler beim Empfangen ...") End Try End With End Sub so ungefähr. Ich kenn weder dein Board noch welche Befehle es will noch hab ich jetzt die VB Syntax dazu im Kopf. Aber vom Prinzip her sollte klar sein, wie das laufen kann.
Hi, vielen Dank für deine Antwort. Leider kann man aus einem separatem Thred nicht so einfach auf eine laufende Form zugreifen. Aber; ich habe mein Problemchen mit einem Timer - Aufruf gelöst. Funktioniert bei z.B. 100 mal 10 Schritte genau so gut wie bei 1 mal 25000 Schritte. Der Lösungsansatz mit dem Timer wurde hier im Forum schon mal erwähnt. Gefunden hatte ich ihn beim googeln. Sollte Interesse bestehen, bin ich gerne bereit zu helfen oder meinen funktionierenden Code hier einzustellen. Vielen Dank auch an alle Leser, auch wenn sonst keiner eine Lösung hatte. Dieser Beitrag kann nun als erledigt angesehen werden. LG Tommy
Thomas G. schrieb: > Hi, > > vielen Dank für deine Antwort. Leider kann man aus einem separatem Thred > nicht so einfach auf eine laufende Form zugreifen. Dann musst du eben über einen Invoke und eine Hilfsfunktion gehen.
Hallo, hat jemand von euch dieses Interface schon einmal mit C# angesteuert statt VB ? Leider kann ich nämlich keine Rückantwort des Interface erhalten. Grüße Hans
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.