Frequenz über Eingang der RS232 einlesen



  • Hi!
    Ich brauche Hilfe. Ich möchte gerne eine Frequenz, die von einem
    Inkrementalgeber erzeugt wird, über einen Eingang der RS232
    einlesen. Ich habe es zwar schon so versucht, aber die Genauigkeit
    lässt hier schwer zu wünschen übrig:

    GetCommModemStatus(hCom, &COMStatus); 
    
    	if (COMStatus == MS_RING_ON)
    	{
    		while (COMStatus & MS_RING_ON) {GetCommModemStatus(hCom, &COMStatus);}
    		begin = read_time();
    		while (!(COMStatus & MS_RING_ON)) {GetCommModemStatus(hCom, &COMStatus);}
    		end = read_time();
    	}
    	else
    	{
    		while (!(COMStatus & MS_RING_ON)) {GetCommModemStatus(hCom, &COMStatus);}
    		begin = read_time();
    		while (COMStatus & MS_RING_ON) {GetCommModemStatus(hCom, &COMStatus);}
    		end = read_time();
    	}
    

    Windows ist kein Echzeitbetriebssystem, das ist schon klar, aber irgendwie
    muss es doch möglich sein, die Frequenzen sauber einlesen zu können.
    Danke schon mal.
    mfg fritze



  • Meinst Du sowas?

    CTS_ON : 3744724586 µs
    DSR_ON : 3744724586 µs
    DSR_OFF: 3744724857 µs
    CTS_OFF: 3744724937 µs
    CTS_ON : 3744725028 µs
    CTS_OFF: 3744726955 µs
    DSR_ON : 3744727030 µs
    CTS_ON : 3744727100 µs
    CTS_OFF: 3744728906 µs
    CTS_ON : 3744728986 µs
    CTS_OFF: 3744730860 µs
    CTS_ON : 3744730939 µs
    CTS_OFF: 3744732821 µs
    CTS_ON : 3744732903 µs
    

    Wie hoch sind denn die Frequenzen?

    Blackbird



  • kannst es so machen:
    ein Thread erfasst alle Pegelaenderungen an der COM und sendet sie mit einem TimeStamp an einen anderen Thread der sie auswertet, speichert, ...

    Hier sind Ausschnitte aus den Threads, die das Prinzip zeigen (hab' jetzt keine Lust, das Ueberfluessige rauszustreichen).
    COMThread:

    ...
    
    	// Auf Events warten:
    	while (!pparams->ThreadStoppen) // solange weitermachen bis TRUE
    	{
    		WaitCommEvent (hCom, &dwEvtMask, &o);  // EventMask "scharf machen"
    		// kommt der Event, ist auch die dwEvtMask geladen und es kann weitergehen
    		if (WAIT_OBJECT_0 == WaitForSingleObject (o.hEvent, INFINITE)) // warten bis Event
    		{
    			lTime = queryPrecisionTimeStamp ();  // Zeit holen
    			// Message senden. In dwEvtMask können mehrere Ereignisse gesetzt sein
    			bRet = PostThreadMessage (dwMonitorThreadId, (QS_ALLPOSTMESSAGE + MSG_TIME), 
    					(WPARAM)dwEvtMask , (LPARAM)lTime);
    		}    // end of: if (WAIT_OBJECT_0 == ...
    	}      // end of: while (...
    ...
    

    MonitorThread:

    ...
    	// create a queue for the thread
    	PeekMessage ((LPMSG)&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
    	// sent event after queue creation back to the threads creator
    	bRet = SetEvent (hEvent);
    
    	printf ("\r\nMonitorThread: warte auf Events ...");
    
    	// get messages by message from threads local queue
    	while ((bRet = GetMessage (&msg, NULL, 0, 0)) != 0)
    	{
    		if (bRet == -1)
    		{ // handle the error and possibly exit
    			MessageBox (NULL, "MonitorThread: GetMessage error", "COM Port:", MB_OK | MB_ICONSTOP);
    			return NULL;  // error!
    		}
    		else  
    		{ // a valid message is received
    			switch (msg.message)
    			{
    			case (QS_ALLPOSTMESSAGE + MSG_COMOPEN):
    				printf ("\r\nMonitorThread: MSG_COMOPEN: lParam=0x%08x wParam=0x%08x", 
    					msg.lParam, msg.wParam);
    				break;
    
    			case (QS_ALLPOSTMESSAGE + MSG_COMCLOSE):
    				printf ("\r\nMonitorThread: MSG_COMCLOSE: lParam=0x%08x wParam=0x%08x", 
    					msg.lParam, msg.wParam);
    				break;
    
    			case (QS_ALLPOSTMESSAGE + MSG_TIME):
    				// Time stamp message: lParam=time, wParam=dwEvtMask
    				szMsg[0] = '\0';
    
    				if (DWORD(msg.wParam) & EV_CTS)
    				{
    					GetCommModemStatus (hCom, &COMStatus);
    					if (COMStatus & MS_CTS_ON)
    					{ // CTS (Pin8) activated
    						wsprintf (szMsgTmp, "\r\nCTS_ON : %lu µs", msg.lParam);
    					}
    					else
    					{ // CTS (Pin8) deactivated
    						wsprintf (szMsgTmp, "\r\nCTS_OFF: %lu µs", msg.lParam);
    					}
    					Ccts.WriteSaveFile (szMsgTmp, strlen (szMsgTmp));
    					Call.WriteSaveFile (szMsgTmp, strlen (szMsgTmp));
    					strcat (szMsg, szMsgTmp);
    				}
    
    				if (DWORD(msg.wParam) & EV_DSR)
    				{
    					GetCommModemStatus (hCom, &COMStatus);
    					if (COMStatus & MS_DSR_ON)
    					{ // DSR (Pin6) activated
    						wsprintf (szMsgTmp, "\r\nDSR_ON : %lu µs", msg.lParam);
    					}
    					else
    					{ // DSR (Pin6) deactivated
    						wsprintf (szMsgTmp, "\r\nDSR_OFF: %lu µs", msg.lParam);
    					}
    					Cdsr.WriteSaveFile (szMsgTmp, strlen (szMsgTmp));
    					Call.WriteSaveFile (szMsgTmp, strlen (szMsgTmp));
    					strcat (szMsg, szMsgTmp);
    				}
    ...
    

    Damit habe ich die Liste im Post weiter oben erstellt.

    Blackbird



  • Hey!
    Hab das jetzt so gemacht, und es funktioniert!
    DANKE für die Hilfe!!!
    mfg fritze



  • Hey blackbird!
    Ich bräuchte nochmals deine Hilfe!
    Es geht um folgendes:
    Der Inkrementalgeber (Hengstler RI32) erzeugt Frequenzen und sendet
    diese über zwei Kanäle. Kanal A und Kanal B.
    Kanal A habe ich mit dem Eingang DCD der RS232 verbunden.
    Kanal B habe ich mit dem Eingang RI der RS232 verbunden.
    Beim Eingang DCD bekomm ich schöne Frequenzen, egal welcher
    Kanal angeschlossen ist. Nur beim Eingang RI geht gar nix oder fast
    gar nix, obwohl ich ihn beim monitoring gleich behandle wie DCD.

    Ich habe mal einen Testlauf gemacht um dir das zu veranschaulichen:
    Inkrementalgeber dreht sich gleichmäßig für fünf Sekunden nach rechts und müsste 125 Hz liefern. Beim diesem Testlauf habe ich berechnet wie oft
    sich der Status auf den Eingängen DCD und RI ändert, und wie oft die
    jeweiligen Eingänge 1 oder 0 bekommen.

    state_changed_counter_DCD: 624
    state_changed_counter_RI: 623
    
    DCD_ON:  312
    DCD_OFF: 312
    
    RI_ON:   0
    RI_OFF:  623
    

    Die Frequenzen die der Inkrementalgeber erzeugt sind völlig in Ordnung,
    da ich sie mit dem Oszi mehrmals gemessen habe.

    Ich weiß das ist jetzt viel auf einmal, aber ich weiß echt nicht mehr
    weiter.

    Danke schonmal
    mfg fritze


Anmelden zum Antworten