Forum: PC-Programmierung [VB.NET] Probleme beim Auslesen der seriellen Schnittstelle


von Michael (Gast)


Lesenswert?

Hallo,

ich hoffe ihr könnt mir helfen, denn ich bin echt am verzweifeln.

Ich habe einen Kartenleser an Com9 meines Rechners angeschlossen. An
diesen muss ich Befehle schicken und dann die Antwort empfangen. Das
komische ist, dass die ersten 2-3 Befehle richtig bearbeitet werden und
die folgenden dann mal richtig und mal falsche Ergebnisse liefern.
Leider hab ich absolut keine Ahnung woran das liegen kann. Das
Lesegerät und die Karten sind in Ordnung, es muss an meinem Programm /
Programmablauf hängen.

Die Verbindung zur seriellen Schnittstelle habe ich so gelöst:

Private Sub connection()

mySerial = New SerialPort("COM9", 9600, IO.Ports.Parity.None, 8,
IO.Ports.StopBits.One)
mySerial.Encoding = System.Text.Encoding.GetEncoding(1252)
mySerial.Open()

End Sub

#################################################################

Die Befehle schick ich folgendermaßen ab:

Private Sub senden(ByVal buffer As Byte())

Dim i As Integer

'Im ersten Array liegt die Anzahl der Folgebytes
Dim anzahl = buffer(0)

'Bytes nacheinander an die Serielle Schnittstelle schicken

For i = 0 To anzahl
   mySerial.Write(Chr(buffer(i)))
Next

End Sub

################################################################

Aufgerufen wird die Sendefunktion aus meinem Hauptprogramm und von dort
wird der entsprechende SendeBefehl übergeben

zb:

Dim buffer1 As Byte() = {&H2, &HB0, &B2}
senden(buffer1)

#################################################################

Die Antwort lese ich mit folgendem Code aus:

Private Function lesen() As Byte()

Dim readbuffer As Byte() = {}

'Empfangsbuffer auf die richtige Größe bringen

ReDim readbuffer(mySerial.BytesToRead() - 1)

'Daten von Schnittstelle in Buffer schreiben

mySerial.Read(readbuffer, 0, mySerial.BytesToRead)

lesen = readbuffer

End Function

#################################################################

Wie gesagt, manchmal geht alles glatt, manchmal nicht. An der Karte
kann es nicht liegen. Hab ich vielleicht irgend etwas nicht bedacht,
was noch beachtet werden muss? Ich hab auch schon mal zwischen die
Sende und Lesevorgänge ein Thread.Sleep(1000) gelegt aber auch das hat
keine Verbesserung gebracht.

Muss noch etwas anderes eingebaut werden, damit die Kommunikation
reibungslos verläuft?

Ich hoffe ihr könnt mir da einen Tipp geben.

VG

Michael

von Karl heinz B. (kbucheg)


Lesenswert?

> Hab ich vielleicht irgend etwas nicht bedacht,
> was noch beachtet werden muss

Da fällt mir auf Anhieb eigentlich nur 'handshaking' ein.

Probier mal nach dem Senden eines einzelnen Zeichens in der
Sendeschleife eine kleine Pause einzulegen um den Gerät Zeit zu
geben, das empfangene Zeichen auch zu verarbeiten. Wenn's dann besser
wird, dann ist es das Handshaking.

von Wolfram (Gast)


Lesenswert?

>Private Function lesen() As Byte()
>Dim readbuffer As Byte() = {}
>'Empfangsbuffer auf die richtige Größe bringen
>ReDim readbuffer(mySerial.BytesToRead() - 1)
>'Daten von Schnittstelle in Buffer schreiben
>mySerial.Read(readbuffer, 0, mySerial.BytesToRead)
>lesen = readbuffer
>End Function

Was tust du hier eigentlich?
Du erstellst dir einen Puffer.
Dann stellst du fest wieviele Bytes an der Seriellen Schnittstelle sind
und vergroesserst dementsprechend den Puffer.
Woher weisst du das schon die ganze Antwort angekommen ist???
Du liest dann als die ermittelte Anzahl von Bytes aus und schreibst sie
in den Puffer.
Dann weist du diesen Puffer von mehreren Bytes einem Rueckgabewert zu
der ein Byte zurückgibt?

von Michael (Gast)


Lesenswert?

hi,

erstmal zu post1:

Hab jetzt mal in die Sendeschleife eine Pause eingebaut, Problem
besteht aber leider weiterhin.

@post2:

zwischen dem senden an die schnittstelle und dem lesen von der
schnittstelle hab ich eine pause eingebaut. daher müsste eigentlich auf
jeden fall schon die komplette antwort da sein. gibt es eine alternative
das zu testen?

Lesen is ja ein Byte-Array in das die einzelnen bytes geschrieben
werden. so kann ich dann im mainprogramm wieder auf die einzelnen
empfangenen bytes zugreifen.

ich beschäftige mich erst sei ein paar tagen mit .net. Wenn ich irgend
etwas sehr umständlich mache bin ich natürlich für jede hilfe dankbar

von Wobex (Gast)


Lesenswert?

Die grundsätzliche Frage bleibt allerding offen: Woher weisst du, wann 
ein Telegramm komplett empfangen ist?
Ist die Anzahl der Bytes je Telegramm immer gleich (längendefiniertes 
Telegramm) oder besitzt das Telegramm ein EOT-Character (CR, LF oder 
&h02) oder wird ein echter Hardware-Handshake durchgeführt - nicht nur 
"warten"?
Wann rufst du lesen() auf?
MySerial.BytesToRead liefert dir (so denke ich) die Anzahl der Bytes im 
Empfangspuffer, die gegenwärtig vorliegen. Ob das alle sind - woher 
weisst du das?
Wenn du nur Teile eines Telegramms ausliest, wird der nicht gelesene 
Rest des Telegramms durch deinen Code an den Anfang des nächsten 
Telegramms gesetzt - wenn das mehrmals passiert, hast du ein perfektes 
Kauderwelsch-Telegramm.
Ich würde zunächst mal das Sendeformat und Handshaking deines 
Kartenlesers überprüfen und debuggen, ob du komplette Telegramme 
einliest - und nicht aneinandergehängte Teiltelegramme...

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
Noch kein Account? Hier anmelden.