Hallo zusammen, ich versuche mit einem Timer in C# über die RS232 - Schnittstelle einen Eingang vom STM32 ständig abzufragen. Klappt soweit auch. Nur, damit ich in C# was auslösen kann bei einem bestimmten Ereignis, muß ich den gelesenen Wert, der in einem string gespeichert wird, zerlegen. Ich habe es bereits versucht, den string in ein char array zu konvertieren, nur komme ich nicht weiter. Folgendes erhalte ich vom Comport zurück: in 0[?25l in 0 = 0 >[?25h. Ich möchte die Zeichenfolge "in 0 = 0" von dem String auswert. Der Rest sind VT100, oder Hyperterminalbefehle, weiß es nicht so recht. Kann mir da jemand einen Tipp geben ? Wäre super.
:
Verschoben durch User
sandman schrieb: > Der Rest > sind VT100, oder Hyperterminalbefehle, weiß es nicht so recht. dann musst du dir erstmal die doku/rfc zu VT100 durchlesen und dann kannst du einen filter schreiben der diese Infos entfernt. Dann sollte dein gesuchter text übrig bleiben.
sandman schrieb: > den string in ein char array zu konvertieren Das sollte in c# vollkommen überflüssig sein. Wenn du Textsegmente miteinander vergleichen willst, kannst du das in c# auch direkt tun.
1 | if (emfpangsstring == "0 = 0") |
2 | {
|
3 | // tu was
|
4 | }
|
Außerdem kann die serielle Schnittstelle einen Event auslösen, in dem du dann die Daten entgegen nehmen kannst. Dann kannst du dir den Timer sparen ;-)
Hallo Sven, den Timer nehme ich halt, weil er es dauernd überprüfen soll. Dein Lösungsansatz hatte ich auch schon mal versucht, hat bei mir aber nichts ausgelöst. Hier mal mein Code: input = serialPort.ReadExisting(); if (input == "in 0 = 0") { MessageBox.Show("Richitg"); textBox2.Text = input; } Wenn ich am Eingang 0 ein Signal anlelge, egal mal welches, sehe ich dann im Debugger von VS, dass dann "in 0 = 1" steht. Also die Auswertung funktioniert. Nur wird keine Messagebox geöffnet.
sandman schrieb: > Hallo Sven, > > den Timer nehme ich halt, weil er es dauernd überprüfen soll. Was soll er dauernd überprüfen? Wenn vom µC ein neuer Text reinkommt, kriegt dein C# Programm in Form eines Events Bescheid und kann sich das, was reingekommen ist ansehen, analysieren und in Variablen die Erkentnisse ablegen. Wozu soll das dann mit einem Timer ständig 'überprüft' werden? > Lösungsansatz hatte ich auch schon mal versucht, hat bei mir aber nichts > ausgelöst. Hier mal mein Code: > > input = serialPort.ReadExisting(); Kein Mensch sagt, dass mit einem ReadExisting die komplette Zeile vorliegt. Du liest das, was bisher alles über die Serielle reingekommen ist. Das kann der Text sein "0[?25l in 0 = 0 >[?25h." kann aber auch der Text "0[?25l in 0 = " sein, weil der Rest zum Zeitpunkt des Aufrufs noch gar nicht vollständig übertragen ist sondern die Zeichen noch auf der Leitung unterwegs sind. Vielleicht solltest du mal den Code anderer Leute studieren, wie man eine Eventgetriebene Empfangsroutine in C# schreibt. So schwer ist das nicht und du kannst dabei nur lernen, wie man es richtig macht.
Er soll überprüfen, ob der Zustand des Ausganges sich von 0 auf 1 geändert hat, und das ständig.
Karl Heinz Buchegger schrieb: > Vielleicht solltest du mal den Code anderer Leute studieren, wie man > eine Eventgetriebene Empfangsroutine in C# schreibt. So schwer ist das > nicht und du kannst dabei nur lernen, wie man es richtig macht. das hilft ihm aber überhaupt nicht weiter, er muss erstmal den Klartext extrahieren. Und wenn der vorher etwas schicken muss, dann hilft ihm der event ansatzt auch nicht. Im event muss man dann selber noch die Daten zusammen ketten weil nicht alles auf einmal kommt. Und wenn ich die letzen Thread zu c# com und event suchen dann merkt man das der event ansatz mehr Probleme als lösungen schafft. eine üblich Kommuniktion läuft ja so ab sende empfang beständigung sende empfang beständigung Dabei hilft einem der Event überhaupt nicht weiter, weil man eh auf die bestätiung warten muss, dann kann man auch gleich ein Read machen.
hi peter, bin auch eher Deiner Meinung mit dem Read. Denn wie gesagt, im Debugger von VisualStudio stehen halt die Sonderzeichen mit drin, habe mir überlegt, dass doch die Variante mit dem string input in eine char Array zu kopieren die beste Lösung geben würde. Dann könnte man doch mit einer for Schleife Zeichen rausfiltern. Nur weiss ich grad im Moment noch keinen sinnvollen Ansatz dafür
Normalerweise schreibe ich die Daten, die ich im Event mit ReadExisting() bekomme in einen globalen Speicher (kann ne Liste mit Bytes sein oder ein String, an den angehängt wird oder oder oder) und jedes mal, wenn neue Daten hinzu kommen, prüfe ich, ob das, was ich erwarte, sei es nun eine definierte Länge oder ein Steuerzeichen oder wasauchimmer, angekommen wurde und starte dann die Verarbeitung der komplett empfangenen Daten. Dazu braucht es keinen Timer. Der verzögert die ganze Sache sowieso nur, denn der Timer schlägt nämlich nie genau dann zu, wenn grade alle Daten da sind. Also die Vorgehensweise nochmal in Schritten: - Beim Event alle Daten von der Schnittstelle lesen und global ablegen (global meint hier eine Funktionsübergreifende Variable, sprich eine Eigenschaft der Klasse) - Nach jedem Empfang prüfen, ob die Bedingung, die vollständigen Empfang aller Daten anzeigt, erfüllt ist - Daten aus dem Puffer nehmen und verarbeiten
Und das char Array brauchst du in c# nicht. Ein string stellt die die selben Möglichkeiten zur Verfügung und noch mehr! stringname[index] gibt dir auch nur ein Zeichen zurück ;-)
Peter II schrieb: > Karl Heinz Buchegger schrieb: >> Vielleicht solltest du mal den Code anderer Leute studieren, wie man >> eine Eventgetriebene Empfangsroutine in C# schreibt. So schwer ist das >> nicht und du kannst dabei nur lernen, wie man es richtig macht. > > das hilft ihm aber überhaupt nicht weiter, er muss erstmal den Klartext > extrahieren. Was hilft ihm nicht? Erst mal muss er ja wohl die komplette Antwort haben, ehe er den Klartext extrahieren kann. > eine üblich Kommuniktion läuft ja so ab > > sende > empfang beständigung > sende > empfang beständigung > > Dabei hilft einem der Event überhaupt nicht weiter, weil man eh auf die > bestätiung warten muss, dann kann man auch gleich ein Read machen. Das sind dann die Programme, die (überspitzt) das halbe Windows einfrieren, nur weil sie auf Antwort von der Gegenstelle warten.
Karl Heinz Buchegger schrieb: > Das sind dann die Programme, die (überspitzt) das halbe Windows > einfrieren, nur weil sie auf Antwort von der Gegenstelle warten. nein das ganze kommt ja in ein Thread. Wie will man sonst sauber das Frage - Antwort spiel hinbekommen. Statemaschine schön und gut aber wie macht man dann ein Timeout - wieder mit Timer?
wieso, der string sieht jedesmal gleich aus wenn ich im debugger schaue, der unterschied ist nur wenn eine 1 anliegt oder eine 0, also "in 0 = 1" oder "in 0 = 0". müßte nur diesen bereich extrahieren können sinnvollerweise. was man oben in dem string nicht sieht ist, dass in den sonderzeichen auch noch ein <-- kleiner pfeil mit enthalten ist...... das macht es glaub noch schwieriger, den string zu extrahieren
sandman schrieb: > das macht es glaub noch schwieriger, den string zu extrahieren Wer sich beim Programmieren auf den GLauben verläßt hat es sowieso sehr schwer... C# (wie vermutlich jede andere Programiersprache) kennt auch eine Methode um su prüfen ob ein Teilstring in einem anderem enthalten ist, man müßte nur mal die Doku lesen und verstehen...
Nicht ideal sollte aber schnell sein for (i=0;emfpangsstring[i]!=0;i++) { if (empfangsstring[i]=='i') if (empfangsstring[i+1]=='n') if (empfangsstring[i+2]==' ') if (empfangsstring[i+3]=='=') if (empfangsstring[i+4]==' ') { wert=empfangsstring[i+5]; wert=wert-0x30; if(wert==1) MsgBox("Wert ist 1"); } }
Uwe schrieb: > Nicht ideal sollte aber schnell sein geht doch auch schöner int i = emfpangsstring.IndexOf("in = "); if ( i > 0 ) { wert = int.parse( empfangsstring[i+5] ); }
hallo uwe, die hilfsvariable sollte auch als string deklariert werden, oder ? Bei int.parse kommt bei mir die Fehlermeldung, dass int keine Definition für parse enthält...........
sandman schrieb: > die hilfsvariable sollte auch als string deklariert werden, oder ? warum ist es denn ein String? > dass int keine Definition für > parse enthält........... schreib mal int.Parse( empfangsstring[i+5] )
sandman schrieb: > ich meinte die variable wert. da muss ein int sein. > int.Parse kommt auch ein fehler und welcher? kannst du überhaupt Programmieren? Denn solche fehler sollte man schon selber beheben können. int.Parse( empfangsstring[i+5].ToString() )
Wie wäre es denn mit
1 | int empfangPruefen(string empfangsstring) |
2 | {
|
3 | if (empfangssting.Contains("0 = 0") |
4 | {
|
5 | return 0; |
6 | }
|
7 | else if (empfangsstring.Contains("0 = 1") |
8 | {
|
9 | return 1; |
10 | }
|
11 | |
12 | return -1; |
13 | }
|
hallo sven, ich bin programmieranfänger, meine input Variable ist als string deklariert und nennt sich "input".
Also, im Event könntest du in etwa so was machen:
1 | // Vorhandene Daten einlesen
|
2 | input += serialPort1.ReadExisting(); |
3 | |
4 | // Prüfen, ob ein gültiger string empfangen wurde
|
5 | ergebnis = empfangPruefen(input); |
6 | |
7 | // wenn ja, string ausleeren
|
8 | if (ergebnis != -1) |
9 | {
|
10 | input = string.empty; // das gleiche wie input = "" |
11 | }
|
Die Funktion "empfangPruefen" steht in einem meiner Post weiter oben. Worüber du dir jetzt noch Gedanken machen musst ist - kann es sein, dass zwei gültige Testabschnitte in "input" stehen? (wie schnell sendet denn der µC die Daten?) - Wenn ja, wie stelle ich sicher, dass ich alle Daten auch auswerte - Ist es nötig, sicherzustellen, dass nicht zwei Threads gleichzeitig auf die Variablen "input" und "ergebnis" zugreifen? (Hier wieder, wie lange dauert die Abarbeitung des Events und wie schnell kommen Daten am PC an?) - Wenn ja, wie stelle ich das sicher? Reicht ein einfaches lock() { } oder muss ich mir deutlich mehr Gedanken machen? Normalerweise brauchst du dir zum ausprobieren um die Fragen keinen Kopf zu machen. Wenn das allerdings mal irgendwo dauerhaft laufen soll, kannst du dir es nicht leisten, solche Punkte außer Acht zu lassen.
// Vorhandene Daten einlesen input += serialPort1.ReadExisting(); // Prüfen, ob ein gültiger string empfangen wurde ergebnis = empfangPruefen(input); // wenn ja, string ausleeren if (ergebnis != -1) { input = string.empty; // das gleiche wie input = "" } alse den Teil schreibe ich in mein Timer rein ?
Nein. In das Event, dass die serielle Schnittstelle dir rauswirft. Vergiss den Timer einfach ;-)
Reden wir hier etwa über Windows? Ja? Da wird (ganz unten, auf der API-Ebene von Windows) eine Datei aufgemacht, wenn man einen COM-Port öffnen will. Als Ergebnis gibt es ein Handle auf diese Datei - aber es gibt per se keinerlei Empfangs-Event. Möglicherweise gibt es in den Untiefen der zugehörigen C# Runtime irgendeine Hook-Funktion, die über ClearCommError(hPort, dwErrorCode, &statPort) und dann statPort.cbInQue ermittelt, ob es unabgeholte Zeichen gibt und dann einen vorher definierten Event auslöst / über Broadcast oder dediziert ist ja egal. Aber das Ganze scheint mir hier ja völlig daneben zu liegen. Lest doch mal gründlich: sandman schrieb: > ich versuche mit einem Timer in C# über die RS232 - Schnittstelle einen > Eingang vom STM32 ständig abzufragen. Er will "einen Eingang vom STM32 abfragen"! Was soll das? Bloß eine falsche Formulierung? Ich nehme mal an, er will einen Ausgang vom STM32 abfragen, der an irgendein Input-Handshake-Bein der RS232 gelegt wurde. Also, welchen Zustand RTS, DSR usw. haben. Ich kann jedenfalls nicht sehen, daß der STM32 irgendein sinnvolles Zeichen über die eigentliche TxD-->RxD Linie schickt. Also ist es sinnlos, über das Ausfiltern von empfangenen Bytes zu diskutieren. W.S.
In C# wird ein Event ausgelöst, wenn Daten Empfangen wurden. Für eine Änderung der Steuerleitungen wird ebenfalls ein Event ausgelöst.
W.S. schrieb: > Er will "einen Eingang vom STM32 abfragen"! Was soll das? Bloß eine > falsche Formulierung? Ich nehme mal an, er will einen Ausgang vom STM32 > abfragen, der an irgendein Input-Handshake-Bein der RS232 gelegt wurde. Was das soll? Der Zustand eines Eingangs des STM32 soll auf den PC übertragen werden. Glaub es einfach, statt irgendetwas anzunehmen.
Hat das vielleicht was mit einem STM32 in Verbindung mit OBD von Auto's zu tun? Also auswerten einer Meldung von einem Steuergerät des Autos per OBD. Ich vermute das mal, weil anstatt Hyperterminal- oder VT100 Krempel könnten das ja entsprechende "Anweisungen" für's Steuergerät sein, die und die Infos bzw Daten rüber zu geben. Also, hat STM32 in dem Falle was mit OBD zu tun?
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.