www.mikrocontroller.net

Forum: PC-Programmierung [vb.net] Serial Port korrekt Daten empfangen


Autor: Lehrmann Michael (ubimbo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo liebe Forengemeinde,

ich hätte eine kleine Problemstellung und bitte um Denkanstöße:

Ich besitze einen "Funkempfänger" auch "Scanner" genannt. Diese besitzt 
eine serielle Schnittstelle. Der Datenverkehr ist recht gut erforscht: 
http://www.freqofnature.com/index.php?m=Software&p...

Ich möchte den Scanner mit Hilfe meiner Software bedienen können. Dies 
klappt auch soweit (Write-Kommandos funktionieren tadellos) nur leider 
der Empfang der vom Scanner gesendeten Informationen bereitet Probleme.

Schreiben:

SerialPort1.Write("LCD1" & vbCrLf)

funktioniert bestens.

Darauf sollte der Scanner antworten, das tut er auch

Lesen tue ich (sicherlich falsch) so:

For i = 0 To 40 Step 1
            Label2.Text = Label2.Text & Chr(SerialPort1.ReadByte)
        Next

leider hängt das Programm nach einiger Zeit und ich bekomme eine 
Fehlermeldung. Dies passiert primär dann, wenn ich "zu schnell" 
hintereinander Kommandos sende.

Ich wollte nun fragen was ich tun muss, damit das alles korrekt abläuft.
Hier ein paar Stichworte die mir einfallen:

- Time out (beim Serial Port) was ist das, welchen Sinn ergibt es und 
wie sollte ich es konfigurieren.

- Sende / Empfangspuffer leeren ?

- Gibt es sowas wie einen Interrupt zum Empfangen oder ein Flag die man 
regelmäßig auslesen könnte ?

- Wie stelle ich sicher, dass keine weiteren Kommandos gesendet werden 
bevor alles ausgelesen ist ?

Vielen Dank

Gruß

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also in c# gibts da ein Event das RecieveByte (oder so) heißt. 
Vielleicht gibts das in VB auch (in c# könnte ich dir konkret sagen wie 
das geht. Basic hab ich so meine Probleme.

Autor: lorefach (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

Ich habe mich erst kürzlich mit dem selben Thema beschäftigt.

Anbei ein Beispiel zum lesen der Daten.

Achtung: Wenn der 'input' in ein Control auf Deiner Form geschrieben 
werden soll, muss mit einem Delegaten gearbeitet werden!

------------------------------------------------------------------------
Imports System.IO.Ports
Public Class Form1

Private WithEvents MySP As New SerialPort

Private Sub Form1_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
MySP = New SerialPort("COM1")
'Hier könnten noch weitere Einstellungen wie StopBits usw. eingestellt 
werden.
MySP.BaudRate = 19200
MySP.Open()
MySP.DtrEnable = True
MySP.RtsEnable = True
End Sub

Private Sub MySP_DataReceived(ByVal sender As Object, ByVal e As
System.IO.Ports.SerialDataReceivedEventArgs) Handles MySP.DataReceived
Dim input As String
input = MySP.ReadLine
MsgBox(input)
End Sub
End Class
-----------------------------------------------------------------------

Gruss
lorefach

Autor: Lehrmann Michael (ubimbo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soo also ich hab's mir jetzt selbst zusammengesucht. Für meine Probleme 
fand ich folgende Lösung:
Dim Empfang As String
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        SerialPort1.PortName = "COM9"
        SerialPort1.BaudRate = 19200
        SerialPort1.DataBits = 8
        SerialPort1.ReadTimeout = -1
        SerialPort1.StopBits = IO.Ports.StopBits.One
        SerialPort1.Parity = IO.Ports.Parity.None
        SerialPort1.ReceivedBytesThreshold = 1
        SerialPort1.Open()
    End Sub

dann
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        Try
            Do Until Empfang = vbCrLf
                'Empfang &= SerialPort1.ReadChar
                Empfang &= Convert.ToChar(Convert.ToInt16(SerialPort1.ReadChar.ToString))
            Loop
            SerialPort1.DiscardInBuffer()

        Catch ex As Exception

        End Try
    End Sub


Ist natürlich alles doppelt und dreifach gemoppelt (der Type-Cast) und 
warscheinlich so das schlimmste was ich machen konnte. Auch das Try ist 
eher behelfsmäßig. Funktioniert aber für meine Anforderungen besten !

Vielen Dank an alle die versucht haben zu Helfen


Gruß =)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lehrmann Michael schrieb:

>             Do Until Empfang = vbCrLf
>                 'Empfang &= SerialPort1.ReadChar
>                 Empfang &=
> Convert.ToChar(Convert.ToInt16(SerialPort1.ReadChar.ToString))
>             Loop
>             SerialPort1.DiscardInBuffer()

Bei sowas leuten bei mir sofort alle Warnglocken. Man Discarded keinen 
Buffer, wenn man nicht weiß was drinnen steht und wie vollständig das 
ist. Eigentlich sollte sich jede Empfnagsroutine jedes einzelne Byte 
ansehen und entscheiden was es damit machen will. Die Gefahr ist 
riesengroß, dass dein Gegenüber schon den nächsten Datensatz auf den Weg 
gebracht hat, von dem ein Teil auch schon angekommen ist, den du dann 
mit dem Discard entsorgst. Der nächste Empfang steigt dann mitten in die 
laufende Übertragung ein und schon ist das Chaos perfekt.

Autor: lorefach (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Michael,

Ich sehe nicht ein, wieso du nicht "SerialPort1.readline" anwendest...
Aus meiner Sicht sollte das selbe Resultat entstehen - einfach 
Einfacher! ;-)

Anyhow - Viel Spass damit!

Gruss
lorefach

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.