vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Top-Preis! AP-Access-Tools-CD Volume 1  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Ein- und Umsteiger
Teilweiser Empfang an Serialport zusammensetzen 
Autor: Undertaker17
Datum: 24.11.15 16:49

Hallo liebe Archiv-ler,

ich hab da ein für mich recht umfangreiches Problem dessen grund ich trotz stundenlanger rumprobiererei bisher nicht ergründen konnte.

Ich habe mir den Code aus .NET- Tipp 0071 angepasst um Daten über eine USB-Virtuelle RS232 Schnittstelle zu empfangen.

    Private Sub myComPort_DataReceived(ByVal sender As Object, ByVal e As _
      System.IO.Ports.SerialDataReceivedEventArgs) Handles _
      myComPort.DataReceived
 
        Select Case e.EventType
            Case IO.Ports.SerialData.Chars
            Case IO.Ports.SerialData.Eof
        End Select
        Dim msg As String = Me.myComPort.ReadExisting
 
        ShowText(msg)
 
 
    End Sub
 
    Private Sub ShowText(ByVal text As String)
        If lblMeldungstext.InvokeRequired Then
            Dim d As New TextBoxCallback(AddressOf ShowText)
            Me.Invoke(d, New Object() {text})
        Else
            lblMeldungstext.Text = lbl.Meldungstext.Text & text
            End If
    End Sub
Der Empfang ansich, funktioniert soweit ganz Prima, nun habe ich leider das Problem, dass die Daten nur häppchenweise angezeigt werden, etwa auf diese weise:

Diese Mel
dung ist e
ine Demon
stration

Wenn ich nun in Showtext stehen habe:


lblMeldungstext.Text = lblMeldungstext.Text & text
,

dann wird der Text logischerweise am Stück angezeigt, da ja der Nachfolgende Teil, dem Vorhergehenden angegliedert wird.

Da aber bei Ankunft eines Neuen Datenpakets, der alte Text überschrieben werden soll, muss ich


lblMeldungstext.Text = text
schreiben.

Dann Rauschen eben nur, die Einzelnen Teilstrings durch, nur der letzte, wird dann dementsprechen bis zur Auslösung eines neuen DataReceived-ereignisses dauerhaft angezeigt.

Nun habe ich mir eine Art Stringbuilder gebaut:


    Private Sub myComPort_DataReceived(ByVal sender As Object, ByVal e As _
      System.IO.Ports.SerialDataReceivedEventArgs) Handles _
      myComPort.DataReceived
 
        Select Case e.EventType
            Case IO.Ports.SerialData.Chars
            Case IO.Ports.SerialData.Eof
        End Select
        Dim msg As String = Me.myComPort.ReadExisting
 
        While (msg.Contains(Chr(0)))
            'die nachricht ist komplett
            Dim tmp = msg.Substring(0, msg.IndexOf(Chr(0)))
            ShowText(msg)
            msg = ""
        End While
        ShowText(msg)
 
 
    End Sub
Da dies aber letztendlich keinen Effekt auf das Verhalten hat, (Leider bin ich mir nicht sicher, ob ein Chr(0) als Endzeichen übertragen wird, oder ob sowas überhaupt übertragen wird), bin ich mir sicher, dass ich da nen Totalen Quark geschrieben hab.

Nun meine Frage, wie könnte ich das ganze anderst, vorallem Zuverlässig schreiben??

Danke schonmal im vorraus,

Gruß

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: GPM
Datum: 24.11.15 17:38

Ich würde es erst mal mit ReadLine probieren.
Wenn es kein Standard-Zeilenende ist, kann man auch ein
eigenes Zeichen angeben. Muss man halt rausfinden.

Imports System.IO.Ports
Public Class Form1
     Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) _
       Handles MyBase.Load
        myComPort.Open()
        'eventuell eigenes NewLine-Zeichen für Zeilenende angeben
        'myComPort.NewLine = Chr(23)               
    End Sub
    Private Sub myComPort_DataReceived(sender As Object, e As _
      SerialDataReceivedEventArgs) Handles myComPort.DataReceived
        Me.Invoke(Sub() lblMeldungstext.Text = myComPort.ReadLine)
    End Sub
