serielle Schnittstelle mit ReadFile() auslesen
-
Die Frage ist nun, wie kann ich den Rückgabewert, in diesem Fall die Endposition, aus der seriellen Schnittstelle auslesen?
Mein Ansatz ist folgendermaßen:Und was ist das Problem? Funktioniert es oder nicht? Kommt eine Fehlermeldung? ...
2 Dinge fallen mir auf: Rueckgabewert von ReadFile nicht ausgewertet. Man kann mehr als 1 Byte auf einmal auslesen.
Jochen Kalmbach schrieb:
Die serielle Schnittstelle ist nicht trivial. Deshalb würde ich eine fertige Klasse verwenden... z.B.:
http://www.codeproject.com/Articles/992/Serial-library-for-CNaja, geht so. Man muss nicht unbedingt overlapped io verwenden.
-
knivil schrieb:
Jochen Kalmbach schrieb:
Die serielle Schnittstelle ist nicht trivial. Deshalb würde ich eine fertige Klasse verwenden... z.B.:
http://www.codeproject.com/Articles/992/Serial-library-for-CNaja, geht so. Man muss nicht unbedingt overlapped io verwenden.
Aber man kann die Klasse verwenden, die das tut.
Zudem ist dann die Anwendnung nicht blockierend und man muss nicht pollen.
-
Ja.
-
Hallo,
danke für die Antworten. Es funktioniert ohne Fehlermeldung, es gibt allerdings immer den gleichen Wert für ReplyData zurück. Immer 128.
@knivil: Hier wird der Rückgabewert von ReadFile ausgewertet, oder nicht ?
if ( BytesRead > 0 ) // A byte is read { RxBuffer[RxCount] = TempByte; // Store the byte RxTimeStamp = timeGetTime(); // reload timestamp }
Ich lese immer nur 1 byte aus und speichere es dann im Vector.
Vielen Dank!
-
Nein, dort wertest du einen InOut-Parameter aus. Ansosnten: Baue ein Minimalbeispiel, hier sind noch viele Sachen unbekannt, beispielsweise welchen Wert hat PSerial_Packetsize, welche Packetgroesse sendet dein Motor, wie ist das Paketformat, ... und: Hast du schon die verlinkte Klasse ausprobiert?
-
ich probiere gerade die fertige Klasse aus....
Falls das nicht funktioniert, melde ich mich wieder!
Danke
-
starter88 schrieb:
@knivil: Hier wird der Rückgabewert von ReadFile ausgewertet, oder nicht ?
if ( BytesRead > 0 ) // A byte is read { RxBuffer[RxCount] = TempByte; // Store the byte RxTimeStamp = timeGetTime(); // reload timestamp }
Nein, ReadFile hat noch einen "direkten" Rückgabewert vom Typ BOOL. Den wertest du gar nicht aus.
Und es fehlt der Else-Zweig.
Deine Schleife geht davon aus, dass in jedem Durchlauf ein Byte gelesen wird. Dann hast du das "if (hats_denn_wirklich_funktioniert)", aber kein "else". D.h. wenn in einem Durchlauf nix gelesen wird, dann wird das Byte in RxBuffer einfach übergangen. Nicht gerade sehr robust.Besser wäre eine Schleife ala
while (not timeout and not message complete) { try to read something if (read was successful) append read data to message buffer } if (not message complete) handle error
Und natürlich müsste man wissen welche Timeout Einstellungen du verwendest (SetCommTimeouts).
Eine fertige Klasse zu verwenden ist aber vermutlich die bessere Lösung. Speziell wenn man noch nicht mehrere Jahre Windows Systemprogrammierung auf dem Buckel hat.
-
Ich habe nun eine fertige Klasse verwendet. Das Schreiben funktioniert wunderbar, allerdings bekomme ich beim Lesen keine vernünftigen Werte heraus.
Hier ist mein Codebool Init_Port_and_Zaber(CString port_name) { if (!port.OpenPort(port_name)) { printf("Cannot open port.\n"); printf("Please check that you typed in the correct name,\n"); printf("and check that the requested port is not currently being used.\n"); printf("press any key to exit..."); return 0; } else if (!port.ConfigurePort(CBR_9600, 8, false, NOPARITY, ONESTOPBIT)) // Baudrate 9600, data byte=8, parity=false, NOPARITY, stopbit=1 { printf("Cannot configure port.\n"); return 0; } //else if (!port.SetCommunicationTimeouts(MAXWORD,0,0,0,0)) else if (!port.SetCommunicationTimeouts(50,10,50,10,50)) { printf("Set Communication not successful.\n"); return 0; } port.send_command(0,2,0); // renumber actuators Sleep(800); Command = 1; port.send_command(0,Command,0); // send all actuators to home position return 1; }
Und hier die Funktion zum Senden und Empfangen der Bytes. Das Senden funktioniert einwandfrei.
BOOL CSerialPort::send_command(unsigned char Unit, unsigned char Command, long Data) { static unsigned char OutBuffer[6]; static unsigned char ReadBuffer[6]; OutBuffer[0] = Unit; OutBuffer[1] = Command; cout <<"Unit "<<OutBuffer[0]<< endl; cout <<"Command"<<OutBuffer[1]<< endl; if(Data<0) { Data = 256*256*256*256 + Data; } float scale; scale=0; scale = 256*256*256; OutBuffer[5] = floor (Data/scale); Data = Data-OutBuffer[5]* scale; scale = 256*256; OutBuffer[4] = floor(Data/scale); Data = Data-OutBuffer[4] * scale; scale = 256; OutBuffer[3] = floor(Data/scale); Data = Data-OutBuffer[3] * scale; OutBuffer[2] = Data; cout <<"Out Buffer 5 "<<OutBuffer[5]<< endl; cout <<"Out Buffer 4"<<OutBuffer[4]<< endl; cout <<"Out Buffer 3"<<OutBuffer[3]<< endl; cout <<"Out Buffer 2"<<OutBuffer[2]<< endl; //iBytesWritten=0; //if(WriteFile(hComm,OutBuffer,6,&iBytesWritten,NULL)==0) //return false; //else return true; for (int i=0; i<6; i++) { WriteByte(OutBuffer[i]); } for (int i=0; i < 6; i++) { ReadByte(ReadBuffer[i]); } unsigned char Unit_1 = ReadBuffer[0]; unsigned char Command_1 = ReadBuffer[1]; cout <<"Return Unit"<<Unit_1<< endl; cout <<"Return Command"<<Command_1 << endl; double Reply_Data; Reply_Data = (256*256*256)*ReadBuffer[5] + (256*256)*ReadBuffer[4] + 256*ReadBuffer[3] + ReadBuffer[2]; if (ReadBuffer[5]>127) { Reply_Data = Reply_Data - (256*256*256*256); cout <<"buffer bigger than 127 "<< endl; } return true; }
Ich vermute ich mache irgendetwas falsch, beim setzen der Timeouts. Über Tipps wäre ich sehr dankbar!
-
Hi Leute,
hier ist ein Link zu einer sehr guten Toolbox für die COM Schnittstelle:
http://members.inode.at/anton.zechner/az/ComTools.zip
MfG
-
Siehe auch www.codeproject.com...
-
Wie stellst du fest, dass Senden funktioniert und Empfangen nicht?