Hallo Leute.
Ich hab ein kleines Problem Daten die von dem µC kommen in VB 2005
zu verarbeiten. Ich hab einen Mega32 mit Bascom Programmiert, und der
sendet mir jede Sekunde einen Temperaturwert, der als "temp_out = 12"
ins Hyperterminal kommt. Nun kann ich mir das ganze schon in VB
mithilfe einer Messagebox anzeigen lassen. Ich brauch aber
diesen Wert in eienr Variablen, so das ich den Wert weiterverarbeiten
kann. Es sollen aber dann noch mehrere Werte kommen die ebenfalls
verarbeitet werden müssen. Desweiteren müssen Daten die vom PC kommen
in Variablen vom µC wo ich dann bestimmte Aktionen wie z.B. Ausgänge
ein und ausschalten kann. Ich hoff ihr könnt mir folgen und Helfen:-).
Gruß
Tobi
Tobias Schmid wrote:
> Hallo Leute.> Ich hab ein kleines Problem Daten die von dem µC kommen in VB 2005> zu verarbeiten. Ich hab einen Mega32 mit Bascom Programmiert, und der> sendet mir jede Sekunde einen Temperaturwert, der als "temp_out = 12"> ins Hyperterminal kommt. Nun kann ich mir das ganze schon in VB> mithilfe einer Messagebox anzeigen lassen. Ich brauch aber> diesen Wert in eienr Variablen, so das ich den Wert weiterverarbeiten> kann.
Dann musst du dir den Wert aus dem empfangenen String herausholen.
Du gehst im VB den String Zeichen für Zeichen durch, bis du deinen
'Trigger' findest und liest weiter, bis du das Ende der Zahl
erkannt hast.
Dazu ist es von Vorteil, wenn dein Trigger, sowie das Ende einer
Zahl möglichst einfach erkennbar sind. Man will sich ja schliesslich
das Leben nicht selbst unnötig kompliziert werden.
Ersetzte im Text, den du vom µC sendest die 'Einleitung' mal
durch einen simplen Kennbuchstaben und häng hinten an die Zahl
noch ein abschliessendes Zeichen drann.
zb. Könntest du den Temperaturwert ganz einfach als "T12;"
senden. Im VB Programm liest du dann ganz einfach Zeichen
aus dem empfangenen String, bis ein grosses 'T' kommt. Aha, als
nächstes kommt ein Zahlenwert, den extrahierst du dann aus dem
String, bis du das Zeichen ';' siehst. Dort ist die Zahl
zuende. Den Text dazwischen extrahierst du und lässt ihn in
eine Zahl umwandeln. Fettich.
> Es sollen aber dann noch mehrere Werte kommen die ebenfalls> verarbeitet werden müssen.
Du gibst jedem 'Wert' einen anderen Kennbuchstaben, der seine
Verwendung kennzeichnet. Dadurch kann das VB Programm erkennen,
was es mit dem Wert tun soll.
> Desweiteren müssen Daten die vom PC kommen> in Variablen vom µC wo ich dann bestimmte Aktionen wie z.B. Ausgänge> ein und ausschalten kann.
Das geht dann in die andere Richtung. Aber du kannst das gleiche
Prinzip benutzen.
Hallo Karl heinz Buchegger,
erstmal Danke für deine Hilfe. Bin aber was VB angeht noch ein wenig
unerfahren. Deswegen wär es mir sehr hilfreich wenn du mir einen
Beispiel-Code senden würdest, so wie ich das in VB schreiben muss.
Gruß
Sorry, aber das ist simple Stringverarbeitung.
Wenn du unerfahren bist, dann wirst du das lernen muessen.
Schau dir die Funktionen Length, Mid, Left, Right, Val in
der VB Doku an.
Karl heinz Buchegger wrote:
> Sorry, aber das ist simple Stringverarbeitung.> Wenn du unerfahren bist, dann wirst du das lernen muessen.> Schau dir die Funktionen Length, Mid, Left, Right, Val in> der VB Doku an.
Wurgs, bloss nicht. VB2005 läuft mit dem .NET-Framework, da sollte man
möglichst nicht auf die Compatibility-Funktionen zurückgreifen müssen.
Strings sind nun auch einfach Objekte mit ihren Methoden und
Eigenschaften.
1
Sub Main()
2
Dim s As String = "T5;T-18;T30;T60;T0;T-200;"
3
4
Dim t As Integer = 0, e As Integer
5
Do
6
t = s.IndexOf("T"c, t) + 1
7
e = s.IndexOf(";"c, t)
8
If t < 1 OrElse e < 0 OrElse e < t Then Exit Do
9
10
Call Console.WriteLine("T: " & s.Substring(t, e - t))
11
Loop
12
13
Call Console.Read()
14
End Sub
Wenn du auf s.SubString(t, e - t) nun noch Integer.Parse() (Bzw.
Integer.TryParse() um sicherzugehen) anwendest kriegst du den
entsprechenden Zahlenwert raus. Oder halt Double.Parse(), falls du
Fliesskommazahlen bekommst.
Hi Philipp Burch,
Danke für dein Beispiel. Wenn ich das richtig sehe werden die Zahlen in
dem String untereinander der Reihe nach aufgelistet. Soweit versteh ich
deinen Code schon nur wie gehts dann weiter?? Also bei mir wird der
String im µC so erzeugt:
Mess = Druck 'Luftdruck
Mess_string = Str(mess) 'Messwert in
String umwandeln
Mess_string = Mid(mess_string , 1 , 6)
Zeichenspeicher = Z1 + Mess_string
Mess = Rhlintemp 'Feuchte
RHT 11
Mess_string = Str(mess) 'Messwert in
String umwandeln
Mess_string = Mid(mess_string , 1 , 6)
Zeichenspeicher = Zeichenspeicher + Z2
Zeichenspeicher = Zeichenspeicher + Mess_string
Mess = Tempc 'Temperatur
RHT 11
Mess_string = Str(mess) 'Messwert in
String umwandeln
Mess_string = Mid(mess_string , 1 , 6)
Zeichenspeicher = Zeichenspeicher + Z3
Zeichenspeicher = Zeichenspeicher + Mess_string
Zeichenspeicher = Zeichenspeicher + Z7
If Senden = 1 Then
Print Zeichenspeicher
Senden = 0
End If
Und diese Werte kommen dann an der Seriellen Schnittstell wieder an und
muss dann in Variablen von VB reingepackt werden. Leider ähnelt sich
Bascom nur ein wenig mit VB, sonst wär das alles nicht so schlimm.
Wenn da mehrere verschiedene Typen ausgewertet werden sollen, dann geht
das wohl einfacher mit einem regulären Ausdruck (RegEx):
1
Module Module1
2
3
Sub Main()
4
Dim buf As String = "245;T5;D1013;F80;T35;T31;F+10;T-3;D+800;F90;D5"
5
6
Dim regex As New Text.RegularExpressions.Regex("[TDF][-\+]?\d+;", Text.RegularExpressions.RegexOptions.Compiled)
7
For Each m As Text.RegularExpressions.Match In regex.Matches(buf)
8
Dim val As Integer = Integer.Parse(m.Value.Substring(1, m.Length - 2))
9
Select Case m.Value.Chars(0)
10
Case "T"c
11
Call Console.WriteLine("Temperatur: {0}°C", val)
12
Case "D"c
13
Call Console.WriteLine("Druck: {0}hpa", val)
14
Case "F"c
15
Call Console.WriteLine("Feuchtigkeit: {0}%", val)
16
End Select
17
buf = buf.Replace(m.Value, "")
18
Next
19
20
Call Console.WriteLine("buf: {0}", buf)
21
22
Call Console.Read()
23
End Sub
24
25
End Module
Erklärung:
'buf' beinhaltet deinen empfangenen String. Du könntest dir also eine
Modulglobale Variable erzeugen (Z.B. 'Buf' oder so) und alles was du an
der RS232 empfängst einfach dort anhängen. In einem Timer, der z.B. fünf
Mal pro Sekunde feuert lässt du dann den obigen Code laufen um 'Buf' zu
zerlegen und die Werte zu extrahieren. Gefundene Werte werden dann
gelöscht, so dass sie beim nächsten Aufruf nicht wieder gefunden werden.
Der RegEx "[TDF][-\+]?\d+;" findet alle Vorkommen in 'buf', die mit
einem 'T', einem 'D' oder einem 'F' anfangen, danach optional ein
Vorzeichen besitzen, folgend eine beliebige Anzahl Ziffern haben und mit
einem ';' enden.
In der Schleife werden nun alle Vorkommen durchgegangen und ausgegeben.
Ich hoffe, das hilft.
@sechszweifuenf:
Das wäre natürlich eigentlich die bessere Variante, aber bei Binärdaten
musst du immer aufpassen, dass du irgendwas wie ein Start- und
Endzeichen hast, das ist bei Klartexten wesentlich einfacher, da hier
nie alle möglichen Zeichen vorkommen.
Erst mal Danke für das Beispiel, dass ist genau das was ich gesucht und
probiert habe. jetzt muss ich das ganz nur noch in eine Grafisch Windows
Anwendung packen. Das müsste ja kein Problem sein. Mal kurz zur
Verwendung
des ganze, so das man sich auch drunter was vorstellen kann.
Ich hab den µC so programmiert, dass er mir alle 5 sec Werte wie
Temperatur, Feuchte, Druck, Schaltzustände usw. an den Pc
sendet diese werden dann am Pc Visualisiert und angezeigt. Bei der
Temperatur soll dann noch eine Soll und Istwert Vergleichung stattfinden
und gegebenenfalls einen Ausgang schalten. Ich bin aber immer Dankbar,
wenn weitere Ratschläge oder Verbesserungen gemeldet werden.
Dann kommt bei "Text.RegularExpressions.regex" Text nicht eindeutig?
Das gleich ist auch bei "Text.RegularExpressions.Match".
Wo ist oder mach ich den fehler?
Tobias Schmid wrote:
> So nun steh ich mal wieder vor einem Problem. wenn ich nun> den Code so eingebe:> Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e> As System.IO.Ports.SerialDataReceivedEventArgs) Handles> SerialPort1.DataReceived> empfangs_string = SerialPort1.ReadLine 'dort werden die> empfangenen Daten deklariert>> Dim regex As New> Text.RegularExpressions.regex("[TDF][-\+]?\d+;",> Text.RegularExpressions.RegexOptions.Compiled)> For Each m As Text.RegularExpressions.Match In> regex.Matches(empfangs_string)> empfangs_string = Integer.Parse(m.Value.Substring(1,> m.Length - 2))> Select Case m.Value.Chars(0)> Case "TI"> temp_in_ist = Val()> Case "TA"> temp_out_ist = Val()>> End Select> empfangs_string = buf.Replace(m.Value, "")> Next> End Sub>> Dann kommt bei "Text.RegularExpressions.regex" Text nicht eindeutig?> Das gleich ist auch bei "Text.RegularExpressions.Match".> Wo ist oder mach ich den fehler?
Das kann so nicht funktionieren. Erstens musst du den Regex anpassen,
damit er wieder auf deine Zeichen passt:
"(TI|TA)[-\+]?\d+;"
Desweiteren stimmt deine Select Case-Anweisung so nicht mehr, da dort
nur anhand des ersten Zeichens verzweigt wird, aber "TI" und "TA" sind
ja nunmal zwei. Ich bin mir gerade nicht sicher, ob sich auch nach
Strings verzweigen lässt, müsste aber eigentlich gehen. Also
1
Select Case m.Value.SubString(0, 2)
2
Case "TI"
3
'...
Die Lösung ist allerdings nicht so toll wenn du verschieden lange
Bezeichner hast. Dann solltest du entweder auf mehrere Ifs anstelle von
Select Case zurückgreifen oder aber, wie bereits erwähnt, den String mit
'Split' zerlegen und die einzelnen Teile auswerten.
Ausserdem macht 'temp_out_ist = Val()' wohl nicht das, was du möchtest.
Versuch's mal mit
temp_out_ist = Integer.Parse(m.Value.SubString(2, m.Value.Length - 3))
Stell mal in den Projektoptionen -> Kompilieren 'Option Strict' und
'Option Explicit' auf 'On' und wundere dich über ca. 100 Compilerfehler
und -warnungen.
Hi Leute,
so jetzt hab ich nochmal alle Möglichkeiten ausprobiert und nachgelesen.
Aber ich komm auf keinen grünen Zweig.
Vieleicht nochmal von Anfang an. Ich hab das Projekt "Windows Anwendung"
gestartet. Mir mal eine Grobe Oberfläche angelegt. Der jetzige Code
sieht
so aus:
1
Public Class Form1
2
3
Dim temp As Integer
4
Dim druck As Integer
5
Dim feuchte As Integer
6
Dim Sende_string As String
7
Dim empfangen As String
8
9
Private Sub TextBox3_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox3.TextChanged
10
11
End Sub
12
13
Private Sub Label1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label1.Click
14
15
End Sub
16
17
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
18
If SerialPort1.IsOpen = False Then
19
SerialPort1.Open()
20
MsgBox("Com 1 geöffnet")
21
Else
22
MsgBox("Com 1 bereits geöffnet")
23
24
25
End If
26
End Sub
27
28
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
29
SerialPort1.Close()
30
MsgBox("Com 1 geschlossen")
31
32
33
End Sub
34
35
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
36
'empfangen = SerialPort1.ReadLine 'dort werden die empfangenen Daten deklariert
37
Dim buf As String = "245;T5;D1013;F80;T35;T31;F+10;T-3;D+800;F90;D5"
38
39
Dim regex As New Text.RegularExpressions.Regex("[TDF][-\+]?\d+;", Text.RegularExpressions.RegexOptions.Compiled)
40
For Each m As Text.RegularExpressions.Match In regex.Matches(buf)
41
Dim val As Integer = Integer.Parse(m.Value.Substring(1, m.Length - 2))
42
Select Case m.Value.Chars(0)
43
Case "T" = temp
44
Case "D" = druck
45
Case "F" = feuchte
46
47
End Select
48
buf = buf.Replace(m.Value, "")
49
Next
50
51
Call Console.WriteLine("buf: {0}", buf)
52
53
Call Console.Read()
54
55
End Sub
56
57
58
59
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
60
61
End Sub
62
End Class
Die Werte Temp Feuchte und Druck sollen in einer TextBox angezeigt
werden
Das würd ich dann so schreiben:
TextBox3_TextChanged = temp
Ich hoff das wenigstens das mal richtig formuliert ist.
- Hast du das Prog jemals kompiliert?
- Hast du Option Strict eingeschaltet?
- Hast du dir die Compilerwarnungen zu Herzen genommen?
- Liest du meine Posts überhaupt?
JA ich hab schon alles Probiert was du mir geschrieben hast, hab auch
deine Posts immer und immerwieder durchgelesen. Ich komm aber einfach
nicht
weiter. Abgesehen mal von den deklarationen die ich in dem case hab, die
auch falsch sind, hab ich nichts unversucht gelassen. Es kommt
immer das gleich wie ich es schon oben beschrieben habe!
Hi Tobias,
ich glaube, Du hast noch nie in vb.net programmiert.
Deshalb habe ich das (sehr einfache) Beispiel im Anhang eingefügt.
Besorge Dir ein vernünftiges Buch, um vb.net zu lernen.
(Beispiel: Michael Kolfer - Visual Basic 2005)
Ohne dem geht es nicht.
Bitte entscheide Dich:
Willst Du eine Consolen-Anwendung oder eine Windows-Anwendung?
Überlege Dir ein Kommunikationsprotokoll und den dazu gehörigen
Ablauf zwischen der Windowsanwendung und Deinem µC.
(z.B Wer ist der Master bzw. der Slave? Woran soll die Windowsanwendung
erkennen, das alle Daten angekommen sind? usw. )
Wenn Du dieses getan hast, kann man über die Windowsanwendung sprechen.
Bitte beherzige Philipp Vorschläge! Dein gepostetes Beispiel ist nicht
lauffähig.
Bye
Klaus
Hi Klaus und Philipp,
danke erst mal für eure bemühungen. Ja das stimmt ich hab fast keine
Ahnung vom VB 2005. Ich hab mal kleinere Programme für Berechnungen
gemacht also nichts großartiges.Ich brauch halt immer ein Beispiel an
dem ich mich orientieren kann. Wenn ich das dann sehen kann versteh ich
das dann auch.Das mit dem Buch werd ich mir zu Herzen nehmen!
Also ich möchte eine Windowsanwendung die man dann Anpassen kann
wie man sie braucht.
das Kommunikationsprotokoll soll über die RS232 Schnittstelle laufen.
Der Master ist der µC der ja die eigentlichen Prozesse ausführt. Slave
ist der PC der nur Hauptsächlich Daten empfängt diese ausgiebt
und je nach bedarf geändert werden und wieder zurückgesendet werden.
Im µC Überprüf ich das mit einem Case ob die Daten vollständig
gesendet worden sind, dies kann ja im PC bestimmt auf die gleiche art
und weiße gemacht werden!? Oder gibt es bessere Ideen?
Danke nochmal für euer Bemühen
by
Tobi
Normalerweise ist der Controller der Slave und der PC der Master. Der
Controller weiss was zu machen ist, und macht das, bis eine Anweisung
vom PC kommt. Mit dem PC verstellt nur ein paar Parameter. Der PC fragt
auch die Daten zum visualisieren ab. Wenn der PC nicht laeuft, so gibt's
nichts anzuseigen, dann muss der controller auch nichts in dieser
richtung machen.
Nur so als Idee.
Hi Tobi,
wenn der µC der Master ist, dann sorge bitte dafür, das er nicht
schneller als alle 200 ms sendet.
Grund:
Windows ist keine Realtimesystem und kann evtl. bei einer schnelleren
Übertragung durch einander kommen.
Bitte überlege Dir, ob die Anmerkung von "sechsdreizwei" nicht
sinnvoller ist.
Zum Protokoll:
Du musst den Sendestring beschreiben.
Beispiel:
Sendestring:
"245;T5;D1013;F80;T35;T31;F+10;T-3;D+800;F90;D5"
Formaler Aufbau:
<id>;<Temp1>;<Druck1>;<Feuchte1>;<Temp2>;<Temp3>;<Feuchte2>;<Temp4>;<Dru
ck3>;<Feuchte3>;<Druck4>
In den Klammer stehen mögliche Variablennamen. Du hast also mehr als
eine Temperatur, Druck bzw. Feuchte. Ich nehme an, Du willst zwischen
diesen
unterscheiden.
Sendestringende:
Als Ende des Sendestrings schlage ich Die ETX (= 0x03) vor.
Damit kannst Du der Windowsanwendung mitteilen, das alle Daten
vorliegen.
Damit hast Du den folgenden Aufbau:
<id>;<Temp1>;<Druck1>;<Feuchte1>;<Temp2>;<Temp3>;<Feuchte2>;<Temp4>;<Dru
ck3>;<Feuchte3>;<Druck4>ETX
Ist die Analyse korrekt?
Bye
Klaus
Welcher nun Master oder Slave der Kommunikation ist hat in erster Linie
nichts mit dem Server und Client Konzept zu tun. Bei mir sind die
Controller jeweils die Kommunikations-slaves, und fuer die Prozesse sind
sie die Server. Der PC ist der Client, der Anfragen macht. Das erlaubt
mehrere an einen Bus zu haengen, und von einem PC zu kontrollieren.
Hi Klaus,
das Senden der Daten erfolgt in einem Sub Menü, dass bis jetzt alle
500ms die werte schickt.
Die anmerkung von "sechsdreizwei" ist auf jeden Fall sinnvoller.
Werd das auch so umsetzen.
Ich werd auch den Aufbau des String so wie von dir beschrieben
Ausführen. Also so:
<id>;<Temp1>;<Druck1>;<Feuchte1>;<Temp2>;<Temp3>;<Feuchte2>;<Temp4>;<Dru
ck3>;<Feuchte3>;<Druck4>ETX
Anbei hab ich mir gerade das Buch das du mir vorgeschlagen hast
Bestellt.
So das ich mir ein genaus Bild von VB machen kann.
by
Tobi
Hi,
erst mal Danke an Klaus für den Super Buchtip! Das Buch ist wirklich
Super! Ich denk wenn ich damit durch bin, sind solche Fragen
überflüssig:-).
by