Mal wieder der ComPort, 2 Versionen, fast gleich eine tut eine nicht
-
Ja, die überschrift ist nicht sehr aussagekräftig,
wusste nicht wie ich mein Problem kurz beschreiben soll.
Ich habe eine ComPort Klasse, in einer älteren Version setze ich
gleich beim öffnen auch alle Parameter also, Baudrate, parity Bits,
etc.. in einer neuen Version habe ich das in zwei Methoden
aufgeteilt. Das Problem ist jetzt das die alte Klasse funktioniert
und die neue Klasse nicht. Der restliche Code in der Klasse ist
unverändert oder nur irrelevant. Das Error Handling habe ich
teilweise entfernt, ist so noch genug Code.Die alte Version
void ComPort::openPort(string port) { bool abbruch = false; string temp; // Handle öffnen temp = "\\\\.\\" + port; comHandle = CreateFile( temp.c_str(), // Com Port Name GENERIC_READ | GENERIC_WRITE, 0, // exclusiv Zugriff NULL, // default Security Attribut OPEN_EXISTING, // muss halt so sein 0, // not overlapped I/O NULL // muss NULL sein für Com Zugriff ); // Error Handling if(comHandle == INVALID_HANDLE_VALUE && abbruch != true) { // error handling... -> Funktion wird NICHT abgebrochen } // momentane config auslesen bool hatGeklappt; hatGeklappt = GetCommState(comHandle, &configuration); // Error Handling if(hatGeklappt != true && abbruch != true) { // error handling... -> Funktion wird NICHT abgebrochen } // config Befüllen configuration.DCBlength = sizeof(DCB); configuration.BaudRate = CBR_38400; configuration.ByteSize = 8; configuration.Parity = NOPARITY; configuration.StopBits = ONESTOPBIT; // Daten schreiben hatGeklappt = SetCommState(comHandle, &configuration); // Error Handling if(hatGeklappt != true && abbruch != true) { // error handling... -> Funktion wird NICHT abgebrochen } else if(abbruch != true) { // error handling... -> Funktion wird NICHT abgebrochen } }
Die neue Version
int ComPort::openPort(string port) { string temp; // Handle öffnen temp = "\\\\.\\" + port; comHandle = CreateFile( temp.c_str(), // Com Port Name GENERIC_READ | GENERIC_WRITE, 0, // exclusiv Zugriff NULL, // default Security Attribut OPEN_EXISTING, // muss halt so sein 0, // not overlapped I/O NULL // muss NULL sein für Com Zugriff ); // Error Handling if(comHandle == INVALID_HANDLE_VALUE) { lastError = "Fehler beim öffnen: " + valueToString(GetLastError()); return -1; } else { lastError = "ComPort erfolgreich geöffnet"; return 0; } } // Aufruf sieht so aus: cp->setCommConfig(CBR_38400, 8, NOPARITY, ONESTOPBIT); int ComPort::setCommConfig(int baudRate, int bytes, int parity, int stopBits) { // momentane config auslesen bool hatGeklappt; hatGeklappt = GetCommState(comHandle, &configuration); // Error Handling if(hatGeklappt != true) { lastError = "Fehler beim config lesen: " + valueToString(GetLastError()); return -1; } // config Befüllen configuration.DCBlength = sizeof(DCB); configuration.BaudRate = baudRate; configuration.ByteSize = bytes; configuration.Parity = parity; configuration.StopBits = stopBits; // Daten schreiben hatGeklappt = SetCommState(comHandle, &configuration); // Error Handling if(hatGeklappt != true) { lastError = "Fehler beim config schreiben: " + valueToString(GetLastError()); return -1; } else { lastError = "Config erfolgreich geschrieben"; return 0; } }
Danke an alle die sichs durchlesen!
Gruß,
Max
-
Uns allen würde viel mehr weiterhelfen (oder zumindestens weniger Ratespiele a la Kristallkugel) wenn präzisere Problembeschreibung ins Forum gepostet werden.
Die pauschale Aussage "funktioniert nicht" ist hier Forum nicht gern gesehen.
Nun, um die Ursache Deines Problems einzugrenzen, welcher Text wird beim Öffnen des COM-Ports ausgegeben? Den Text "Fehler beim öffnen: xx" oder den Text "ComPort erfolgreich geöffnet"?
Martin
-
Nach jeder API Funktion, bei der du Probz vermutest, GetLastError() nutzen. Ich versteh ned warum ihr ned mal GetLastError() benutzt, die funktion ist ned nur zur zierde da. sie liefert euch so gut wie immer einen aussagekräftigen fehlercode zurück.
-
Oder benutze doch einfach eine getestete und sauber geschriebene Klasse die schon existiert:
http://www.codeproject.com/KB/system/serial.aspx
-
So, stimmt ich sollte den Fehler genauer beschreiben.
GetLastError benutze ich hab nur das Error Handling teils rauseditiert
damits überischtlicher wird.Neine, eine fertige Klasse möchte ich nicht, danke
Das Problem ist nichtmal das öffnen, sondern das schreiben.
Nur, die write Methode ist bei beiden Versionen exakt gleich,
ich habe das Problem schon auf diesen Part eingegrenzt. Irgendwo
in diesem Code muss ein Fehler sein welcher dazu führt das ich mit
der alten Version anderst schreibe als in der neuen.
WriteFile führt auch zu keinem Fehler, alles kein Problem, der Fehler
muss irgendwie bei SetCommState liegen vermute ich.Gruß,
Max
-
dann guck halt ob das handle in der funktion auch echt noch gültig ist und die anderen werte, ist doch easy
-
blub² schrieb:
WriteFile führt auch zu keinem Fehler, alles kein Problem, der Fehler muss irgendwie bei SetCommState liegen vermute ich.
Wenn WriteFile zu keinem Fehler führt, dann kann SetCommState auch nicht der Fehler sein.
Irgendwie beschreibst (und postest) Du nur die Hälfte des Problems.
-
blub² schrieb:
Neine, eine fertige Klasse möchte ich nicht, danke
Dann ist Dir allgemein kaum helfen. Warum willst Du das nicht?
-
Naja, soweit zu gehen, ihm zu sagen, ihm sei nicht mehr zu helfen, würde ich nicht wagen
Ernsthaft gibt es schon sinnvolle Erwägungen, die jemanden dazu bringen, keine vorgefertigten Klassen zu nehmen. Didaktisch, d.h. man möchte es durch selbermachen verstehen (laut Pädagogen und Didaktikern die besten Lernweise). Oder die Software darf keine 3rd-Party-Sachen enthalten, Stichwort Lizenzbindung an z.B. GPL oder ähnliches. Und selbst völlig freie Dinge dürfen nicht immer verwendet werden, manche Kunden möchten gerne alles neu und aus einer Hand haben.
Manchmal muss man es einfach selbst machen...
-
blub² schrieb:
// config Befüllen configuration.DCBlength = sizeof(DCB); configuration.BaudRate = baudRate; configuration.ByteSize = bytes; configuration.Parity = parity; configuration.StopBits = stopBits;
Ich würde die DCB-Struktur grundsätzlich komplett neu definieren (also auch die anderen Members).
Ansonsten hast Du hin und wieder gefährliche Stolperfallen, wenn Du beim Auslesen mit GetCommState() plötzlich "Handshake aktiviert" usw. in der Struktur vorfindest.Martin
-
mad_martin schrieb:
Didaktisch, d.h. man möchte es durch selbermachen verstehen (laut Pädagogen und Didaktikern die besten Lernweise).
Das meine ich
Ok, um mal mein Problem noch genauer zu beschreiben:
Ich schreibe ein Programm das Daten in den Speicher einer
Maschine schreibt. Mit der älteren Version funktioniert das wunderbar,
mit der neueren nicht!
Das komische: Ich schreibe mit beiden Versionen genau die
gleichen Daten in die Schnittstelle (überprüft mit so einem Serial
Port Monitor Tool). Allerdings kriege ich nur eine Antwort
von der Maschine wenn ich die alte Version benutze.
Die Write Methode ist > exakt < gleich geblieben (copy & paste ;)),
nur die open Methode hat sich verändert durch das zerlegen in zwei
Methoden.Naja, ich werd noch ein bisschen rumprobieren und mich nochmal melden.
Gruß,
Max
PS: Danke Mmacher, werde ich noch implementieren!
-
blub² schrieb:
Die Write Methode ist > exakt < gleich geblieben (copy & paste ;)),
nur die open Methode hat sich verändert durch das zerlegen in zwei
Methoden.Da kommt in mir der Verdacht auf, daß Du mit dem Handling von Variablen irgendwas falsch gemacht hast.
Beispiele (in Anlehnung an Deine Quellcodes wieiter oben):
-Gültigkeit der lokalen Variablen?
-Übergebe ich wirklich einen Pointer zum String (und nicht etwa nur den ersten Buchstaben) an die Funktionen
-Zeigt der Pointer auf einen gültigen Speicherbereich? Ist dieser Speicher auch reserviert?Martin
P.S.: Was passiert eigentlich, wenn Du die beiden zerlegten Open-Funktionen wieder zu einer zusammenfügst? Gleiches Fehlerbild?
-
blub² schrieb:
Die Write Methode ist > exakt < gleich geblieben (copy & paste), nur die open Methode hat sich verändert durch das zerlegen in zwei
Methoden.Schon besser. Greift zwischen beiden Aufrufen ev. etwas auf den Port zu (Taskswitch reicht schon) ?
-
Taskswitch?wie soll er den denn verhindern
-
merker schrieb:
blub² schrieb:
Die Write Methode ist > exakt < gleich geblieben (copy & paste), nur die open Methode hat sich verändert durch das zerlegen in zwei
Methoden.Schon besser. Greift zwischen beiden Aufrufen ev. etwas auf den Port zu (Taskswitch reicht schon) ?
Ob das eine oder zwei Methoden sind, hat aber keinen Einfluss auf die Task Switschereil.
-
Europa4 schrieb:
Taskswitch?wie soll er den denn verhindern
Spezifisch auf die zitierte Frage: Thread Synchronisierungs Mechanismen.
-
...
Das Problem lag in der Read Methode.
Sorry das ich euch mit dem Mist hier belästigt hab
Das Problem ist dass man ja bei ReadFile angeben muss
wieviele Bytes man lesen will.
Bzw, ich hab dass so verstanden dass ich die maximale
Anzahl an Bytes angeben muss. Es tut allerdings nur richtig
wenn ich maximal so viele Bytes angebe wie auf dem Input
Buffer liegen! Weiß jemand wie ich auslesen kann wieviele
Bytes darin liegen? Oder muss ich die ganze Zeit
WaitCommEvent() laufen lassen?Danke,
Max