End Class
MfG GPM
0
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: Undertaker17
Datum: 25.11.15 13:46

Hallo GPM,

also so im Prinzip hör ich was du siehst... hab das auch grad ausprobiert, aber irgendwie tut sich nix.
Selbst über die Ausgabe per Debug.Print kommt nix an.
Hab ich das also jetzt Falsch verstanden, und Falsch geschrieben, oder funktionierts einfach nicht?


Gruß

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: GPM
Datum: 25.11.15 14:35

Einfach einen Funktionstest machen:
'Sende-Empfangstest bei einer einzelnen COM-Schnittstelle
'durch die Verbindung von RD+TD (9polig = Pin2 mit Pin3)
Imports System.IO.Ports
Public Class Form1
    Dim WithEvents Btn As New Button With {.Dock = DockStyle.Bottom, .Text = _
      "Senden", .Height = 30, .Parent = Me}
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As _
      System.EventArgs) Handles Me.Load
        Me.Width = 400
        SerialPort1.PortName = "COM5"   'Eigenen Portname einsetzen
        SerialPort1.Open()
    End Sub
 
    Private Sub Btn_MouseDown(sender As Object, e As EventArgs) Handles _
      Btn.MouseDown
        SerialPort1.WriteLine("Es ist gerade: " & Now.ToLongTimeString)
    End Sub
 
    Private Sub SerialPort1_DataReceived(sender As Object, e As _
      SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        Me.Invoke(Sub() Me.Text = SerialPort1.ReadLine)
    End Sub
End Class
MfG GPM
0
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: Undertaker17
Datum: 25.11.15 19:45

Also so siehts bei mir ausNach deinem ersten Tipp mit Readline)
    Private Sub frmHaupt_Load(ByVal sender As Object, ByVal e As _
      System.EventArgs) Handles Me.Load
        Dim str() As String = IO.Ports.SerialPort.GetPortNames()
        If str.Length = 0 Then
            MsgBox("No Serialport available!", MsgBoxStyle.Critical)
            Me.Close()
        End If
 
        myComPort = New IO.Ports.SerialPort("COM3")
        myComPort.BaudRate = 9600
        myComPort.DataBits = 8
        myComPort.StopBits = IO.Ports.StopBits.One
        myComPort.Parity = IO.Ports.Parity.None
        myComPort.ReceivedBytesThreshold = 1
        myComPort.Open()
        myComPort.Encoding = System.Text.Encoding.Default
        myComPort.NewLine = Chr(1)
    End Sub
 
 
 Private Sub myComPort_DataReceived(ByVal sender As Object, ByVal e As _
   System.IO.Ports.SerialDataReceivedEventArgs) Handles myComPort.DataReceived
 
        Me.Invoke(Sub() lblMeldungstext.Text = myComPort.ReadLine)
 
        'Select Case e.EventType
        '    Case IO.Ports.SerialData.Chars
        '    Case IO.Ports.SerialData.Eof
        'End Select
        'Dim msg As String = Me.myComPort.ReadExisting
 
        'While (msg.Contains(Chr(23)))
        '    'die nachricht ist komplett
        '    Dim tmp = msg.Substring(0, msg.IndexOf(Chr(23)))
        '    ShowText(msg)
        '    msg = ""
        'End While
 
        'ShowText(msg)
 
 
    End Sub
 
    Private Sub ShowText(ByVal text As String)
 
        'Me.Invoke(Sub() Debug.Print(myComPort.ReadLine))
        If lblMeldungstext.InvokeRequired Then
            Dim d As New TextBoxCallback(AddressOf ShowText)
            Me.Invoke(d, New Object() {text})
        Else
            lblMeldungstext.Text = text
        End If
    End Sub
Leider passiert immer noch nix...

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: GPM
Datum: 25.11.15 21:32

