serieller Scan geht nur einmal

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

Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von Axxxxxl.

    serieller Scan geht nur einmal

    Hallo,

    ich habe mir unter Zuhilfenahme eines freien VB Projektes ein kleines Programm geschrieben, welches mir die COM1 Schnittstelle öffnet an der ein Barcodescanner (Datalogic) angeschlossen ist. Beim ersten Scan wird auch ohne Fehler die Daten des Barcodes (in diesem Fall eine 8-stellige Nummer) eingelesen und in meinem Label angezeigt.
    Scanne ich aber nun den nächsten Barcode, scheint dies zwar zu funktionieren aber es werden keine Daten mehr angezeigt. Wenn ich dann weitere Codes scanne (alle die gleiche Sorte) werden manchmal ein paar Zahlen daraus angezeigt, manchmal gar nichts. Erst wenn ich das Programm ganz neu starte, geht es wieder einmal.

    Vielleicht findet da jemand von euch einen Fehler?! Die Einstellungen der COM Schnittstelle sind definitiv richtig, da wir dieses auch an unseren Maschinen nutzen, wo die Scanner eigentlich in Betrieb sind und dort die gleichen Codes lesen.

    Hier der komplette Code:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class frm_main
    2. ' Das Delegat muss die selbe Signature haben
    3. Delegate Sub TextBoxCallback(ByVal text As String)
    4. Private WithEvents myComPort As IO.Ports.SerialPort
    5. ' Bei den meisten Geräten ist ein Abschlußzeichen erforderlich, meistens
    6. ' wird ChrW(13) oder ChrW(10) oder beide benötigt
    7. ' - Wählt was eure Gegenstelle benötigt:
    8. ' Private EndOfCommand As String = Constants.vbCr.ToString
    9. ' Private EndOfCommand As String = Constants.vbLf.ToString
    10. Private EndOfCommand As String = Constants.vbCrLf.ToString
    11. Private Sub frm_main_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    12. 'COM Port beim Beenden schließen
    13. myComPort.Close()
    14. End Sub
    15. Private Sub Form1_Load(ByVal sender As System.Object, _
    16. ByVal e As System.EventArgs) Handles MyBase.Load
    17. 'Initialisierung der COM Schnittstelle (in Klammern = gewünschter COM Port)
    18. opencom(0)
    19. End Sub
    20. Private Sub opencom(ByVal comport As Integer)
    21. ' Mal nachschauen, ob es hier SerialPorts gibt
    22. Dim str() As String = IO.Ports.SerialPort.GetPortNames()
    23. 'gefundene COM Ports anzeigen
    24. Dim port As String
    25. Dim gesamtport As String
    26. For Each port In str
    27. gesamtport = port
    28. Next port
    29. 'Anzeige öffnen
    30. 'MessageBox.Show("gefundene COM Ports: " & gesamtport, "Info", MessageBoxButtons.OK, MessageBoxIcon.Information)
    31. ' Wenn nein, dann beenden:
    32. If str.Length = 0 Then
    33. MessageBox.Show("Es wurden keine COM Ports gefunden!", "kein COM Port gefunden", MessageBoxButtons.OK, MessageBoxIcon.Information)
    34. slbl_status.Text = "keine COM Ports verfügbar!"
    35. End If
    36. ' Eine Instance von SerialPort erstellen
    37. ' Im Normalfall ist das COM1:
    38. myComPort = New IO.Ports.SerialPort(str(0))
    39. slbl_port.Text = "COM 1"
    40. 'Einstellungen der seriellen Schnittstelle setzen
    41. ' Die folgenden vier Einstellungen müssen denen der
    42. ' Gegenstelle entsprechen
    43. myComPort.BaudRate = 9600
    44. myComPort.DataBits = 8
    45. myComPort.StopBits = IO.Ports.StopBits.One
    46. myComPort.Parity = IO.Ports.Parity.None
    47. ' Wichtig! Hier wird eingestellt nach wieviel Bytes im Eingangspuffer
    48. ' das DataReceived Event gefeuert wird
    49. myComPort.ReceivedBytesThreshold = 1
    50. ' COM Port öffnen
    51. myComPort.Open()
    52. End Sub
    53. ' Wird ausgelöst wenn die Comm die in ReceivedBytesThreshold eingestellte Anzahl Bytes empfangen hat
    54. Private Sub myComPort_DataReceived( _
    55. ByVal sender As Object, _
    56. ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
    57. Handles myComPort.DataReceived
    58. Select Case e.EventType
    59. Case IO.Ports.SerialData.Chars
    60. ' Ein Zeichen wurde empfangen und im Eingabepuffer platziert.
    61. Case IO.Ports.SerialData.Eof
    62. ' Das Dateiendezeichen wurde empfangen und im
    63. ' Eingabepuffer platziert.
    64. End Select
    65. slbl_status.Text = "es wurden Daten empfangen..."
    66. Dim msg As String = myComPort.ReadExisting
    67. ShowText(msg)
    68. myComPort.DiscardOutBuffer()
    69. End Sub
    70. ' Wird ausgelöst wenn sich die Steuerleitungen geändert haben
    71. Private Sub myComPort_PinChanged(ByVal sender As Object, ByVal e As _
    72. System.IO.Ports.SerialPinChangedEventArgs) Handles myComPort.PinChanged
    73. Select Case e.EventType
    74. Case IO.Ports.SerialPinChange.Break
    75. ' Bei der Eingabe wurde ein "break" erkannt.
    76. Case IO.Ports.SerialPinChange.CDChanged
    77. ' Der Zustand des CD-Signals (Carrier Detect) hat sich geändert.
    78. ' Mit diesem Signal wird angezeigt, ob ein Modem mit einer
    79. ' Telefonleitung verbunden ist und ein Datenträgersignal
    80. ' erkannt wurde.
    81. Case IO.Ports.SerialPinChange.CtsChanged
    82. ' Der Zustand des CTS-Signals (Clear to Send) hat sich geändert.
    83. ' Mit diesem Signal wird angegeben, ob Daten über den seriellen
    84. ' Anschluss gesendet werden können.
    85. Case IO.Ports.SerialPinChange.DsrChanged
    86. ' Zustand des DSR-Signals (Data Set Ready) hat sich geändert.
    87. ' Mit diesem Signal wird angezeigt, ob das Gerät am seriellen
    88. ' Anschluss betriebsbereit ist.
    89. Case IO.Ports.SerialPinChange.Ring
    90. 'Ein Ringindikator wurde erkannt.
    91. End Select
    92. End Sub
    93. ''' Wird ausgelöst wenn ein Fehler in der Übertragung endeckt wurde
    94. Private Sub myComPort_ErrorReceived( _
    95. ByVal sender As Object, _
    96. ByVal e As System.IO.Ports.SerialErrorReceivedEventArgs) _
    97. Handles myComPort.ErrorReceived
    98. Select Case e.EventType
    99. Case IO.Ports.SerialError.Frame
    100. ' Die Hardware hat einen Rahmenfehler erkannt.
    101. slbl_status.Text = "Fehler: Rahmenfehler Hardware!"
    102. Case IO.Ports.SerialError.Overrun
    103. ' Ein Zeichenpufferüberlauf ist aufgetreten. Das nächste
    104. ' Zeichen geht verloren.
    105. slbl_status.Text = "Fehler: Überlauf, nächstes Zeichen geht verloren!"
    106. Case IO.Ports.SerialError.RXOver
    107. ' Ein Eingabepufferüberlauf ist aufgetreten.
    108. ' Die Kapazität des Eingabepuffers ist erschöpft,
    109. ' oder es wurde ein Zeichen nach dem Dateiendezeichen
    110. ' (EOF, end-of-file) empfangen.
    111. slbl_status.Text = "Fehler: Eingabepufferüberlauf!"
    112. Case IO.Ports.SerialError.RXParity
    113. ' Die Hardware hat einen Paritätsfehler erkannt.
    114. slbl_status.Text = "Fehler: Paritätsfehler!"
    115. Case IO.Ports.SerialError.TXFull
    116. ' Die Anwendung hat versucht, ein Zeichen zu übertragen, aber
    117. ' die Kapazität des Ausgabepuffers war erschöpft.
    118. slbl_status.Text = "Fehler: Kapazität Ausgabepuffer erschöpft!"
    119. End Select
    120. 'Im Textfeld anzeigen dass es einen Fehler gab
    121. ShowText("Fehler")
    122. End Sub
    123. ' Da die Daten aus einem anderem Thread kommen müssen wir die Ausgabe über Invoke machen
    124. Private Sub ShowText(ByVal text As String)
    125. If lbl_data.InvokeRequired Then
    126. Dim d As New TextBoxCallback(AddressOf ShowText)
    127. Invoke(d, New Object() {text})
    128. Else
    129. 'alten Text löschen
    130. lbl_data.Text = ""
    131. 'empfangenen Text in Textbox schreiben
    132. lbl_data.Text = text
    133. End If
    134. End Sub
    135. ' Hier wird der Command zusammengesetzt und versendet
    136. Private Sub Send(ByVal command As String)
    137. Me.myComPort.Write(command & Me.EndOfCommand)
    138. End Sub
    139. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_exit.Click
    140. 'Me.Send("Ein Befehl, den die Gegenstelle kennt!")
    141. Application.Exit()
    142. End Sub
    143. Private Sub BeendenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles BeendenToolStripMenuItem.Click
    144. Application.Exit()
    145. End Sub
    146. Private Sub btn_exit_Click(sender As Object, e As EventArgs) Handles btn_exit.Click
    147. Application.Exit()
    148. End Sub
    149. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    150. 'Label löschen
    151. lbl_data.Text = ""
    152. End Sub
    153. End Class
    ==> seid .net zueinander :D <3 <==

    Axxxxxl schrieb:

    VB.NET-Quellcode

    1. myComPort.DiscardOutBuffer()
    Nimm mal diese Zeile aus myComPort_DataReceived() raus.
    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!
    Leider keine Änderung. Die Zeile hatte ich auch erst später aus einem anderen Tipp hinzugefügt, die war im org. Projekt nicht enthalten.

    Ich habe jetzt mal getestet.

    - der Barcode der gescannt wird, enthält die Zeichen: "M1255:A2:SU" # CLRF (schickt also den Zeilenvorschub gleich mit)
    - beim ersten Scan wird auch "M1255:A2:SU" ohne Fehler in die Textbox geschrieben
    - ich lasse mir nun vor dem Schreiben in die Textbox eine Messagebox anzeigen in der ich sehe, was vom Scanner kommt
    - ab dem 2 Scan kommt dann zunächst ein "M" einzeln und dann hinterher "1255:A2:SU"
    - warte ich nun eine bestimmte Zeit vor dem nächsten Scan, wird dieser dann auch wieder fehlerfrei als "M1255:A2:SU" angezeigt.

    Kann es evtl. was damit zu tun haben?:

    VB.NET-Quellcode

    1. ' Wichtig! Hier wird eingestellt nach wieviel Bytes im Eingangspuffer
    2. ' das DataReceived Event gefeuert wird
    3. myComPort.ReceivedBytesThreshold = 1




    ==> seid .net zueinander :D <3 <==

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