Com Port Rückgabe

Gast #2695388
Lesenswert?

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.
#2695528
Lesenswert?

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 ;-)
Gast #2695592
Lesenswert?

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.
#2695640
Lesenswert?

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.
Gast #2695670
Lesenswert?

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.
Gast #2695684
Lesenswert?

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
#2695721
Lesenswert?

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
#2695762
Lesenswert?

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.
Gast #2695771
Lesenswert?

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?
Gast #2695773
Lesenswert?

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
Gast #2695828
Lesenswert?

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");
    }
}
#2696912
Lesenswert?

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.
Gast #2696992
Lesenswert?

// 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 ?
Gast #2697929
Lesenswert?

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.
Gast #2700521
Lesenswert?

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.
Gast #2704158
Lesenswert?

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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren