Hallo. Ich habe ein ein problem mit folgenden Programmteil: Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived Control.CheckForIllegalCrossThreadCalls = False Dim data, zwischen As String data = SerialPort1.ReadExisting() SerialPort1.DiscardInBuffer() 'Empfangene Daten auswerten: If data.Contains("L1Value") Then data = data.Remove(0, 7) data = CInt(data) zwischen = data 'nur zum debuggen TrackBarL1.Value = data Label1.Text = data * 10 & " %" End If End Sub Ich werte einen String aus der über die serielle SChnittstelle empfangen wird. Und zwar erstmal nur für ein Objekt, d.h. die If-Anweisung könnte man auch erstmal weglassen. Das Problem ist nun folgendes: Der String der empfangen wird lautet "L1Value" direkt gefolgt von einer Zahl 0 bis 10. Also z.B. L1Value9 oder L1Value10 Ich scheide dann L1Value vom String ab und weise die Zahl einem Label und Trackbar zu. Das klappt eigentlich ganz gut nur funktioniert es nicht richtig mit dem String "L1Value10"! data hat nach dem Scneiden den Wert 1! Es funktioniert nur einmal wenn der erste String der nach dem programmstart gesendet wird "L1Value10" ist. Nur dann übernimmt das Programm die 10. ??? Ich verstehe das nicht. Bin auch noch Anfänger mit Visual Basic (2005)
Was passiert bei z.B. 11-21 "L1Value11"-"L1Value21"
Schalte mal in den Projektoptionen "Option Strict" auf "On", korrigiere alle Fehler und poste den Code noch mal. Möglicherweise funktioniert es dann bereits. Zeilen à la "data = CInt(data)" sind jedenfalls relativ sinnfrei. Damit wandelst du den Inhalt des Strings "data" erstmals explizit in einen Integer um und gleich anschliessend implizit wieder in einen String.
Du machst da einen "threadübergreifenden Zugriff", das bedeutet, diese Verarbeitungsroutine für die serielle Schnittstelle ist in einem anderen Thread beheimatet als das Steuerelement, auf das du die Werte zuweist. Das klingt erstmal komisch, aber ich hatte ein ähnliches Problem auch schon mal und das generierte die verrücktesten Fehler. Setze mal "Control.CheckForIllegalCrossThreadCalls" auf True (oder kommentier die Zeile aus), und du wirst sehen dass VB bei der Ausführung da eine Exception wirft !! Eine Lösung fand ich im MSDN, die sollte dir auch weiterhelfen: -> http://msdn.microsoft.com/de-de/library/ms171728.aspx Hth, Mario
@juppi >Was passiert bei z.B. 11-21 >"L1Value11"-"L1Value21" Weiss nicht, kommt doch gar nicht vor dass ich was subtrahiere. ??? @Philipp >Zeilen à la "data = CInt(data)" sind jedenfalls relativ sinnfrei. Damit >wandelst du den Inhalt des Strings "data" erstmals explizit in einen >Integer um und gleich anschliessend implizit wieder in einen String. Aber wieso kann ich dem TrackBarL1.Value einen String zuweisen, wenn der doch als Integer definiert ist? >"Option Strict" auf "On" Was bedeutet das? Wo stelle ich das ein? @Mario Was soll es mir bringen den Wert wieder auf True zu setzen, außer dass es dann überhaupt nicht mehr geht?
Wenn du die Option "CheckForIllegalCrossThreadCalls" auf False stellst, dann UNTERDRÜCKST du eine Fehlermeldung über einen unzulässigen Vorgang. Und offensichtlich hat dein Programm genau an der Stelle ein Problem ! Ich mach dir nen Vorschlag: Du schreibst dein Programm um, so wie ich's dir gleich zeige. Wenn es dann geht, gibste mir - virtuell - einen aus, wenn nicht, dann nehm ich alles zurück und behaupte das Gegenteil, ok ? Also, mach das ganze mal so:
1 | Private Sub DeineDatenEmpfangsRoutine(...) |
2 | |
3 | ' Folgende Zeile auskommentieren (Überprüfung an) |
4 | ' Control.CheckForIllegalCrossThreadCalls = False |
5 | |
6 | Dim data, zwischen As String |
7 | data = SerialPort1.ReadExisting() |
8 | SerialPort1.DiscardInBuffer() |
9 | |
10 | 'Empfangene Daten auswerten: |
11 | If data.Contains("L1Value") Then |
12 | |
13 | data = data.Remove(0, 7) |
14 | data = CInt(data) |
15 | zwischen = data 'nur zum debuggen |
16 | |
17 | 'TrackBarL1.Value = data |
18 | 'Label1.Text = data * 10 & " %" |
19 | ' das wird ersetzt durch: |
20 | SetTrackBarAndLabel(data) |
21 | |
22 | End If |
23 | End Sub |
24 | |
25 | ' Delegate für SetTrackBarAndLabel (nötig für asynchrone Calls) |
26 | Delegate Sub SetTrackBarAndLabelCallback(data As String) |
27 | |
28 | ' Und hier die Sub, die threadsicher TrackBar und Label updatet |
29 | Private Sub SetTrackBarAndLabel(ByVal data As String) |
30 | |
31 | If TrackBarL1.InvokeRequired Then |
32 | Dim d As New SetTrackBarAndLabelCallback(AddressOf SetTrackBarAndLabel) |
33 | Me.Invoke(d, New Object() {data}) |
34 | Else |
35 | TrackBarL1Value = data |
36 | Label1.Text = data * 10 & " %" |
37 | End If |
38 | |
39 | End Sub |
Eigentlich solltest du noch checken, ob "data" wirklich eine Zahl ist, bevor du es auf TrackBar und Label loslässt ... Viel Erfolg, Mario
Benji Bone wrote: > @Philipp >>Zeilen à la "data = CInt(data)" sind jedenfalls relativ sinnfrei. Damit >>wandelst du den Inhalt des Strings "data" erstmals explizit in einen >>Integer um und gleich anschliessend implizit wieder in einen String. > > Aber wieso kann ich dem TrackBarL1.Value einen String zuweisen, wenn der > doch als Integer definiert ist? Es ist durch die implizite Konvertierung möglich. "data" wird in einen Integer umgewandelt und dann zugewiesen, aber du hast keine Kontrolle darüber. Ausserdem ist es einfach nicht schön. >>"Option Strict" auf "On" > Was bedeutet das? Wo stelle ich das ein? "Option Strict On" bedeutet, dass sich der Code genau an die Regeln halten muss, implizite Konvertierungen und solche "Unschönheiten" werfen dann einen Fehler. Gibt zwar mehr Schreibarbeit, ist aber weniger fehleranfällig. Die Einstellung findest du unter Project->Options->Compiler oder sowas...
@Mario Ich habe deinen Code mal eingefügt, aber es funktioniert immer noch nicht richtig. :-( Schade, ich hätte dir sehr gerne einen ausgegeben... Was mir auffällt ist, dass das Programm anscheinend nur die erste Ziffer nach "L1Value" beachtet. Ich kann nämlich anhängen was ich will, ohne dass es Auswirkungen hat. Ich schicke z.B. "L1Value89384" dann geht die TrackBar auf 8 bzw. Label: 80%, bei "L1Value10000" oder "L1Value18373" auf 1 bzw. Label: 10%. ???
Schade, hätte wetten können dass es das ist ! Zumal du sagst, dass es beim ersten Mal immer klappt ... Versuch doch mal das Problem weiter einzukreisen und finde raus, welcher Befehl nicht das tut was er soll.
Ich habe das Problem mit data = SerialPort1.ReadLine() gelöst. Am Ende des Strings muss man noch ein LF dran hängen und schon klappts. :-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.