Das Standard-Zeilenende ist Chr(10)
Wenn ich mir den String "Hallo" schicke mit:
SerialPort1.WriteLine("Hallo")
und lass mir dann die Bytes einzeln anzeigen,
ergibt das : 72 97 108 108 111 10

Du musst nun halt selbst herausfinden, was bei Dir nach
dem letzten Text-Zeichen, als Abschluss kommt.

Gibt es denn keine Infos zu der Sendeart?

MfG GPM
0
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: Undertaker17
Datum: 26.11.15 14:44

Was genau meinst du mit "Sendeart"?

In der Programmiersoftware des gerätes gibt es eine option "Datenendzeichen: EOT/EOX", falls du das meinst...

Ich hab also eben versucht mir die Bytes auch mal anzeigen zu lassen:

        Dim msg As String = Me.myComPort.ReadExisting
        Dim TextConv As Byte = CByte(msg)
 
        Debug.Print(msg)
        Debug.Print(TextConv)
Bei der Convertierung wird allerdings eine Exception geworfen:


System.InvalidCastException wurde nicht behandelt.
HResult=-2147467262
Message=Ungültige Konvertierung von der Zeichenfolge
14:3 in Typ Byte.
.
.
.

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: GPM
Datum: 26.11.15 17:53

Ja, hier die unsichtbare ASCII-Zeichen z.B ETX, EOT:
http://halvar.at/elektronik/rs232/

Empfangene Zeichen als Byte in einer TextBox:
'Sende-Empfangstest bei einer einzelnen COM-Schnittstelle
'durch die Verbindung von RD+TD (9polig = Pin2 mit Pin3)
Public Class Form1
    Dim WithEvents Btn As New Button With {.Dock = DockStyle.Bottom, .Text = _
      "Senden", .Height = 30, .Parent = Me}
    Dim WithEvents Tb1 As New TextBox With {.Dock = DockStyle.Left, .Multiline _
    = True, .Parent = Me}
    Dim WithEvents Tb2 As New TextBox With {.Dock = DockStyle.Right, .Multiline _
    = True, .Parent = Me}
    Dim WithEvents T As New Timer
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As _
      System.EventArgs) Handles Me.Load
        SerialPort1.PortName = "COM5"   'Eigenen Portname einsetzen
        SerialPort1.Open()
        T.Start()
    End Sub
 
    Private Sub Btn_MouseDown(sender As Object, e As EventArgs) Handles _
      Btn.MouseDown
        SerialPort1.WriteLine("Hallo")
    End Sub
 
    Private Sub T_Tick(sender As Object, e As System.EventArgs) Handles T.Tick
        Dim b As Byte
        Do While SerialPort1.BytesToRead > 0
            b = CByte(SerialPort1.ReadByte)
            Tb1.Text &= "  " & b
            Tb2.Text &= Chr(b)
        Loop
    End Sub
End Class
MfG GPM
0
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: Undertaker17
Datum: 27.11.15 16:14

Sooo, also jetzt bin ich endlich ein wenig schlauer.

Ich hab nun einige wenige mögliche Steuerzeichen aus deiner Geposteten liste ausprobiert.*

003 - ETX, 004 - EOT, 024 - CAN, und 000 - NUL.

Die Einzige konfiguration in der überhaupt etwas übertragen wird ist mit 000. Also kann ich ja davon ausgehen dass das das tatsächliche Endzeichen sein muss.


Wenn ich nun folgendes verwende:
    Private Sub myComPort_DataReceived(ByVal sender As Object, ByVal e As _
      System.IO.Ports.SerialDataReceivedEventArgs) Handles _
      myComPort.DataReceived
 
        Dim msg As String = Me.myComPort.ReadExisting
 
        While (msg.Contains(Chr(0)))
            'die nachricht ist komplett
            Dim tmp = msg.Substring(0, msg.IndexOf(Chr(0)))
            ShowText(msg)
            msg = ""
        End While
 
        ShowText(msg)
    End Sub
 
    Private Sub ShowText(ByVal text As String)
 
        If lblMeldungstext.InvokeRequired Then
            Dim d As New TextBoxCallback(AddressOf ShowText)
            Me.Invoke(d, New Object() {text})
        Else
            lblMeldungstext.Text = text
            Debug.Print(text)
        End If
    End Sub
