Anzeigeproblem mit SerialPort

  • VB.NET

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

    Anzeigeproblem mit SerialPort

    Eingesetzt wird : Visual Studio 2019

    Hallo,

    ich brauche wieder eure Hilfe. Ich muss noch ältere Geräte über einen SerialPort ansteuern. Die eigentliche SerialPort-Programmierung (Senden/Empfangen) wird im Hintergrund in einem Windows-Frame >FrmSetup< ausgeführt.
    Es funktioniert auch alles sehr gut, die Daten werden korrekt gesendet und im Empfangsbereich kommen die Rückmeldedaten auch korrekt an, dies sehe ich mit einem Debug.Print Befehl. Nun will ich die empfangenen Daten in einem Forms.Label auf dem Windows-Frame >UserForm< anzeigen lassen, funktioniert aber nicht, die Daten werden nicht angezeigt. Ich habe dies auch schon mit einer Text-Box probiert, auch ohne Erfolg. Selbst wenn ich einfach nur >>XXX<< aus dem Sub "DataReceived" anzeigen will, ebenfalls kein Erfolg.
    Ich kann mir das nur so erklären, dass aus dem "DataReceived" keine Daten in ein anders Frame übertragen werden kann.
    Hier mein Quellcode für den Empfang.

    VB.NET-Quellcode

    1. '********************************************************************
    2. '* >> Input 2 << Eingang der Daten von CPort2 | 18.09.2019 *
    3. '********************************************************************
    4. Sub CPort2_DataReceived(sender As System.Object, e As System.IO.Ports.SerialDataReceivedEventArgs) Handles CPort2.DataReceived
    5. Dim msg As String = Me.CPort2.ReadExisting
    6. msg = msg.Replace(Chr(6), "<ACK>") '* filtern ACK
    7. msg = msg.Replace(Chr(21), "<NAK>") '* filtern NAK
    8. UserForm.LB_UMC.Text = msg '* <<<<< Problem- wird nicht angezeigt
    9. Debug.Print("MSG = " & msg) '* Korrekte Empfangsdaten werden angezeigt
    10. End Sub


    Hab ihr eine Lösung für mein Problem?

    Zusatz: Beim öffnen und schließen der Verbindung kann ich >Offline< bzw. >Online< ohne Probleme in das Forms.Label schreiben.

    VB.NET-Quellcode

    1. Sub Status_Port2()
    2. Try
    3. If Me.CPort2.IsOpen = True Then
    4. Me.CPort2.Close()
    5. UserForm.BT_UmcOnOff.BackColor = Color.Red
    6. UserForm.LB_UMC.Text = "Offline" '* Wird korrekt angezeigt
    7. Exit Sub
    8. End If
    9. If Me.CPort2.IsOpen = False Then
    10. Me.CPort2.Open()
    11. UserForm.BT_UmcOnOff.BackColor = Color.Green
    12. UserForm.LB_UMC.Text = "Online" '* Wird korrekt angezeigt
    13. End If
    14. Catch ex As Exception
    15. Call FrmMeldungen.TryError("FrmSetup.Status_Port", ex.Message, 1)
    16. End Try
    17. End Sub


    Danke für Eure Hilfe
    Hubertus
    @Hubertus Das SerialPort arbeitet nicht im GUI-Thread.
    Bekommst Du eine Exception, dass Du auf die GUI aus einem anderen Thread heraus aufrufst?
    Du musst die Bedienung der GUI in den GUI-Threead invoken:

    VB.NET-Quellcode

    1. Private Sub SerialPort1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
    2. Dim txt = SerialPort1.ReadExisting()
    3. Me.Invoke(Sub() Me.Label1.Text = txt)
    4. End Sub
    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!
    Hallo,
    vielen Dank für deine Antwort. Wie du auf dem beigefügten Quellcode sehen kannst, habe ich schon viele Programm Varianten probiert. Im CPort1 ist ein Versuch, der kein Exception ausgegeben hat, aber auch keine Anzeige auf dem UserForm Label.
    Im jetzigen Versuch CPort2 wurde mir nun eine Exception angezeigt.

    System.InvalidOperationException: "Invoke oder BeginInvoke kann für ein Steuerelement erst aufgerufen werden, wenn das Fensterhandle erstellt wurde."

    VB.NET-Quellcode

    1. '********************************************************************
    2. '* >> Input 1 << Eingang der Daten von CPort1 | 18.09.2019 *
    3. '********************************************************************
    4. Private Sub CPort1_DataReceived(sender As System.Object, e As System.IO.Ports.SerialDataReceivedEventArgs) Handles CPort1.DataReceived
    5. ReceivedText1(CPort1.ReadExisting())
    6. End Sub
    7. Private Sub ReceivedText1(ByVal [text] As String)
    8. If UserForm.LB_ISEL.InvokeRequired Then
    9. Dim x As New SetTextCallback(AddressOf ReceivedText1)
    10. Me.Invoke(x, New Object() {(text)})
    11. Else
    12. UserForm.LB_ISEL.Text = [text]
    13. End If
    14. End Sub
    15. '********************************************************************
    16. '* >> Input 2 << Eingang der Daten von CPort2 | 18.09.2019 *
    17. '********************************************************************
    18. Sub CPort2_DataReceived(sender As System.Object, e As System.IO.Ports.SerialDataReceivedEventArgs) Handles CPort2.DataReceived
    19. Dim msg2 As String = Me.CPort2.ReadExisting '* Empfangsdaten in String msg2 schreiben
    20. msg2 = msg2.Replace(Chr(6), "<ACK>") '* ACK filtern
    21. msg2 = msg2.Replace(Chr(21), "<NAK>") '* NAK filtern
    22. Me.Invoke(Sub() UserForm.LB_UMC.Text = msg2) '* Empfangsdaten in Label-Box anzeigen
    23. Debug.Print("MSG = " & msg2)
    24. End Sub


    Danke
    Hubertus
    @Hubertus Das ist eine andersartige Exception, da greifst Du auf ein unfertiges Fenster zu.
    In welchem Ablauf liegt dieser Code?
    ==========
    Mach doch zunächst alles im Hauptfenster.
    Wenn das läuft, kannst Du anfangen, den Code zu dezentralisieren.
    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!
    Hallo,

    das eigentliche Hauptprogramm ist die UserForm. Dieses Programm ist sehr umfangreich, von ihm werden Funktionen in anderen Windows-Forms aufgerufen. Eines dieser anderen Windows-Form ist >> FrmSetup << In dieser Form sind alle SerialPort Funktionen eingebunden und programmiert.
    Aufgerufen werden diese Funktionen zB. senden : Call FrmSetup.Senden1(>Daten<, >Port<")
    Dies funktioniert ja auch alles ohne Probleme. Was ich nicht nachvollziehen kann ist, ich kann von jeder Windows-Form (siehe meinen Beitrag 1) den Text-Eintrag für UserForm,LB_xxx.text ändern.
    Es gibt ja viele Beispiele im Internet, aber alle beziehen sich aber auf die selbe Windows-Form, in dem auch die SerialPort-Funktionen laufen.
    Fragen Fragen Fragen

    Danke und Gruß
    Hubertus

    Hubertus schrieb:

    ich kann von jeder Windows-Form (siehe meinen Beitrag 1) den Text-Eintrag für UserForm,LB_xxx.text ändern.
    Mit welchem Code machst Du das?
    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!
    @Hubertus Das hatte ich befürchtet.
    Das ist inkompatibler mist sch.... VB6-Ranz.
    Verstehe diesen Thread:
    Dialoge: Instanziierung von Forms und Aufruf von Dialogen
    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!
    Hallo,

    ich weiß, dass noch viel VB6 in meiner Programmierung enthalten ist. Trotzdem habe ich das Problem jetzt gelöst.
    Mit dem Aufruf der Serial-Kommunikation starte ich auch die FrmSetup mit >>.show<< und lege sie in die Task. So ist sie aktiv und ich kann jetzt die Antwort in das Label auf der UserForm schreiben.
    Mir ist klar, dass dies nicht normal ist, aber es funktioniert.

    Danke für deine Unterstützung.
    Gruß
    Hubertus

    Hubertus schrieb:

    aber es funktioniert
    Wenn Du nicht sofort beginnst, "ordentlich" zu programmieren, wirst Du wegen jedem ähnlichen Problem hier im Forum nachfragen, und das wird auch Dir keinen Spaß machen.
    Sorry.
    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!
    Hallo RodFromGermany,

    du hast natürlich Recht. Ich versuche schon immer mehr die "neuen" Möglichkeiten zu nutzen. Es soll keine Ausrede sein, aber es ist auch eine Zeitfrage, sich alle neuen Möglichkeiten als Hobby-Programmierer anzueignen. Ich habe mir das Programmieren selbst beigebracht und bin deshalb noch sehr mit VB6 behaftet. Vieles habe ich schon umlernen müssen und der Lernprozess geht immer weiter. Gerade dieses Problem, was ich jetzt provisorisch gelöst habe, werde ich nach und nach in eine "ordentliche" Programmierung ändern.
    Deshalb bin ich auch euch Spezialisten sehr dankbar für eure Unterstützung.

    Gruß
    Hubertus

    Hubertus schrieb:

    aber es ist auch eine Zeitfrage
    Möglicherweise greifst Du, wenn Du falsch auf Forms zugreifst, auf mehrere disjunkte Instanzen derselben Form zu, und da hast Du Datenmüll und kannst ihn nicht aufdröseln. :/
    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!