Hilfe beim kommunikation mit COM Port
-
Ich hab von c++ leider keinen Schimmer. Ich programmiere nur in c, weil ich in der Regel recht Hardware nah arbeite.
Wenn der Messschiebr float überträgt(bist du sicher?), dann sähe das bei mir etwa so aus:float zahl; zahl = (c[0]<<24)|(c[1]<<16)|(c[2]<<8)|c[3]; printf("%f",zahl);Mfg, North.
-
Auf jedenfall liefert der Schieber Kommzahlen. Aber sonst sieht der Code doch eigentlich recht okay aus. Er kompiliert ja auch ohne Probleme. Weiß jetzt allerdigs nicht wo ich deinen Code hinpacken soll bzw was er ersetzt!
-
Probier doch mal folgendes:
Ersetze:
serial.ReadData(c,2); serial.Close(); cout<<c<<endl;Durch:
float zahl;.
.
.serial.ReadData(c,4); //float sind 4 Byte serial.Close(); zahl = (c[0]<<24)|(c[1]<<16)|(c[2]<<8)|c[3]; cout<<zahl<<endl;
-
Hab das jetzt mal so probiert aber er gibt immer den selben Wert aus. das kann ja auch nicht richtig sein, weil sich ja der Wert des Schibers verändert.
-
Mir fällt gerade auf, dass du für c garkeinen Speicher allozierst

Ansonsten sieht das eigentlich ganz OK aus.
Was genau ist denn das für ein Messschieber? Gibt's da 'nen Datenblatt zu?Mfg, North.
-
Was genau meinst du mir allozieren? (auch wenn doof klingt)
Es ist ein Digitalschieber und hat Werte mit 3 Nachkomm stellen. Ein Datenblatt gibt es glaub ich nicht mehr.
-
char *c; reserviert nur den Speicher für einen Pointer auf char.
Wenn du den mit Leben füllen willst, dann musst du dem noch entsprechend der Anzahl der Element Speicher zuweisen.
Also,
1. dynamisch:char *c; c = (char*)malloc(4*sizeof(char));oder
c = (char*)calloc(4,sizeof(char));oder
c = (char*)LocalAlloc(LMEM_ZEROINIT,4*sizeof(char));2. statisch
char c[4];Bei 1. am Schluß nicht das free(c) bzw. LocalFree(c) vergessen.
Komisch, dass dein Programm nicht abgeschmiert ist.Mfg, North.
-
Also es hat sich schon mal was getan aber er gibt immer noch eine Zahl aus und zwar immer die selbe. Trotz Veränderung am Schieber. Kann es sein das gar nicht der COM Port angesprochen wird?
-
OK, das kriegen wir schon raus.
1. Überprüf doch mal mit dem Hyperterminal o.ä. was an der seriellen Schnittstelle ankommt.
2. Check mal die Rückgabewerte der Methoden die du aufrufst.
3. Steht da auf deinem Schieber nicht irgend ein Name oder Nummer drauf nach der man mal googeln könnte?Mfg, North.
-
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.