mikrocontroller.net

Forum: PC-Programmierung Auf ein Ereignis warten ( Visual C# 2005 Express Edition)


Autor: Tobias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte ein Programm schreiben das Daten über die RS232 an einenen 
Prozessor sendet und dann auf die Antwort wartet. Dann erst soll das 
Programm weiter machen.
Ich habe bereits ein Programm was Daten sendet und auch empfangen kann. 
Über 'serialPort1_DataReceived()' inkl. Threadsicherer Verarbeitung 
klappt das ganze auch soweit. Nur bin ich jetzt mit meinem 
(Anfänger)-Latein am Ende.
Ich möchte im Programm sicher stellen, dass die Antwort auf meine 
Anfrage auch gekommen ist, bevor ich weiter mache.
Es wird wohl irgendwie über Treads gehen. Nur wie kann ich den Thread in 
dem alles läuft anhalten?

Der Ablauf soll in etwa so sein:

1) serialPort1.Write("Hallo");

2) (Warten auf Antwort in 'serialPort1_DataReceived()')

3) Antwort auswerten

4) if(Antwort == ok)
     serialPort1.Write("123");

5) weiter mit 2)

Zur Zeit schreibe ich die Anfragen in einer Funktion untereinander weg 
und werte sie in DataReceived() aus.
Nur sende ich ja die Anfragen hintereinander weg. Und das soll nicht 
sein.

Kann mir da jemand weiterhelfen.

Danke und Grüße
Tobias

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thread ist schon richtig. Dann musst du zuerst ein Event registrieren, 
also der SerialPort komponente bekannt geben, welches Event das 
Empfangs-Event ist. Und dann im Thread einfach WaitOne() mit diesem 
Event benutzen. Dann bleibt der Thread da stehn und macht erst weiter, 
wenn das Event eintritt. Am sinnvollsten nimmt man dafür ein Autoreset 
Event.

Autor: Tobias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Christian,

das klingt ja ganz einfach und genau nach dem was ich suche.
Nur wie mache ich das Code-Technisch?
Vom logischen verstehe ich deine Antwort zwar, kann sie aber leider 
nicht umsetzen :-(
Kannst Du mir da noch ein wenig unter die Arme greifen?

Tobias

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Uff....also Beispielcode hab ich keinen. Einer meiner Hiwis macht das 
momentan für einen CAN-Adapter von IXXAT. Da guck ich immer mal, wie das 
geht.
Zuerst solltest du einfach einen Thread erstellen, wie, steht ja in der 
MSDN Hilfe.
Dann musst du deine Serialport-Klasse hernehmen, wenn´s die aus dem .NET 
Framework ist, gibts ja auch die Anleitung im MSDN. Da halt beim 
Initialisieren das Event registrieren. Das gings mit dem AutoReset 
Event. Such halt mal nach den Begriffen in der MSDN Hilfe. Da findest du 
immer den Beispielcode. im Thread dann einfach WaitOne() aufrufen, als 
Übergabeparameter das Event. Viel mehr kann ich dir leider nicht sagen.
Vielleicht solltest du erst mal einen ganz einfachen Thread 
programmieren, und z.b. mit Thread.Sleep(2000) alle 2000ms irgend ne 
Meldung oder sowas erzeugen, damit du den Mechanismus verstehst.

Autor: Torq (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es geht moeglicherweise noch etwas einfacher. Ich habe das eben so 
geloest, dass ich mir in Thread1 eine Methode definiert habe:

private string serialPort1.sendCommand()

Im Thread dieser Methode wird an den serialPort ein Textstring 
geschickt, und laengstenfalls zwei Sekunden auf Antwort gewartet; 
Rueckgabewert ist entweder die Antwort des Ports oder eine 
Fehlermeldung.

Jetzt ists aber so, dass die Variable, die die Antwort des SerialPorts 
enthalten soll, Teil von Thread1 ist, waehrend der serialPort einen 
eigenen Thread (Thread2) darstellt. Aergerlicherweise wird das Event von 
Thread2 erst dann in die Variable geschrieben, wenn Thread1 nicht mehr 
wartet. Ich wollte aber, dass Thread2 die Antwort direkt in die Variable 
schreibt, sobald sie kommt. Die Loesung ist die Befehlszeile:

Application.DoEvents();

Damit haelt Thread1 an und arbeitet alle anderen Events ab, bevor beim 
urspruenglichen Event weitergemacht wird. Komplett sieht die Loesung so 
aus:


  private string serialPortSendCommand(SerialPort p, String str) {
    int timer = 0;
    p.Write(str);

    while(answer == "" && timer < 40) {
      System.Threading.Thread.Sleep(50);
      Application.DoEvents();
      timer++;
    }
    if (timer > 30) return "Error! No Signal!";
    else return answer;
  }

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wozu überhaupt threads?


 serialPort1.Write("Hallo");
 serialPort1.Read();

fertig. Die Timeouts kann ma ja auch festlegen - ist das zu einfach oder 
überseh ich was?

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter II schrieb:
> wozu überhaupt threads?
>
>
>  serialPort1.Write("Hallo");
>  serialPort1.Read();
>
> fertig. Die Timeouts kann ma ja auch festlegen - ist das zu einfach oder
> überseh ich was?

Das ist die einfachste Variante. Eleganter ist das über Events zu lösen, 
da das ganze Programm da nicht an einer Stelle wartet. Threads nimmt man 
eher bei Asyncronen Aufgaben.

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Samuel K. schrieb:
> Das ist die einfachste Variante. Eleganter ist das über Events zu lösen,
> da das ganze Programm da nicht an einer Stelle wartet.

man kann aber das senden und empfangen komplett im Thread machen. damit 
ist auch beim Senden die GUI noch aktiv.

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das geht auch. Ich persönlich würde es über Events machen und eine 
Variable setzen, ob die Anfrage bestätigt worden ist oder nicht. Bei 
Events ist die GUI übrigens auch noch aktiv.

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Samuel K. schrieb:
> Bei Events ist die GUI übrigens auch noch aktiv.
Dann hast du das Problem aber auch noch beim Senden. Das Blockiert bis 
alle datenn in den Puffer geschrieben sind.

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das dauert aber wenn man nur Steuerbefehle sendert nicht so lang.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.