Dann werden zwar daten Übertragen, aber das ergibt das ursprüngliche Problem.


Wenn ich allerdings deine Methode verwende mittels Readline, dann funktioniert es im Prinzip wie es soll.

Allerdings ist mir eben aufgefallen, dass sich das Programm(Im Debugmodus von VB) dann vollständig aufhängt.(Nur das Programm als solches, VB kann ganz normal, soweit das im Debugmodus möglich ist, verwendet werden). Eine Exception wird nicht ausgegeben.
    Private Sub myComPort_DataReceived(ByVal sender As Object, ByVal e As      _
      System.IO.Ports.SerialDataReceivedEventArgs) Handles _
      myComPort.DataReceived
 
        Me.Invoke(Sub() lblMeldungstext.Text = myComPort.ReadLine)
 
    End Sub
Edit: Also das Programm hängt sich auch in Fertig kompiliertem Zustand auf. Laut Taskmanager liegt die CPU nutzung aber bei 0%, und die Arbeisspeicherbelegung bei ca. 14 MB. Aber dieser Text "Programm reagiert nicht", oder wie das auch schon wieder war, fehlt...

Wenn Das Programm innerhalb der IDE läuft, wird der Text noch angezeigt. In Kompiliertem Zustand, passiert nichts. Wie als wäre das Fenster eingefroren. Es lässt sich wieder Mini, noch Maximieren, und schon gar nicht per Kreuzchen Schließen. Ledigliich per "Task beenden" kann das Programm geschlossen werden.



Beitrag wurde zuletzt am 27.11.15 um 16:50:57 editiert.

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: sv00010
Datum: 27.11.15 17:18

Meiner Meinung nach solltest du das Empfangen der Daten und das Anzeigen der Daten trennen.
Ich würde mir an deiner Stelle einen Speicher erstellen, (z.B. einen MemoryStream) und dort die Daten, welche gelesen wurden einfüllen.
Zum Anzeigen würde ich dann nur noch vom Speicher lesen.
0
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: Undertaker17
Datum: 28.11.15 14:31

hallo sv00010,

Danke für deine Antwort. Diese möglichkeit habe ich auch schon in betracht gezogen, allerdings nicht mittels MemoryStream. Ich hätte jetzt erst den übertragenen String in eine Text-datei geschrieben, und diese dann wieder ausgelesen.

Mit MemoryStream habe ich bisher noch nicht gearbeitet. Hab es eben mal versucht, mit den Informationen die ich im Visual Basic 2008 Buch von Michael Kofler/Addison Weasley gefunden hab, leider bringt mich das nicht wirklich weiter....

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: Undertaker17
Datum: 01.12.15 00:38

Guten Morgen zusammen,

Sorry, dass ich euch damit noch weiter auf die Nerven geh...
Ich hab mich jetzt einige Stunden in die MemoryStream- Klasse eingelesen, aber irgendwie steh ich auf nem Dicken Schlauch. Initialisieren eines MemoryStreams ist klar.

Aber wenn ich jetzt Daten in den Stream Schreiben will, dann meckert VB rum, irgendwas von String und Byte-Array. Den genauen Wortlaut hab ich jetzt nicht im Kopf. Aber im Grunde ist das ja klar.

Aber geht das ganze denn nicht einfacher? Ich muss ja jetzt quasi erst den Empfangenen String in Byte Konvertieren, das dann wiederrum in einen MemoryStream packen, aus dem dann wieder auslesen und die Bytes wieder in String umwandeln??

Ich bekomm ja den String im Grunde genommen schon Anzeigefertig geliefert, nur eben nicht am Stück, also muss es doch eine Einfachere möglichkeit geben, den zusammenzusetzen, und anzuzeigen, anstatt so nen umweg zu gehen.

