Hilfe beim kommunikation mit COM Port
-
Hi
Also, ich würde auch erstmal anfangen, alle rückgabewerte zu überprüfen, und über GetLastError rauskriegen, ob alles geklappt hat.
Dann mußt du erstmal wissen, welche baudrate der Meßschieber braucht, 9600 ist zwar anzunehmen, aber man weiß nie.
Dein Pointer auf char sollte genausogroß sein, wie iMaxCount.
Mfg Reinhold Fischer
-
Etwas andere Wortwahl aber im Grunde was ich meinte

-
Merci. Hab ich gemacht! Aber jetzt sagt er Fehler beim Setzen der Com Port Parameter.
Hab hier mal den aktuellen Code:
#include <iostream> #include <windows.h> class CSerial { public: CSerial(); ~CSerial(); BOOL Open (int nComPortNr, int nBaud, int nBits, int nParity, int nStopp); BOOL Close (void); BOOL ModeSet (int nBaud, int nBits, int nParity, int nStopp); BOOL SetTimeout (int iTotalReadTimeout); BOOL IsOpen (void); int ReadData (char *buffer, int iMaxCount); int SendData (const char *buffer, int iBytesToWrite); BOOL WriteCommByte (unsigned char ucByte); private: HANDLE hComm; DCB dcb_alt; COMMTIMEOUTS timeouts_alt; }; CSerial::CSerial() { hComm = INVALID_HANDLE_VALUE; } CSerial::~CSerial() { Close (); } BOOL CSerial::IsOpen() { if (INVALID_HANDLE_VALUE != hComm) return (TRUE); else return (FALSE); } BOOL CSerial::ModeSet (int nBaud, int nBits, int nParity, int nStopp) { if (INVALID_HANDLE_VALUE == hComm) { SetLastError(ERROR_INVALID_HANDLE); return (FALSE); } DCB dcb; ZeroMemory (&dcb, sizeof(dcb)); dcb.DCBlength = sizeof(DCB); if (!GetCommState (hComm, &dcb)) { //close(); MessageBox (NULL, "Fehler beim Ändern der COM-Port Parameter\nGetCommState()", NULL, NULL); return (FALSE); } dcb.BaudRate = nBaud; dcb.ByteSize = (BYTE)nBits; dcb.Parity = (BYTE)nParity; dcb.StopBits = (BYTE)nStopp; if (!SetCommState (hComm, &dcb)) { Close (); MessageBox (NULL, "Fehler beim Ändern der COM-Port Parameter\nSetCommState()", NULL, NULL); return (FALSE); } return (TRUE); } BOOL CSerial::Open (int nComPortNr, int nBaud, int nBits, int nParity, int nStopp) { if (INVALID_HANDLE_VALUE != hComm) { return (TRUE); } char szPort[16]; wsprintf (szPort, "\\\\.\\COM%d", nComPortNr); hComm = CreateFile (szPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hComm == INVALID_HANDLE_VALUE) { MessageBox (NULL, "Fehler beim Öffnen des COM-Ports!\nCreateFile()", NULL, NULL); return (FALSE); } if (!GetCommTimeouts(hComm, &timeouts_alt)) { DWORD dwError = GetLastError(); Close (); SetLastError(dwError); MessageBox (NULL, "Fehler beim Öffnen des COM-Ports!\nGetCommTimeouts()", NULL, NULL); return (FALSE); } COMMTIMEOUTS timeouts; timeouts.ReadIntervalTimeout = MAXDWORD ; timeouts.ReadTotalTimeoutMultiplier = MAXDWORD ; timeouts.ReadTotalTimeoutConstant = 3000; // Timeout ist 3000ms timeouts.WriteTotalTimeoutMultiplier = 1000; timeouts.WriteTotalTimeoutConstant = 1000; if (!SetCommTimeouts(hComm, &timeouts)) { DWORD dwError = GetLastError(); Close (); SetLastError(dwError); MessageBox (NULL, "Fehler beim Öffnen des COM-Ports!\nSetCommTimeouts()", NULL, NULL); return (FALSE); } DCB dcb; ZeroMemory (&dcb, sizeof(dcb)); dcb.DCBlength = sizeof(DCB); if (!GetCommState (hComm, &dcb)) { DWORD dwError = GetLastError(); Close (); SetLastError(dwError); MessageBox (NULL, "Fehler beim Öffnen des COM-Ports!\nGetCommState()", NULL, NULL); return (FALSE); } dcb_alt = dcb; dcb.fBinary = TRUE; // muss immer "TRUE" sein! dcb.fParity = TRUE; dcb.fOutxCtsFlow = FALSE; dcb.fOutxDsrFlow = FALSE; dcb.fDtrControl = DTR_CONTROL_ENABLE; dcb.fDsrSensitivity = FALSE; dcb.fTXContinueOnXoff = TRUE; dcb.fOutX = FALSE; dcb.fInX = FALSE; dcb.fErrorChar = FALSE; dcb.fNull = FALSE; dcb.fRtsControl = RTS_CONTROL_ENABLE; dcb.fAbortOnError = FALSE; dcb.wReserved = 0; // muss immer "0" sein! dcb.BaudRate = nBaud; dcb.ByteSize = (BYTE)nBits; dcb.Parity = (BYTE)nParity; dcb.StopBits = (BYTE)nStopp; dcb.fParity = (dcb.Parity != NOPARITY); if (!SetCommState(hComm, &dcb)) { DWORD dwError = GetLastError(); Close (); SetLastError(dwError); MessageBox (NULL, "Fehler beim setzen der COM-Port Parameter\nSetCommState()", NULL, NULL); return (FALSE); } return(TRUE); } BOOL CSerial::Close (void) { if (INVALID_HANDLE_VALUE == hComm) // COM-Port überhaupt geöffnet? return(TRUE); if (!SetCommTimeouts(hComm, &timeouts_alt)) { MessageBox (NULL, "Fehler beim Schließen des COM-Ports\nSetCommTimeouts()", NULL, NULL); return (FALSE); } // alte Parameter zurückschreiben. Bei Fehler ist hier Schluss! if (!SetCommState (hComm, &dcb_alt)) { MessageBox (NULL, "Fehler beim Schließen des COM-Ports\nSetCommState()", NULL, NULL); return (FALSE); } CloseHandle (hComm); // Port schließen hComm = INVALID_HANDLE_VALUE; // das Handle zurücksetzen return (TRUE); } BOOL CSerial::SetTimeout (int iTotalReadTimeout) { if (INVALID_HANDLE_VALUE == hComm) return (TRUE); COMMTIMEOUTS timeouts; timeouts.ReadIntervalTimeout = MAXDWORD ; timeouts.ReadTotalTimeoutMultiplier = MAXDWORD ; timeouts.ReadTotalTimeoutConstant = (DWORD) iTotalReadTimeout; timeouts.WriteTotalTimeoutMultiplier = 1000; timeouts.WriteTotalTimeoutConstant = 1000; if (!SetCommTimeouts(hComm, &timeouts)) return (FALSE); return(TRUE); } BOOL CSerial::WriteCommByte (unsigned char ucByte) { if (INVALID_HANDLE_VALUE == hComm) { return (FALSE); } if (!TransmitCommChar(hComm, ucByte)) { MessageBox (NULL, "Fehler beim Schreiben auf COM-Port!\nTransmitCommChar()", NULL, NULL); } return (TRUE); } int CSerial::SendData (const char *buffer, int iBytesToWrite) { if (INVALID_HANDLE_VALUE == hComm) { return (0); } DWORD dwBytesWritten = 0; WriteFile(hComm, buffer, iBytesToWrite, &dwBytesWritten, NULL); return ((int) dwBytesWritten); } int CSerial::ReadData (char *buffer, int iMaxCount) { if (INVALID_HANDLE_VALUE == hComm) { SetLastError(ERROR_INVALID_HANDLE); return (0); } DWORD dwRead = 0; char chRead; int i = 0; while (ReadFile(hComm, &chRead, 1, &dwRead, NULL)) { if (dwRead != 1) break; buffer[i++] = chRead; if (i == iMaxCount) break; } return (i); }Aber die Parameter müssten eigentlich stimmen. Hab da bei Systemsteuerung Ssytem.. die COM eigenschaften übernommen oder müssen da andere rein??
-
Füg doch mal anstatt:
SetLastError(dwError); MessageBox (NULL, "Fehler beim setzen der COM-Port Parameter\nSetCommState()", NULL, NULL);folgendes ein:
LPVOID error_text; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_FROM_HMODULE |FORMAT_MESSAGE_IGNORE_INSERTS ,NULL,dwError,0,(LPTSTR) &error_text,0,NULL); MessageBox(NULL,(LPCSTR)error_text,NULL,NULL); LocalFree(error_text);und sag was er ausgibt.
Mfg, North.
-
Hab ich gemacht!
Jetzt zeigt er das Fehlerfenster aber es steht nix drin also alles grau?
Was sagt mir das jetzt? Na ich hoffe euch sagt es was denn ich steh ziehmlich auf'm Schlauch.
-
Bin ich jetzt doof

