Warte-Schleife mit Event-Handling gesucht



  • Hallo zusammen!

    Ich möchte einen Sensor über COM-Schnittstelle ansteuern und benutze dazu die ActiveX-Komponente "MS Communication Control"
    Das funktioniert recht gut.
    Der Sensor an sich ist gelagert auf einem Schrittmotor, um den Sensor um 360° drehen zu können.

    Jetzt will ich eine Schleife basteln, in der bei jedem Schleifendurchgang der Schrittmotor um einen Schritt weiter fährt und dann wartet, bis ein Messwert vom Sensor eingelesen und in eine FlexGrid-Tabelle gebracht wurde.

    Das Problem ist, eine Warte-Funktion zu basteln, um das Weiterdrehen des Motors so lang herauszuzögern bis der Messwert in der FlexGrid-Tabelle ist.

    Mit einer Sleep-Funktion:

    void CSchrittmotorDlg::Sleep(int Delay)
    {
    	// die nachfolgende Funktion macht genau die Anzahl an MilliSekunden, wie im Fenster
    	// der Wartezeit eingetragen wurde
    	long time1 = clock();
    	long time2 = clock();
    
    	while (time2 - time1 < Delay)		// in time1 bleibt die vorher initialisierte Zeit
    	{
    	time2 = clock();				// time2 wird ständig aktualisiert
    	}									// wenn der Unterschied zwi beiden Zeiten mehr als 100 ist, gehts weiter im Hauptprogramm
    }
    

    kann ich zwar warten, aber währenddessen sind keine weiteren Events zugelassen.

    Also meine Frage:

    Wie kann ich eine Sleep-Funktion schreiben, die auch andere Events (in dem Fall den "CommEvent") zulässt?

    Danke im Voraus...



  • Die Sleep ist dafür nicht geeignet, da sie wie Du schon sagst die Nachrichtenverarbeitung blockiert. Lagere alles was die Schnittstellenansteuerung angeht in einen Worker-Thread aus und kommuniziere mit selbstdefinierten Nachrichten. So bleibt die Nachrichtenverarbeitung im Hauptthread arbeitsfähig.
    Kannst auch bei Codeprojekt die Klasse CSerial dafür holen und verwenden. Ich arbeite gerade selbst damit. Man muss sich nur erst mal da reinarbeiten, dann ist das eine prima Sache. Threads werden dort schon automatisch in der Klasse gehandled....



  • Du könntest auch Events nutzen und mit WaitForSingleObject() auf das Eintreffen warten. In der MSDN gibt es dazu auch ein paar Beispiele.



  • Danke euch beiden!

    Mit der Serial.h hatte ich es auch schon mal versucht, das war mir aber zu undurchsichtig, sodass ich bei der MS CommControl gelandet bin ,aber wenn Du sagst, dass es mit der Serial.h funktioniert, dann schau ich mir das noch mal an...

    Und die Sache mit dem WaitFor SingleObject() werd ich auch weiterverfolgen!

    Vielen Dank dafür!



  • AndyDD schrieb:

    Die Sleep ist dafür nicht geeignet, da sie wie Du schon sagst die Nachrichtenverarbeitung blockiert. Lagere alles was die Schnittstellenansteuerung angeht in einen Worker-Thread aus und kommuniziere mit selbstdefinierten Nachrichten. So bleibt die Nachrichtenverarbeitung im Hauptthread arbeitsfähig.
    Kannst auch bei Codeprojekt die Klasse CSerial dafür holen und verwenden. Ich arbeite gerade selbst damit. Man muss sich nur erst mal da reinarbeiten, dann ist das eine prima Sache. Threads werden dort schon automatisch in der Klasse gehandled....

    Hallo!

    Hab mich mal kundig gemacht zwecks der Serial.h, aber es bleiben trotzdem Fragen offen:
    Die Serial.h und die Serial.cpp hab ich von der Seite: http://www.winapi.net/index.php?inhalt=t3

    Hier erstmal mein Code:

    void CSer_testDlg::OnOK() 
    {
    CSerial serial;
    
    char r		= 'r';
    char s		= 's';
    char t		= 't';
    char a		= 'a';
    char D		= 'D';
    char Sechs	= '6';
    char Vier 	= '4';
    char CR		= '\r';
    char LF		= '\n';
    
    char* lpBuffer = "";
    
    serial.Open(3, 9600, 8, 2, 1);		// öffne COM-Port #3 mit 9600 Baud, 8 Datenbits, 
    					// 2 Stopbits, ungerade Parität
    
    // senden der einzelnen Zeichen notwendig, da der Sensor zu langsam ist, um einen String zu verarbeiten
    serial.WriteCommByte(r);
    m_Edit2 = serial.ReadData(lpBuffer);
    serial.WriteCommByte(s);
    m_Edit2 = serial.ReadData(lpBuffer);
    serial.WriteCommByte(t);
    m_Edit2 = serial.ReadData(lpBuffer);
    serial.WriteCommByte(a);
    m_Edit2 = serial.ReadData(lpBuffer);
    serial.WriteCommByte(t);
    m_Edit2 = serial.ReadData(lpBuffer);
    serial.WriteCommByte(D);
    m_Edit2 = serial.ReadData(lpBuffer);
    serial.WriteCommByte(Sechs);
    m_Edit2 = serial.ReadData(lpBuffer);
    serial.WriteCommByte(Sechs);
    m_Edit2 = serial.ReadData(lpBuffer);
    serial.WriteCommByte(Vier);
    m_Edit2 = serial.ReadData(lpBuffer);
    serial.WriteCommByte(CR);
    m_Edit2 = serial.ReadData(lpBuffer);
    serial.WriteCommByte(LF);
    m_Edit2 = serial.ReadData(lpBuffer);
    
    UpdateData(FALSE);
    }
    

    Meinen Sensor muss ich z.B. mit dem Befehl "rstatD664\r\n" ansprechen.
    Erst wenn das \n erfolgt ist, antwortet er mir.

    Frage 1: Dann muss die Datenübertragung nonoverlapped sein, oder?
    Frage 2: Warum muss nach jedem WriteCommByte ein ReadData kommen? (Ansonsten sendet er gar nix, ich will aber noch nichts empfangen)
    Frage 3: Wie stelle ich die Schnittstelle in Empfangsbereitschaft nachdem der Befehl gesendet wurde?
    Frage 4: Die Sache mit dem Multi-Threading, ist das hier automatisch oder muss ich das auch einstellen?

    Ich simuliere den Sensor zum Teil mit einem anderen Rechner, wobei der Datentransfer über ein gekreuztes serielles Kabel erfolgt, so kann ich auch die Antwort des Sensors simulieren und sehe was mein Prog rausschickt...

    Danke im Voraus und Sorry für meine Unwissenheit... 😕

    Andi


Log in to reply