Oder denke ich jetzt einfach zu bequem??

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: ModeratorFZelle (Moderator)
Datum: 01.12.15 13:25

1. Die Serielle Schnittstelle liefert dir bytes und nicht strings.
2. Die kann man ganz simpelst in einer List(of byte) speichern.
3. aus der kann man natürlich auch Daten lesen und auch löschen
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: Undertaker17
Datum: 02.12.15 11:20

Also ich bin jetzt so weit, dass ich die Empfangenen daten als Bytes empfange:

    Private Sub myComPort_DataReceived(ByVal sender As Object, ByVal e As _
      System.IO.Ports.SerialDataReceivedEventArgs) Handles _
      myComPort.DataReceived
 
        Dim Bytes As New List(Of Byte)
        Me.Invoke(Sub() Bytes.Add(myComPort.ReadByte()))
        Dim n As Integer
 
        For n = 0 To Bytes.Count - 1
            Debug.Print(Bytes(n))
        Next
End Sub
Durch Debug.Print erhalte ich folgende Ausgabe:

13
10
49
49
58
48
54
32
48
50
46
49
50


Wenn ich nun weiter gehen will, und diese Bytes in einen String umwandeln will,

    Private Sub myComPort_DataReceived(ByVal sender As Object, ByVal e As _
      System.IO.Ports.SerialDataReceivedEventArgs) Handles _
      myComPort.DataReceived
 
        Dim Bytes As New List(Of Byte)
        Me.Invoke(Sub() Bytes.Add(myComPort.ReadByte()))
        Dim n As Integer
 
        For n = 0 To Bytes.Count - 1
            Debug.Print(Bytes(n))
        Next
 
        Dim o As Integer
        For o = 0 To Bytes.Count - 1
            System.Text.Encoding.Unicode.GetString(Bytes)
        Next
 
    End Sub
Erhalte ich Folgenden Fehler:


Fehler 1 Der Wert vom Typ "System.Collections.Generic.List(Of Byte)" kann nicht in "1-dimensionales Array von Byte" konvertiert werden.


Also wie mache ich daraus nun wieder einen String mit dem sich was anfangen lässt??


Edit:

Hab die Konvertierung grade so versucht:
        Dim Bytes As New List(Of Byte) From {"13", "10", "49", "49", "58", _
          "48", "54", "32", "48", "50", "46", "49", "50"}
 
        Dim o As Integer
        For o = 0 To Bytes.Count - 1
            Convert.FromBase64String(Bytes)
 
        Next
aber selbst so wird bei mir dieser Fehler ausgegeben



Beitrag wurde zuletzt am 02.12.15 um 11:31:08 editiert.

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: GPM
Datum: 02.12.15 11:57

System.Text.Encoding.Default.GetString(Bytes.ToArray))
MfG GPM
0
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: GPM
Datum: 02.12.15 12:25

Wenn 13,10 als Zeilenende verwendet wird und
myComPort.NewLine = Environment.NewLine ist,
sollte aber auch ReadLine funktionieren.

MfG GPM
0
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: Undertaker17
Datum: 03.12.15 13:19

Also, ich hab jetzt mittlerweile Einen Fortschritt gemacht:

    Private Sub myComPort_DataReceived(ByVal sender As Object, ByVal e As _
      System.IO.Ports.SerialDataReceivedEventArgs) Handles _
      myComPort.DataReceived
 
        Dim Bytes As New List(Of Byte)
        Dim b As Byte
        Do While myComPort.BytesToRead > 0
            b = CByte(myComPort.ReadByte)
 
            Me.Invoke(Sub() Bytes.Add(b))
            System.Text.Encoding.Default.GetString(Bytes.ToArray)
            'Me.Invoke(Sub() lblMeldungstext.Text &= "  " & b)
            'Me.Invoke(Sub() lblMeldungstext.Text &= Chr(b))
        Loop
        Dim n As Integer
 
        'For n = 0 To Bytes.Count - 1
        '    Debug.Print(Bytes(n))
        'Next
 
 
        Dim o As Integer
        For o = 0 To Bytes.Count - 1
            Me.Invoke(Sub() lblMeldungstext.Text &= _
              System.Text.Encoding.Default.GetString(Bytes.ToArray))
            Me.Invoke(Sub() txtÜbergang.Text &= Bytes.Item(o))
        Next
 
    End Sub
