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.
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.
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() )
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 ?
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.
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?