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.