Ich erhalte nun im Debugmäßig angelegten Textfeld txtÜbergang einen ganzen Stapel an Bytes.

131049515849503248514653131049556513105545574832651310542758487328432453269105110119101105115117110103324284114111165131051511510511065131051031011103242876532465131052861051081081051101065131056513105310111032427510810511010510711511611446324946513105913100

Diese wiederrum habe ich ja dann versucht, in String umzuwandeln und im lblMeldungstext auszugeben.

Aber dort werden lediglich die ersten 3 Zeilen immer wiederholt.

13:15 03.12.2015
17 A
7-90 *KT
.
.
.
hier fehlen noch einige Zeilen

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: Undertaker17
Datum: 04.12.15 11:52

    Private Sub myComPort_DataReceived(ByVal sender As Object, ByVal e As _
      System.IO.Ports.SerialDataReceivedEventArgs) Handles _
      myComPort.DataReceived
 
        Dim Bytes As New List(Of Byte)
        Dim b As Byte
        Do While myComPort.BytesToRead > 0
            b = CByte(myComPort.ReadByte)
 
            Me.Invoke(Sub() Bytes.Add(b))
 
        Loop
 
        Dim o As Integer
        For o = 0 To Bytes.Count - 1
            Me.Invoke(Sub() txtMeldungÜbergang.Text &= _
              System.Text.Encoding.Default.GetString(Bytes.ToArray))
            Me.Invoke(Sub() txtÜbergang.Text &= Bytes.Item(o))
        Next
 
 
    End Sub
Aaalso so wird die gesamte meldung schonmal ausgegeben, allerdings wird sie immernoch schier unendlich wiederholt.

Kommt leute, Ich komm einfach nicht drauf, wie ich das unterbinden kann....

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: GPM
Datum: 04.12.15 13:54

Private Sub myComPort_DataReceived(sender As Object, e As _
  SerialDataReceivedEventArgs) Handles myComPort.DataReceived
 Dim blist As New List(Of Byte)
 Do While (myComPort.BytesToRead > 0)
   blist.Add(CByte(myComPort.ReadByte))
 Loop
 Me.Invoke(Sub() DecodeBytes(blist))
End Sub
 
Private Sub DecodeBytes(blist As List(Of Byte))
 txtMeldungÜbergang.Text &= System.Text.Encoding.Default.GetString( _
   blist.ToArray)
 For Each b In blist
  txtÜbergang.Text &= "|" & b
 Next
End Sub
MfG GPM
0
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: Undertaker17
Datum: 08.12.15 15:02

Naja Danke für die Antwort. Soweit funktioniert das wunderbar.

    Private Sub myComPort_DataReceived(ByVal sender As Object, ByVal e As  _
SerialDataReceivedEventArgs) Handles myComPort.DataReceived
        Dim blist As New List(Of Byte)
        Do While (myComPort.BytesToRead > 0)
            blist.Add(CByte(myComPort.ReadByte))
        Loop
        Me.Invoke(Sub() DecodeBytes(blist))
    End Sub
 
    Dim puffer as String
 
    Private Sub DecodeBytes(ByVal blist As List(Of Byte))
 
        puffer &= System.Text.Encoding.Default.GetString( _
          blist.ToArray)
    End Sub
Den Teil in der For Each- Schleife habe ich entfernt, ich wollte die Bytes nur "Debug-mäßig" sehen, ob sich was tut.

Nun wird ja der text in der Variablen puffer zusammengesetzt.

Wenn ich nun den Text auf einem Label anzeigen will, würde ich ja schreiben:

txtMeldung.Text = puffer
So wird aber immer wieder durch das &= bei DecodeBytes neuer Text hinzugefügt. Es soll ja immer nur der Aktuelle Text angezeigt werden, also muss ich wissen wann die Datenübertragung beendet ist.