Der sollte dir dann eigentlich die Fehlermeldung von SetCommState() ausgeben...
Was hat denn dwError für 'nen Wert?
-
Sorry für doppelpost:
Probier mal FormatMessage ohne |FORMAT_MESSAGE_FROM_HMODULE
-
Er gibt aus:
Fehler falscher Parameter!

Das hat ich doch schonmal...
-
Kalle77 schrieb:
Das hat ich doch schonmal...
Wann? Bisher wußten wir nur wo der Fehler auftrat, jetzt wissen wir was es für ein Fehler ist.
Also ich mache bei mir folgende Einstellungen:ZeroMemory (&dcb, sizeof(dcb)); dcb.DCBlength=sizeof(sDcb); dcb.BaudRate = 9600; dcb.fParity = FALSE; dcb.fBinary = TRUE; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; dcb.fOutxCtsFlow = FALSE; dcb.fOutxDsrFlow = FALSE; dcb.fDtrControl = DTR_CONTROL_ENABLE; dcb.fRtsControl = RTS_CONTROL_ENABLE; dcb.fDsrSensitivity = FALSE; dcb.fAbortOnError = FALSE; dcb.ByteSize = 8;Den Rest lasse ich unverändert(auch kein GetCommState).
Damit klappts.MfG, North.
-
Die Fehlermeldung hatte ich heut gegen 11:00 schon mal irgendwie!
Also nach der Änderung bringt er jetzt 3 Fehlermeldungen
1. Fehler beim schließen des COM Ports SetCommState()
2. Fehler beim ändern des COM Ports SetCommState()
3. Fehler beim schließen des COM Ports SetCommState()
-
Wenn ich das richtig sehe, gibt's jetz kein Prblem mehr beim Öffnen des Ports.
Hast du immernoch ModeSet in deiner main? Wenn ja, schmeiß raus.
-
Sorry habe das Problem immer noch! ModeSet hab ich rausgehauen und jetzt kommt der Fehler beim schließen. Nur warum ist die Frage? irgendwelche Anregungen. Ich find der Code scheint ganz okay zu sein!
-
Das Problem beim Öffnen waren falsche Settings in der DCB Struktur. Ich schätze mal das ist beim Schließen dann auch das Problem. Da soll ja anscheinend der Ausgangszustand wieder hergestellt werden(was ich persönlich unnötig finde). Speicherst du denn überhaupt noch die alten Settings mit GetCommState in dcb_alt? Wenn nicht schmeiß entweder das SetCommState aus der Close Methode raus oder hol dir beim Öffnen doch wieder die alten Settings.
MfG, North.
-
Also die Fehlermeldungen sind auf jedenfall schon mal weg. Habe die Setcommstate aus Close rausgeschmissen1 Aber er bringt trotzdem nur wirre Werte. Scheinbar kann er keine Verbindung zum Schieber aufnehmen oder er empfängt nichts bzw was falsches! Oder was meinst du?
-
Die Frage ist, welche Baudrate usw. der Schieber hat. Da bräuchte man das Datenblatt. Alternativ mal mit Hyperterminal o.ä. durchprobieren.
-
Alles schon gemacht aber HyperTerminal bringt nix. Baudrate und co sind aber richtig...
-
Ich gebe zu, mir gehen die Ideen aus. Sendet der Schieber permanent Werte, also auch wenn ihn nicht bewegt? Falls ja, kommt da immer das Selbe an? Und sind das tatsächlich immer 4 Byte?
-
Hallo!
Habe noch eine Frage zu einem Pogrammteil!
zahl = (c[0]<<24)|(c[1]<<16)|(c[2]<<8)|c[3];
Was bedeutet diese Zeile? Ist das die Byteverschebung?
-
Ja, desshalb ist es wichtig zu wissen, wie die Daten vom Schieber übermittelt werden. Sonst kommt dabei nur Müll raus.