Wegaufnehmer über COM ansprechen



  • Hallo liebes Forum!

    Ich habe hier einen kleinen Beschleunigungsaufnehmer, der über USB über einen Virtuellen COM-Port mit meinem PC verbunden ist. Über das Hyper Terminal ist es mir möglich auf den Wegaufnehmer unter Verwendung vom Hersteller mitgelieferter Funktionen mit ihm zu kommunizieren. Nun möchte ich das aber auch über ein C++ Programm tun. Dazu habe ich folgenden Code geschrieben:

    int main(array<System::String ^> ^args)
    {
    	BOOL bPortReady;
    	HANDLE hCom;
    	LPCWSTR sComPort = L"Com3";
    	DCB dcb;
    	COMMTIMEOUTS CommTimeouts;
    	BOOL bWriteRC;
    	DWORD iBytesWritten;
    
    	hCom = CreateFile(sComPort,
    					GENERIC_READ | GENERIC_WRITE, 
    					0,
    					NULL,
    					OPEN_EXISTING,
    					0,
    					NULL);
    
    	bPortReady = GetCommState(hCom, &dcb);
    	dcb.BaudRate = CBR_115200;
    	dcb.ByteSize = 8;
    	dcb.Parity   = NOPARITY;
    	dcb.StopBits = ONESTOPBIT;
    	dcb.fAbortOnError = true;
    
    	bPortReady = SetCommState(hCom, &dcb);
    
    	CommTimeouts.ReadIntervalTimeout = 50;
    	CommTimeouts.ReadTotalTimeoutConstant = 50;
    	CommTimeouts.ReadTotalTimeoutMultiplier = 10;
    	CommTimeouts.WriteTotalTimeoutConstant = 50;
    	CommTimeouts.WriteTotalTimeoutMultiplier = 10;
    
    	bPortReady = SetCommTimeouts(hCom, &CommTimeouts);
    
    	bWriteRC = WriteFile(hCom, "*start\r", 7, &iBytesWritten, NULL);
    	getchar();
    	bWriteRC = WriteFile(hCom, "*Zon\r", 5, &iBytesWritten, NULL);
    	getchar();
    	bWriteRC = WriteFile(hCom, "*Zoff\r", 6, &iBytesWritten, NULL);
    
    	CloseHandle(hCom);
        return 0;
    }
    

    Eigentlich müsste sich durch den Befehl "Zon" und "Zoff" die Farbe einer Diode auf der Platine des Beschleunigungsmessers ändern, tut sie aber nicht. Hat jemand eine Idee warum nicht?



  • Du prüfst hier keinerlei Rückgabewerte. Ist CreateFile denn erfolgreich gewesen? Was steht in iBytesWritten?

    P.S.: Vielleicht hilft es, den Port mit PurgeComm erstmal zu säubern, bevor du deinen Kram dahin schickst.

    P.P.S.: Es gibt fertige Klassen, die die Kommunikation über die serielle Schnittstelle vereinfachen und nicht so fehleranfällig sind wie ein eigener Versuch. Such z.B. mal auf CodeProject.com nach CSerial.

    EDIT: hat sich erledigt... 🤡



  • Das öffnen des Portes funktioniert ganz wunderbar. Und die Prüfung hat ich auch schon mal in einer früheren Version Implementiert. Die hatte ebenfalls keine Beanstandung geliefert. Ich glaube der Fehler muss irgendwie mit dem WriteFile zusammen hängen, lass mich aber gern eines besseren belehren.

    PurgeComm hab ich jetzt mal bei hinzugefügt, ohne nennenswerten Erfolg.

    Ich guck mir derweil mal die Klasse CSerial an.

    SetCommState ist in Zeile 26.



  • StinkePunk schrieb:

    SetCommState ist in Zeile 26.

    Ja, hab's dann doch gesehen und meinen Beitrag schon editiert. Meine Augen werden wohl schon schlechter... 🤡 😃



  • Ich hab's irgendwann mal so gemacht:

    PurgeComm(XXXHandle->hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
    
          for(UINT i=0;i<strlen(sendBuffer);i++) {
            rtn=WriteFile(pXXLMotorHandle->hPort,&sendBuffer[i],(DWORD)1,&dwBytesWritten,NULL);
          }
    

    Hier schreibe ich also byteweise. Welcher Sinn dahinter steckte, kann ich dir heute leider auch nicht mehr sagen. Aber vielleicht hatte ich ähnliche Probleme und hab es so lösen können. Keine Ahnung (ist auch nix, was an den Kunden gegangen ist)...



  • StinkePunk schrieb:

    [cpp]int main(array<System::String ^> **^**args)

    2fache XOR-Operation? Warum das denn? Kompiliert das überhaupt?



  • tha_specializt schrieb:

    StinkePunk schrieb:

    [cpp]int main(array<System::String ^> **^**args)

    2fache XOR-Operation? Warum das denn? Kompiliert das überhaupt?

    C++/CLI-Kram... Er ist im Grunde im falschen Forum. Da der betreffene Code aber nix mit managed Kram zu tun hat, hab ich mal nix gesagt.



  • Genau. Ich Programmiere mit VC++2008, wollte aber reinen unmanaged code haben. Das (array<System::String ^> ^args) ist so ein Relikt.



  • StinkePunk schrieb:

    Genau. Ich Programmiere mit VC++2008, wollte aber reinen unmanaged code haben.

    Was heißt aber? VC++2008 heißt doch nicht automatisch managed, und alles andere ist die Ausnahme! Tss, tss... 😉



  • Nun, hab in letzter Zeit so viel managed Code geschrieben, dass ich schon kaum noch weiß, dass VC++ auch anders kann 🤡



  • Ich hab das jetzt mal so probiert:

    PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);
    	getchar();
    	char start[7] = "*start";
    	for(int i = 0; i < 7; i++){
    		bWriteRC = WriteFile(hCom, (LPCVOID)start[i], 1, &iBytesWritten, NULL);
    	}
    
    	PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);
    	getchar();
    	char Zon[5] = "*Zon";
    	for(int i = 0; i < 4; i++){
    		bWriteRC = WriteFile(hCom, (LPCVOID)Zon[i], 1, &iBytesWritten, NULL);
    	}
    
    	PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);
    	getchar();
    	char Zoff[6] = "*Zoff";
    	for(int i = 0; i < 5; i++){
    		bWriteRC = WriteFile(hCom, (LPCVOID)Zoff[i], 1, &iBytesWritten, NULL);
    	}
    

    aber auch ohne Erfolg.


Log in to reply