Habs eben so probiert,:
    Dim endeerreicht As Boolean = False
    Dim Nachricht As String
 
    Private Sub myComPort_DataReceived(ByVal sender As Object, ByVal e As _
      System.IO.Ports.SerialDataReceivedEventArgs) Handles _
      myComPort.DataReceived
        Dim blist As New List(Of Byte)
        Do While (myComPort.BytesToRead > 0)
            blist.Add(CByte(myComPort.ReadByte))
 
        Loop
        endeerreicht = True
 
        Me.Invoke(Sub() DecodeBytes(blist))
 
 
 
    End Sub
 
    Private Sub DecodeBytes(ByVal blist As List(Of Byte))
        Nachricht &= System.Text.Encoding.Default.GetString(blist.ToArray)
        If endeerreicht = True Then
            txtMeldung.Text = Nachricht
            Nachricht = ""
            endeerreicht = False
        End If
 
    End Sub
und gestern auch schon durch verschieden Verschachtelte Do- While- Until Schleifen, aber ich hab dann entweder gar nichts, oder wieder nur Teilstrings.

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: GPM
Datum: 08.12.15 17:26

Bei Textübertragung wird halt am Ende ein Newline eingefügt
und die Zeile dann mit ReadLine ausgelesen. Die Einstellungen
- Beschreibungen sollten im Handbuch erklärt werden. Wenn nicht,
dann mit dem Support des Hardware-Hersteller abklären.
Bei meinen Arduinos werden die Texte mit Serial.println(txt)
als Text + NewLine-Zeichen gesendet. So bekommt man immer die
komplette Nachricht angezeigt.

MfG GPM
0
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: Undertaker17
Datum: 08.12.15 18:34

hm Okay ich formuliere es mal etwas anders:

 
    Dim Nachricht As String
 
Private Sub myComPort_DataReceived(ByVal sender As Object, ByVal e As _
  System.IO.Ports.SerialDataReceivedEventArgs) Handles myComPort.DataReceived
        Dim blist As New List(Of Byte)
        Do While (myComPort.BytesToRead > 0)
            blist.Add(CByte(myComPort.ReadByte))
        Loop
        Me.Invoke(Sub() DecodeBytes(blist))
    End Sub
 
    Private Sub DecodeBytes(ByVal blist As List(Of Byte))
        Nachricht &= System.Text.Encoding.Default.GetString(blist.ToArray)
    End Sub
So. Wenn jetzt das erste mal text eingeht, dann...

Nachricht = Dies ist eine Testmeldung

Wenn nun das 2. mal z.b.: die Selbe Meldung eingeht...

Nachricht = Dies ist eine Testmeldung Dies ist eine Testmeldung

usw...

Wenn ich aber jetzt z.b.:



    Dim endeerreicht As Boolean = False
    Dim Nachricht As String
 
 
        Private Sub myComPort_DataReceived(ByVal sender As Object, ByVal e As _
          System.IO.Ports.SerialDataReceivedEventArgs) Handles _
          myComPort.DataReceived
        Dim blist As New List(Of Byte)
        Do While (myComPort.BytesToRead > 0)
            blist.Add(CByte(myComPort.ReadByte))
            If myComPort.BytesToRead <= 0 Then endeerreicht = True
        Loop
 
        Me.Invoke(Sub() DecodeBytes(blist))
    End Sub
 
    Private Sub DecodeBytes(ByVal blist As List(Of Byte))
        Nachricht &= System.Text.Encoding.Default.GetString(blist.ToArray)
        If endeerreicht = True Then
            txtMeldung.Text = Nachricht
            Nachricht = ""
            endeerreicht = False
        End If
    End Sub
so wird wieder nur das letzte fragment, des zuvor zusammengesetzten textes ausgegeben:

Nachricht = stmeldung

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: Undertaker17
Datum: 10.12.15 20:50

Also ich hab das Problem jetzt folgendermaßen gelöst:

