Serialport Stream

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 72 Antworten in diesem Thema. Der letzte Beitrag () ist von Haudruferzappeltnoch.

    Serialport Stream

    Hallo,

    hab gesehen ein SerialPort hat eine BaseStream-Eigenschaft, jetzt hört sich das für mich so an als würden da die 0en und 1en drin stehen, die so ein SerialPort empfängt.
    Wie kann man da reingucken? Die Eigenschaft ist ein Stream, im Tutorial zu Streams steht man kann nur mit davon abgeleiteten Klassen arbeiten.
    Sammeln sich dadrin die Daten oder wann wird der aktualisiert?

    Viele Grüße

    Haudruferzappeltnoch schrieb:

    im Tutorial zu Streams steht man kann nur mit davon abgeleiteten Klassen arbeiten.
    So isses.
    Kopiere den Inhalt in einen MemoryStream, den kannst Du als Byte-Array ablegen.
    docs.microsoft.com/de-de/dotne…memorystream?view=net-6.0
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Langsam. Das ist zwar ne Property vom Typ Stream, gibt aber bei Aufruf die Innerei internalSerialStream wieder. Und die ist vom Typ SerialStream, die von Stream abgeleitet ist. Also keine Zauberei.
    Rauszufinden durch Drücken von F12, wenn man im CodeEditor auf der SerialPort-BaseStream-Eingenschaft ist. Alternativ Rechtsklick -> Gehe zu Definition. Da kann man dann immer weitergehen, siehe Anhang
    Bilder
    • Bild 1.png

      12,37 kB, 560×179, 95 mal angesehen
    • Bild 2.png

      16,73 kB, 724×524, 93 mal angesehen
    • Bild 3.png

      1,35 kB, 320×44, 93 mal angesehen
    • Bild 4.png

      4,77 kB, 610×154, 93 mal angesehen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    A shot into the blue (ungetestet, da ich keine Prüfmöglichkeit vor Ort hab): StreamReader nutzen

    VB.NET-Quellcode

    1. Using StreamReader As New IO.StreamReader(SerialPort1.BaseStream)
    2. Dim DeineBytes = StreamReader.ReadToEnd()
    3. End Using

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Haudruferzappeltnoch schrieb:

    Wie kopiere ich denn den Inhalt?
    Stream.CopyTo()
    docs.microsoft.com/de-de/dotne…-copyto(system-io-stream)
    Du musst Dir mal im ObjectBrowser oder in den Docs ansehen, was da alles für Methoden zur Verfügung stehen.
    Da findest Du gewiss ohne das Forum die passende.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Haudruferzappeltnoch schrieb:

    Ich weiß nicht wann da ein Bit kommt, aber angenommen es kommt nichts. Sollte ich da dann ein Resultat bekommen?


    Ja und auch nein, hast du das Event SerialPort.DataReceived abboniert, wirds gefeuert solltest du was einlesen können. Fragst du selbst turnusmäßig nach anstatt das Event zu feiern:

    VB.NET-Quellcode

    1. if serial.BytesToRead > 0 then

    hast du zumindest ein Resultat, also insofern, das du weisst ob was zu lesen da ist oder nicht.
    Weiss nicht was du machst.
    So einfach ist es:

    VB.NET-Quellcode

    1. Imports System.IO.Ports
    2. Public Class Form1
    3. Private WithEvents serial As New SerialPort
    4. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    5. serial.PortName = "COM1"
    6. serial.BaudRate = 9600
    7. Try
    8. serial.Open()
    9. Catch ex As System.IO.IOException
    10. End Try
    11. End Sub
    12. Private Sub serial_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles serial.DataReceived
    13. Debug.WriteLine(serial.BytesToRead())
    14. Debug.WriteLine(serial.ReadExisting())
    15. End Sub
    16. End Class

    Das war die einfachste art, ich mach sowas auch mit Threads(+loop) und prüfe selber ob Daten da sind und arbeite mit Byte, der SerialPort Basestream ist nicht relevant für uns. Schau dir im Objectbrowser mal die SerialPort Klasse an

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Takafusa“ ()

    @Haudruferzappeltnoch Welche Veranlassung hast Du, mit dem Portr-Stream zu arbeiten?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Eine gute Übguns für sowas wäre TCP kommunikation. Fängste an Strings zu schreiben, sowas wie ein TCP-Chat, StreamReader/Writer, dann probierste mal den BinaryReader und BinaryWriter, schreibt mal zahlen hin und her, wenn du dir die Binary/reader+writer klassen anschaust, siehst du wie du direkt Integers, Short usw, lesen /schreiben kannst, dann kannste auch mal Bytes senden und auswerten, also z.B. aus 4 Bytes selbst einen Integer machen(BitConverter).

    Beim basestream von SP wirste keine spaß haben. Such mal hier nach TCP Chats, da gab es hier doch was.
    Ja das habe ich schon festgestellt. Aber Verständnis kommt bei mir da nicht auf. Deswegen sehr wackelig

    Habe zum Beispiel das hier, das funktioniert:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    2. If Not Port1.IsOpen Then
    3. Port1.PortName = "COM1" ''cmbPort.SelectedItem.ToString
    4. Port1.BaudRate = 115200
    5. Port1.DataBits = 8
    6. Port1.Parity = IO.Ports.Parity.None
    7. Port1.StopBits = IO.Ports.StopBits.One
    8. Port1.DtrEnable = True
    9. Port1.RtsEnable = True
    10. Port1.Handshake = IO.Ports.Handshake.None
    11. Port1.Open()
    12. End If
    13. End Sub
    14. Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
    15. If Port1.IsOpen Then Port1.Close()
    16. End Sub
    17. Private Sub SerialPort1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles Port1.DataReceived
    18. If Port1.IsOpen Then
    19. Dim p As Integer
    20. System.Threading.Thread.Sleep(100) ''Wenn ich das nicht habe, kommt es manchmal durcheinander
    21. Me.Invoke(Sub() p = Port1.BytesToRead)
    22. Dim COMBuffer() As Byte = New Byte(p - 1) {}
    23. Port1.Read(COMBuffer, 0, p)
    24. Me.Invoke(Sub() Read_Message(COMBuffer))
    25. End If
    26. End Sub
    27. Private Sub Read_Message(COMB As Byte()) ''Ist die Frage ist diese COMB noch das Original oder was ist da schon alles mit passiert?
    28. Dim enc As New System.Text.ASCIIEncoding()
    29. Dim str As String = enc.GetString(COMB)
    30. txtBarcode.Text = str
    31. End Sub


    Wollte auch mal ohne DataReceived schauen, weil da läuft ja schon einiges. Und dann auch mal die Bits anschauen, ich weiß nicht was das StopBit ist, oder die Baudrate, oder der Handshake oder oder oder

    Haudruferzappeltnoch schrieb:

    ich weiß nicht was das StopBit ist, oder die Baudrate, oder der Handshake oder oder oder
    Wichtiger ist die port.NewLine-Property, die gibt die Zeilenende-Zeichen vor, dann kannst Du im DataReceived-Event mit .ReadLine arbeiten.
    docs.microsoft.com/de-de/dotne…?view=dotnet-plat-ext-6.0
    Dazu musst Du nur die Beschreibung des Dagtentransferprotokolls der Gegenstelle lesen.
    Oder beide Seiten programmieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ok wenn BytesToRead > 0 und ReadExisting gibt mir den String aus. Ist ein Zeichen ein Byte? So kams bei mir jetzt zumindest hin.
    Bisher alles ohne DataReceived-Event.

    Aber was ist mit den anderer Methoden Read ReadToEnd. Was muss ich bei denen machen damit sie funktionieren?
    Liegt das am Zeilenende-Zeichen?
    Wird in den BaseStream nur etwas gefüllt, wenn ein Zeilenende erkannt wird?

    Das Zeilenende läuft doch bestimmt selbst auch in den BaseStream?

    Haudruferzappeltnoch schrieb:

    Ist ein Zeichen ein Byte?
    Jein. :thumbsup:
    Du kannst das SerialPort einmal betreiben zur Übertragung von Strings. Da sind die Zeichen Chars entsprechend des eingestellten Encodings.
    Die Lese- und Schreib-Befehle arbeiten mit Strings, gesendet werden sie entsprechend des eingestellten Encodings.
    Andererseits kannst Du das SerialPort betreiben zur Übertragung von Byte-Arrays, dann sind die behandelten Zeichen Bytes.
    Auf der Leitung selbst (die kannst Du mit einem Sniffer-Tool überwachen) liegen nur Bytes, die eben von Sender und Empfänger entsprechend des Protokolle interpretiert werden.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!