Wert aus Textbox in Variable und Variable an ComPort senden

  • VB.NET

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

    Wert aus Textbox in Variable und Variable an ComPort senden

    Hallo zusammen, ich bin neu im Forum und hätte direkt mal eine Frage..

    Ich bekomme von einer SPS Daten per RS232-Schnittstelle gesendet, welche in einer Richtextbox dargestellt werden, als hexadezimal.
    Die Daten werden so eingelesen: "A1-FF-0B-D3" (als Beispiel).

    Ich hab es so eingestellt dass das "-" Zeichen eine neue Zeile auslöst, und nicht mit angezeigt wird.

    Jetzt möchte ich den Wert der zweiten Zeile zurück an den Port schicken, aber nicht einzeln sondern innerhalb einer Zeichenfolge.

    Ich hab also folgendes versucht: Den Wert aus Zeile 2 der RichTextBox in die Variable "eintest" schreiben, und diesen bei einem ButtonClick an den Port senden mit folgendem Code:
    In Public Class Form1:

    VB.NET-Quellcode

    1. Dim eintest As Integer
    (as Byte und String ebenfalls probiert)

    Im DataReceived des Com Ports:

    VB.NET-Quellcode

    1. If ausgabe.Text.Length > 3 Then ausgabe.Lines(2) = eintest 'wenn die Zweite Zeile einen Wert hat (.Length > 3) -> zweite Zeile in die Variable "eintest" schreiben


    Der Button:

    VB.NET-Quellcode

    1. Dim antwort() As Byte = {&H04, &HDF, eintest, &HFF}
    2. If antwort.TextLength > 0 Then SerialPort1.Write(antwort, 0, 4) 'Die Variable, die den Wert aus Textbox Zeile 2 haben soll, innerhalb der Zeichenfolge die gesendet werden soll und wird nur gesendet wenn die antwort-TextBox > 0 ist, damit ich weiß dass die Variable nicht leer ist


    So, nun endlich zum Problem: mit dem o.g. Code wird immer "00" gesendet, auch wenn Zeile 2 der TextBox z.B A1 ist.

    Testweise habe ich den Wert der Variable in einen Label schreiben lassen: Es ist immer "0". Zudem frage ich mich, ob mit diesem Code z.B. ein "A1" der Textbox / in der Variable dann auch als hexadezimales Zeichen gesendet wird, bzw. wie ich dies bewirken kann ("&H" anhängen!?).

    Kann jemand helfen?

    PS: Ich mach das mit Framework 3.5 damit es bestenfalls auch unter Win XP funktioniert...

    Danke schon mal

    escape schrieb:

    Der Button:
    VB.NET-Quellcode

    Dim antwort() As Byte = {&H04, &HDF, eintest, &HFF}
    If antwort.TextLength > 0 Then SerialPort1.Write(antwort, 0, 4) 'Die Variable, die den Wert aus Textbox Zeile 2 haben soll, innerhalb der Zeichenfolge die gesendet werden soll und wird nur gesendet wenn die antwort-TextBox > 0 ist, damit ich weiß dass die Variable nicht leer ist


    Hey, das kann doch garnicht kompilieren, ein Byte-Array hat ein solches Feld(TextLength) garnet, poste mal was was wirklich läuft. Schalte auch option Strict On um, du weist einen string einen integer zu, ohne ihn zum string zu machen.
    Visual Studio – Empfohlene Einstellungen
    @escape Willkommen im Forum. :thumbup:
    Bevor Du auch nur eine weitere Zeile Code schreibst, solltest Du auf Option Strict On umstellen:
    Visual Studio – Empfohlene Einstellungen
    Wenn Du das nicht tust, wirst Du nicht verstehen, was bei Dir nicht funktioniert
    und
    Dir wird nicht qualitativ hochwertig geholfen.
    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 den Hinweis,
    Option Strict On steht jetzt in der ersten Zeile ;)

    Takafusa schrieb:

    ein Byte-Array hat ein solches Feld(TextLength) garnet


    antwort.TextLength ist eine RichTextBox... diese Zeile wird nicht bemängelt, auch mit "Option strict on" nicht.

    Bemängelt wurde:

    escape schrieb:

    If ausgabe.Text.Length > 3 Then ausgabe.Lines(2) = eintest


    "Option Strict On disallows implicit conversions from 'Integer' to 'String'"

    escape schrieb:

    Dim antwort() As Byte = {&H04, &HDF, eintest, &HFF}

    und hier "Option Strict On disallows implicit conversions from 'Integer' to 'Byte'"

    Ich habe nun noch folgendes Versucht:
    meine "eintest"-Variable -> as string statt as integer.
    UND:

    escape schrieb:

    If ausgabe.Text.Length > 3 Then ausgabe.Lines(2) = eintest


    Das musste ich drehen. Also

    VB.NET-Quellcode

    1. ...Then eintest = ausgabe.Lines(2)​
    warum auch immer - jetzt wird es im Label korrekt dargestellt.


    Nur beim senden gibt es Probleme:

    VB.NET-Quellcode

    1. ​SerialPort1.write(eintest)
    erstmal einfach einzeln, ohne Zeichenfolge, zum testen:

    Es wird nun für "81" (Wert aus der Textbox in der Variabe, im Label auch korrekt 81) "38 31" gesendet bzw. so kommt es am Port an... wie schaffe ich es nun, die Daten in der Variable, im Hex Format an den Port zu senden? Also dass für 81 in der Variable Hex 81 gesendet wird, und nicht 38 31? Muss dazu sagen dass jedes mögliche Hex Zeichen in der Textbox, und damit im Label stehen kann...

    escape schrieb:

    antwort.TextLength ist eine RichTextBox... diese Zeile wird nicht bemängelt, auch mit "Option strict on" nicht.


    VB.NET-Quellcode

    1. Dim antwort() As Byte = {&H04, &HDF, eintest, &HFF} If antwort.TextLength > 0 Then SerialPort1.Write(antwort, 0, 4)


    Sieht für mich so aus als wäre das im selben Scope, denn dann würde das bemängelt, wobei eigendlich hier überschneidende Scopes da sind, ist aber auch nicht wirklich sauber variablen und Controls identisch zu bennenen. Das dass der Kompiler überhaupt zulässt....

    Wie kontrollierst du denn ob alles auch richtig ankommt?

    escape schrieb:

    . wie schaffe ich es nun, die Daten in der Variable, im Hex Format an den Port zu senden?


    Denkfehler, probier mal das aus:

    VB.NET-Quellcode

    1. Dim i1 As Integer = &HFF
    2. Dim i2 As Integer = 255
    3. MessageBox.Show(i1 & ":" & i2)



    Hast du ein Byte, Integer oder sonstige Ganzzahl, ist es nicht relevant wie das für dich aussieht, der Wert ist der gleiche, ob da nun &HFF oder 255 steht. Beim und hier "Option Strict On disallows implicit conversions from 'Integer' to 'Byte'"
    Da meckert der Compiler, ist auch richtig ein Integer besteht aus 4 Bytes, ein Byte kann höchtens den Wert 255 haben, was wenn der integer 256 ist? Dann fliegt dir eine System.OverflowException um die Ohren. Wenn du dir ganz sicher bist, das < 256 dann kannste das einfach so machen

    VB.NET-Quellcode

    1. dim zahl as integer = 255
    2. Dim antwort() As Byte = {&H04, &HDF, CInt(zahl), &HFF}

    Wenn du sicher programmieren willst machste das aber so:

    VB.NET-Quellcode

    1. dim zahl as integer = 259
    2. if zahl > 255 then
    3. messagebox.show("Wert zu hoch für.....")
    4. 'oder
    5. throw new exception("")'hier stoppt das programm und wirft eine exception, aber kommt einen Crash gleich
    6. return 'hier wird eine sub verlassen, in funktionen musst du mit return was zurüchgeben, bei Boolean is klar sollte dann false sein, sonst kannst entweder [tt]nothing[/tt] returnen oder was auch immer, wichtig ist dan aber erstmal zu schauen was zurückkommt, bevor du dann mit dem wert weiter arbeitest.
    7. end if
    8. Dim antwort() As Byte = {&H04, &HDF, CInt(zahl), &HFF}


    Bei Fehlern einfach mit dem Cursor über der Schlangenlinie beim fehler hover, VS schlägt(nicht immer) korrekturen vor, Vorschläge anschauen und evtl. durch klicken übernehmen.

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

    @escape Poste nicht viele einzelne aus dem Zusammenhang herausgerissene Codezeilen, sondern die ganze Prozedur.
    Schreib, was in der TextBox drinne steht und was am Ende rauskommen soll.
    Dann kriegen wir das auch hin. ;)
    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!

    escape schrieb:

    wie schaffe ich es nun, die Daten in der Variable, im Hex Format an den Port zu senden?
    Ich glaube nicht, dass das der Weg ist.
    Zahlem im Hex-Formatsind lediglich eine String-Repräsentation eines ganzzahligen numerischen Wertes: Dim txt = 42.ToString("X2").
    Ich gehe mal davon aus, dass Du eine Bytefolge senden willst. Lies dazu mal in der Dokumentation der Gegenstelle, was die erwartet.
    Und dann noch dies:
    Überzeuge Dich davon, dass Dein Code auch das tut, was er tun soll.
    Lerne zu debuggen!
    Debuggen, Fehler finden und beseitigen
    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!

    RodFromGermany schrieb:

    Ich gehe mal davon aus, dass Du eine Bytefolge senden willst.


    Das ist richtig, meine Variable muss sich in die Bytefolge einfügen, und dementsprechend das Hex Zeichen "80" senden, wenn in der Textbox Zeile 2 eine 80 steht.



    Nun einmal der gesamte Code: Ich habe ihn nochmal etwas übersichtlicher gemacht und Kennungen verändert.

    VB.NET-Quellcode

    1. Imports System.IO.Ports
    2. Imports System.Windows.Forms
    3. Imports System.Text
    4. Public Class Form1
    5. Dim eintest As String 'Variable, in die der Sequenzcounter eingelesen wird
    6. Private Sub Button25_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button25.Click
    7. Dim zumsenden() As Byte = {&H4, &HDF, eintest, &HFF} 'sendet die definierte Zeichenfolge zusammen mit dem Wert in der Variable "eintest" -> abhängig davon, was von der SPS ankommt bzw. aus der Textbox in die Variable geschrieben wird
    8. If txtBytes.TextLength > 2 Then SerialPort1.Write(zumsenden, 0, 4)
    9. End Sub
    10. Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    11. Dim meldedich() As Byte = {&HB1, &HC1, &H0, &HFF} 'fragt die Daten der SPS ab
    12. If SerialPort1.IsOpen Then SerialPort1.Write(meldedich, 0, 4)
    13. End Sub
    14. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    15. Control.CheckForIllegalCrossThreadCalls = False ' Ja, sollte man nicht machen...
    16. End Sub
    17. Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
    18. Dim vonsps As String = SerialPort1.ReadExisting 'ließt die Daten von der SPS und speichert sie in einem String
    19. txtOrgString.Text = vonsps 'Daten werden an eine RichTextBox übergeben, die die Daten als String zeigt
    20. Dim hexString As String = txtOrgString.Text
    21. Dim array As Byte() = Encoding.GetEncoding("ISO-8859-1").GetBytes(hexString)
    22. txtBytes.Text = BitConverter.ToString(array) 'Daten werden zu Bytes konvertiert und an eine RichTextBox übergeben, die die Daten als Bytes zeigt
    23. If txtBytes.Text.Length > 3 Then eintest = txtBytes.Lines(2) 'Wenn die Textbox vollständig ist: der Wert in Zeile 2 der Textbox wird in die "eintest" Variable geschrieben
    24. If txtBytes.Text.Length > 3 Then labeltest.Text = eintest 'nur zur Ansicht: Daten von der Variable werden in einem Label angezeigt, muss, wenn alles stimmt, mit der zweiten Zeile der Textbox übereinstimmen, funktioniert!
    25. End Sub
    26. Private Sub Button10_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button10.Click
    27. SerialPort1.Encoding = System.Text.Encoding.GetEncoding("ISO-8859-1")
    28. SerialPort1.Open()
    29. Timer1.Start() 'startet den "SPS melde dich" Timer beim verbinden
    30. End Sub
    31. Private Sub Button11_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button11.Click
    32. If SerialPort1.IsOpen = True Then SerialPort1.Close()
    33. End Sub
    34. Private Sub txtBytes_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtBytes.TextChanged
    35. txtBytes.Text = txtBytes.Text.Replace("-", "" & vbNewLine) 'ersetzt das "-", das nach jedem Wert kommt, mit einer neuen Zeile. Unelegantes "NewLine" quasi
    36. End Sub
    37. Private Sub Button12_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button12.Click
    38. Dim aendern() As Byte = {&HB1, &HCD, &HDD, &HA2, &HFF} 'ändert den Wert / Sequenz-Counter, der an die SPS zurück geschickt werden soll, Button nur zu Testzwecken. Macht die SPS normalerweise selbstständig
    39. SerialPort1.Write(aendern, 0, 5)
    40. End Sub
    41. End Class


    Nun zu den Problemen die ich aktuell noch habe:
    • Die zweite Zeile der Textbox, dessen Wert in die Variable geschrieben und an den Port zurück gesendet werden soll, kann ein beliebiges Hex Zeichen sein. Bei z.B. 80 kommen keine Fehler, ist es aber z.B. 9A kommt "Ungültige Konvertierung von der Zeichenfolge 9A im Typ Integer." wenn ich die Variable an den Port senden will.
    • Wenn in der Texbtbox / in der Variable "81" steht, wird als Hex 38 31 gesendet, statt "81" -> SPS erkennt es nicht korrekt. Ich bin mir nicht sicher an welcher Stelle im Code und wo ich dafür sorgen kann, dass die Werte in der Textbox/Variable als Hex behandelt und gesendet werden.


    Was ich eigentlich möchte:
    • Die SPS sendet mir eine Zeichenfolge, z.B "A1-FF-0B-D3", in der Textbox sieht es dann so aus
    A1
    FF -> Wert für Variable
    0B
    D3
    • Der Wert in der zweiten Zeile, in diesem Fall "FF" soll in die Variable "eintest" gespeichert werden, und beim Klick eines Buttons innerhalb einer Zeichenfolge als Hex FF zurück an die SPS gesendet werden ->

      VB.NET-Quellcode

      1. Dim zumsenden() As Byte = {&H4, &HDF, eintest, &HFF}

    Es gibt außerdem zwei RichTextBoxen die die empfangenen Daten als String und als Bytes darstellen.

    Okay, das war jetzt ausführlich, ich hoffe ihr versteht wo ich hänge.
    Läuft Dein Projekt auf Option Strict On :?:
    Visual Studio – Empfohlene Einstellungen
    Vorher hat es keinen Zweck hier weiter zu reden.
    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!

    RodFromGermany schrieb:

    Läuft Dein Projekt auf Option Strict On


    Ich hatte das Projekt der Übersicht halber nochmal erstellt, und die Option dabei vergessen, sie ist jetzt wieder aktiv.

    escape schrieb:

    Dim zumsenden() As Byte = {&H4, &HDF, eintest, &HFF}



    Mit Option Strict On habe ich noch den Fehler dass ich String nicht in Byte konvertieren kann.

    Abgesehen davon gibt es keine weiteren Fehler die vorher nicht angezeigt wurden.

    escape schrieb:

    dass ich String nicht in Byte konvertieren kann.
    Und da hast Du noch Handlungsbedarf:
    Dim value = Convert.ToIntegeer(DEIN_HEX_STRING, 16)
    "80" => 128
    usw.
    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!