ANSI einlesen via RS-232 und darstellen (vorher war es ein LCD-Display)

  • VB.NET

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    ANSI einlesen via RS-232 und darstellen (vorher war es ein LCD-Display)

    Hallo Zusammen,

    Hoffentlich kann mir jemand weiterhelfen.
    Via RS-232 Schnittstelle werden Texte versendet. Das Empfangen mit dem Serial-Port funktioniert auch.

    Werden die Texte mit einem Terminal (z.B RealTerm) dargestellt, so werden diese korrekt dargestellt sofern ''Display As Ansi" angewählt wird.

    Das einlesen im VB klappt leider nicht
    Folgende Einstellungen habe ich ich versucht, scheinen aber keine Unterschied zu machen.

    VB.NET-Quellcode

    1. 'SerialPort1.Encoding = System.Text.Encoding.GetEncoding(1252) '1252 = ANSI
    2. ''SerialPort1.Encoding = System.Text.Encoding.Default



    Folgendes wird empfangen und auch ausgegeben.
    [1;1f Ich bin Zeile 1
    [2;1f [?25l

    Gibt es eine Möglichkeit dies ohne Konvertierung auszugeben? RealTerm (RS-232 Terminal) scheint mit der ANSI-Einstellung ein VT-100 Protokoll zu unterstützen

    Schon mal besten Dank für Eure Rückmeldung(en)

    carepicha schrieb:

    keine Unterschied
    Du musst zunächst einmal bestimmen, ob da 8 Bit pro Zeichen oder 16 Bit pro Zeichen gesendet werden. Wenn das klar ist, sollten bestenfalls bei Sonderzeichen (ÄÖÜß) Übertragungsfehler kommen, da kannst Du die CodePage einstellen.
    Teste diesen Code unsd sieh Dir die 3 Flags an:

    VB.NET-Quellcode

    1. SerialPort1.Encoding = System.Text.Encoding.ASCII
    2. Dim flag1 = SerialPort1.Encoding.IsSingleByte
    3. SerialPort1.Encoding = System.Text.Encoding.GetEncoding(1252)
    4. Dim flag2 = SerialPort1.Encoding.IsSingleByte
    5. SerialPort1.Encoding = System.Text.Encoding.Unicode
    6. Dim flag3 = SerialPort1.Encoding.IsSingleByte

    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!
    Wenn ich den Port verbinde zeigt es an, dass es 8 Bit sind.

    Ich habe deinen Vorschlag ausgeführt. (Kein Encoding aktiv)
    Es sind Flag1 & Flag2 True ?? War dies so zu erwarten? Ergibt dass einen Sinn?

    Die Problematik scheint nicht nur die Sonderzeichen zu sein.
    Ich möchte nochmals auf das RealTerm (Terminal) zu sprechen kommen. (Daten werden anstatt auf VB-Programm an das Terminal gesandt)
    1. Mit Einstellung ASCII wird der Text vorlaufend im Textfeld dargestellt (immer wieder das gleiche, weil dieser auch zyklisch gesendet wird)
    2. Mit Einstellung ANSI wird der Text im Textfeld immer wieder überschrieben. (Text kann ändern und wird somit immer wieder 'refresht' )

    Mit dem VB- Programm ergibt sich verhalten 1, sollten aber Verhalten 2 haben.
    Im empfangenen Text scheint es also auch Steuerzeichen für die Ausgabe am Display zu haben. (Deshalb der Hinweis zum VT 100 Terminal)

    Besten Dank für Deine/Eure Bemühungen

    carepicha schrieb:

    Steuerzeichen
    Poste mal Deinen Code.
    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!
    Anbei mein Code.
    Es gibt ein (Test)SUB um den Code von einem Txt.File einzulesen. (Da die RS-232 Schnittstelle nicht mitgenommen werden kann....) Das Text-File wurde erstellt beim mitlesen auf der RS-232 Schnittstelle.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System
    2. Imports System.Threading
    3. Imports System.IO.Ports
    4. Imports System.ComponentModel
    5. Public Class btnToAsci
    6. Dim myPort As Array
    7. Delegate Sub SetTextCallBAck(ByVal [text] As String)
    8. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    9. Try
    10. myPort = IO.Ports.SerialPort.GetPortNames()
    11. cb_PORT.Items.AddRange(myPort)
    12. cb_PORT.SelectedIndex = 0
    13. cb_Baud.SelectedIndex = 0
    14. SerialPort1.PortName = cb_PORT.Text
    15. SerialPort1.BaudRate = cb_Baud.Text
    16. SerialPort1.DataBits = 8
    17. SerialPort1.Parity = Parity.Even
    18. SerialPort1.StopBits = StopBits.One
    19. 'SerialPort1.Encoding = System.Text.Encoding.GetEncoding(1252) '1252 = ANSI
    20. 'SerialPort1.Encoding = System.Text.Encoding.Default
    21. SerialPort1.Open()
    22. Catch ex As Exception
    23. MsgBox("Fehler im Load-Event")
    24. End Try
    25. End Sub
    26. Private Sub btn_init_Click(sender As Object, e As EventArgs) Handles btn_init.Click
    27. SerialPort1.Close()
    28. SerialPort1.PortName = cb_PORT.Text
    29. SerialPort1.BaudRate = cb_Baud.Text
    30. SerialPort1.Open()
    31. 'btn_init.Enabled = False
    32. End Sub
    33. Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
    34. Me.Invoke(Sub() ReceivedText(SerialPort1.ReadExisting()))
    35. End Sub
    36. Private Sub ReceivedText(ByVal [text] As String)
    37. rtb_Terminal.Text &= [text]
    38. End Sub
    39. Private Sub SerialPort1_ErrorReceived(sender As Object, e As SerialErrorReceivedEventArgs) Handles SerialPort1.ErrorReceived
    40. MsgBox("Ich die RS-232 hat einen Fehler erhalten (ERROR RECEIVED)")
    41. End Sub
    42. Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    43. If SerialPort1.IsOpen = True Then
    44. SerialPort1.Close()
    45. MsgBox("port geschlossen")
    46. End If
    47. End Sub
    48. Private Sub btn_txtlesen_Click(sender As Object, e As EventArgs) Handles btn_txtlesen.Click
    49. Dim FileReader As String
    50. Dim sArray As String
    51. FileReader = My.Computer.FileSystem.ReadAllText("C:\temp\captureANSI.txt")
    52. 'sArray = Split(rtb_readfromtxt.Text, vbCrLf)
    53. rtb_readfromtxt.Text = FileReader
    54. End Sub
    55. Private Sub btn_split_Click(sender As Object, e As EventArgs) Handles btn_split.Click
    56. Dim dataArray() As String
    57. dataArray = rtb_readfromtxt.Text.Split(Chr(27))
    58. Dim lines() = rtb_Terminal.Lines
    59. rtb_Terminal.Clear()
    60. For i = 0 To dataArray.Length - 1
    61. rtb_Terminal.Text &= dataArray(i) & vbNewLine
    62. Next
    63. SerialPort1.Encoding = System.Text.Encoding.ASCII
    64. Dim flag1 = SerialPort1.Encoding.IsSingleByte
    65. SerialPort1.Encoding = System.Text.Encoding.GetEncoding(1252)
    66. Dim flag2 = SerialPort1.Encoding.IsSingleByte
    67. SerialPort1.Encoding = System.Text.Encoding.Unicode
    68. Dim flag3 = SerialPort1.Encoding.IsSingleByte
    69. End Sub
    70. Dim iAscCode As Integer
    71. Dim sChar As String
    72. ' ASCII-Code in Zeichen umwandeln
    73. Private Sub btn_ToAnsi_Click(sender As Object, e As EventArgs) Handles btn_ToChar.Click
    74. sChar = Chr(tb_Eingabe.Text)
    75. lbl_Label1.Text = sChar
    76. End Sub
    77. Private Sub btn_ToAsci_Click(sender As Object, e As EventArgs) Handles btn_ToAsci.Click
    78. ' Zeichen in ASCII-Code umwandeln
    79. iAscCode = Asc(tb_Eingabe.Text)
    80. lbl_Label1.Text = iAscCode
    81. End Sub
    82. End Class

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

    Jetzt hast Du meinen Testcode in die btn_split_Click_Click() reingebaut und weißt gar nicht, was der Code da soll. Rauswerfen.
    Machst Du Option Strict On.Gib dem Port vor .Open() ein Encoding.
    Solange Du testest, trage die Port-Propertries fest in den Quelltext ein.
    Löse alle Probleme, und wenn sie gelöst sind, mach diese Properties variabel.
    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!
    1. VT100 Ansi hat nix mit Windows Ansi zu tun.
    2. VT100 kannte nur 7-Bit-Zeichen (Deswegen sollte es keine Rolle spielen ob du kein Encoding [= 7Bit] oder Encoding.Default [= CP1252 bei deutschem Windows] verwendest.

    Mit dem VB- Programm ergibt sich verhalten 1, sollten aber Verhalten 2 haben.


    Quellcode

    1. [1;1f Ich bin Zeile 1


    [1;1f oder genauer ESC[1;1f bedeutet Zeile 1;Spalte 1

    (ESC = CHR(27) oder Hex 1B)

    Also musst du nur die Escape-Codes auswerten und deine Ausgabe entsprechen anpassen. ^^

    carepicha schrieb:

    im Load-Event
    Raus damit.
    Nimm das Shown-Event.
    Und schmeiß endlich die paar Zeilen Testcode raus, die Du von mir übernommen hast. :rolleyes:
    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!

    Eierlein schrieb:

    1. VT100 Ansi hat nix mit Windows Ansi zu tun.
    2. VT100 kannte nur 7-Bit-Zeichen (Deswegen sollte es keine Rolle spielen ob du kein Encoding [= 7Bit] oder Encoding.Default [= CP1252 bei deutschem Windows] verwendest.

    Mit dem VB- Programm ergibt sich verhalten 1, sollten aber Verhalten 2 haben.

    Quellcode

    1. [1;1f Ich bin Zeile 1


    [1;1f oder genauer ESC[1;1f bedeutet Zeile 1;Spalte 1



    (ESC = CHR(27) oder Hex 1B)

    Also musst du nur die Escape-Codes auswerten und deine Ausgabe entsprechen anpassen. ^^


    Deshalb die Spielerei mit der Split Funktion

    VB.NET-Quellcode

    1. dataArray = rtb_readfromtxt.Text.Split(Chr(27))

    Aber ich war der Ansicht da es mit einem Terminal mit der ANSI-Einstellung korrekt darstellt (Zeilenumbrüche, Cursor aktiv/inaktiv) dies mit VB.NET auch ohne Anpassungen möglich sein könnte. Bin aber nach wie vor nicht schlüssig

    @ RodFromGermany
    Mit Shown (ich nehme an Form.Shown) ändert sich nichts. Gleiches Verhalten wie vorher. Was war der Sinn diesbezüglich?



    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „carepicha“ ()

    Escape-Sequenzen bestehen nicht nur aus dem ESC-Zeichen.
    Wenn du's ganz korrekt machen willst, musst du dir einen VT100-Emulator schreiben.
    Edit: Oder eine fertige DLL zu Hilfe nehmen: sourceforge.net/projects/vt100net/

    Wenn du nur die Nutzdaten ausfiltern willst, dann kannst du die Sequenzen einfach wegwerfen.
    Stark vereinfachte Regel:
    Eine Sequenz besteht aus ESC und einem weiteren Zeichen.
    Wenn dieses weitere Zeichen eine Nummer oder ein [ ist, dann endet die Sequenz erst beim nächsten Buchstaben (A-Za-z) (incl.).
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „petaod“ ()

    carepicha schrieb:

    Was war der Sinn diesbezüglich?
    Falls in der Form_Load gewisse (nicht alle) Exceptions auftreten, wird der folgende Code nicht ausgeführt, aber das Programm startet "normal" weiter.
    ----
    Wo Du unbedingt drauf achten solltest:
    Es gibt Encodings, die übertragen nur 7 Bit (ASCII, UTF7), die solltest Du nicht verwenden. Mit UTF8 sollte Deine Kommunikation eigentlich funktionieren.
    Steuerzeichen (0 bis 31) sind von CodePage / Encoding nicht betroffen.
    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!
    Danke für Eure Hilfestellung. Hatte gehofft es sei ein Standard. Dem scheint aber nicht so.....
    Es wird wohl eine DLL oder irgend etwas in derart benötigen. In der Applikation sind auch benutzerdefinierte Zeichen verwendet worden.
    Benutzerdefinierte Zeichen sind im Bereich > 128 .....:-(
    Du musst vor allem unterscheiden zwischen deinen beiden Problemen:
    - Ausfiltern der Escape-Sequenzen
    - Richtige Darstellung des Nutztextes

    carepicha schrieb:

    Es wird wohl eine DLL oder irgend etwas in derart benötigen
    Sehe ich nicht so.
    Die Escape-Sequenzen kannst du blind ausfiltern und den Rest mit der richtigen Codepage darstellen.

    Aber mach, wie du willst.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    carepicha schrieb:

    Benutzerdefinierte Zeichen
    Werden 1 oder 2 Byte per Zeichen übertragen?
    Danach das Encoding zumindest eingrenzen.
    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!