Ich hab ein 2tes programm geschrieben, welches mit einer modifizierten Version des Codes von GPM die Textfragmente empfängt, zusammensetzt, und in einer neu angelegten Datei Speichert.

Das Hauptprogramm fragt per Timer ab, ob diese Datei vorhanden ist. Falls nicht, passiert, wer hätts gedacht, NIX.
Falls doch, wird der text aus der Datei gelesen, auf dem Label ausgegeben, und die Übergabedatei anschließend gelöscht.

Beim eingang einer neuen Meldung geht das Spiel von vorne los.

Das ist mit Sicherheit nicht die feinste Art und Weise, und sicherlich auch keine Dauerlösung, (hätte schon gerne alles allin1), aber fürs erste müsste es wohl reichen.

Danke nochmal für eure hilfreichen Hinweise,

Frohe Weihnachtszeit und einen guten Rutsch.

Gruß Undertaker17

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: Undertaker17
Datum: 30.12.15 15:22

Also ich habs jetzt hinbekommen, dass es funktioniert so wie ich das will:

    Private Sub myComPort_DataReceived(ByVal sender As Object, ByVal e As _
      System.IO.Ports.SerialDataReceivedEventArgs) Handles _
      myComPort.DataReceived
        Debug.Print("DR ausgelöst")
        msg = myComPort.ReadLine
        Me.ShowText(msg)
 
    End Sub
 
    Private Sub ShowText(ByVal text As String)
        Debug.Print("ST ausgelöst")
        Dim Nachricht As String
        If lblMeldungstext.InvokeRequired Then
            Dim d As New TextBoxCallback(AddressOf ShowText)
            Me.Invoke(d, New Object() {text})
        Else
            Nachricht &= text
            lblMeldungstext.Text = Nachricht
        End If
 
    End Sub
Dass das Readline ohne Klammern da steht, ist so beabsichtigt, warum weiß ich allerdings nicht.

Was mir ebenfalls schleierhaft ist, ist wieso es jetzt SO funktioniert wie es soll...

Wenn die erste Meldung eingeht, bekomme ich im Direktfenster folgende ausgabe:


DR ausgelöst
ST ausgelöst
ST ausgelöst
DR ausgelöst
ST ausgelöst
ST ausgelöst
DR ausgelöst
ST ausgelöst
ST ausgelöst
DR ausgelöst
ST ausgelöst
ST ausgelöst
DR ausgelöst


Man beachte die erste und die Letzte Zeile.

Erst wird ganz normal das DataReceived ausgelöst.
Am ende aber wird, dieses Wieder ausgelöst, und dort wird dann nichts mehr an ShowText übergeben, also ist die "Befehlskette" ja mehr oder weniger Unvollständig ausgeführt.

Wenn nun die zweite meldung eingeht,

erhalte ich folgende ausgabe:


ST ausgelöst
ST ausgelöst
DR ausgelöst
ST ausgelöst
ST ausgelöst
DR ausgelöst
ST ausgelöst
ST ausgelöst
DR ausgelöst
ST ausgelöst
ST ausgelöst
DR ausgelöst


Nun wird zuerst das ShowText ausgeführt.

Letztendlich kanns mir ja egal sein wieso das so ist, da es ja jetzt Funktioniert. allerdings würde ich es gerne Verstehen...

Kanns mir jemand erklären??

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Teilweiser Empfang an Serialport zusammensetzen 
Autor: Manfred X
Datum: 31.12.15 13:22

Hallo!

Prüfe bereits im "DataReceived"-Eventhandler, ob ein "Invoke" des Meldungslabels
nötig ist und und führe dieses "Invoke" ggf. dort bereits durch
- nicht erst in der "ShowText"-Routine.

Schreibe die empfangenen Teil-Zeichenfolgen nicht direkt in das Label, sondern
baue den Text zunächst z.B. in einem Stringbuilder zusammen und nutze Databinding
für das Display.

Beitrag wurde zuletzt am 31.12.15 um 13:26:05 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel