Diesen anderen Thread kannte ich nicht, der ist hier auch nicht genannt :( :( :(Zitat von radbruch
Diesen anderen Thread kannte ich nicht, der ist hier auch nicht genannt :( :( :(Zitat von radbruch
Ciao sagt der JoeamBerg
Das Problem ist hier, dass die Daten zwar korrekt ankommen (ist das so ?), aber eben mit 10 Sek Delay.
D.h. das mit der Baudrate und den anderen Config-Sachen ist NICHT das Problem.
Dann kann es nur ein Problem in der Software sein. Ich vermute PC-Seitig, will aber keinem Unrecht tun.
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
Richtig die Daten kommen korrekt. Die Verzögerung ist das Problem.
Ich habe jetzt die Parameter im C++ -Programm folgendermaßen belegt:
Die Kommunikation mit dem Bascom-Programm und der Konsole klappt ohne Probleme und ohne Verzögerung. Deswegen sehe ich das Problem, ebenfalls wie PicNick, PC-seitig. Ich kann mir das aber nicht erklären. Hier mal mein ReadFile und WriteFile:Code:dcbSerialParams.BaudRate= CBR_128000; //CBR_57600; dcbSerialParams.ByteSize=8; dcbSerialParams.StopBits=ONESTOPBIT; dcbSerialParams.Parity=NOPARITY; dcbSerialParams.fOutxCtsFlow=0; dcbSerialParams.fOutxDsrFlow=0;
Ich sende Daten vom Joystick zum Controller und der sendet sie wieder zurück zum PC. Die Daten die ich sende sind immer die aktuellen Daten der Joystickachsen. Dann empfange ich z.B. 10 mal den gleichen Wert der Achsen, obwohl ich mehrfach schon aktuellere Daten zum Controller gesendet habe. Erst nach ca. 10 Sekunden erhalte ich mit ReadFile die Daten die ich 10 Sekunden vorher zum Controller gesendet habe. Zwischen WriteFile und ReadFile empfängt der Controller nur einmal Daten und sendet auch nur einmal Daten zurück. Das habe ich mit LED-blinken getestet.Code:char *write_pointer = write_char; DWORD len = write_pointer ? (DWORD)strlen(write_pointer) : 0; DWORD dwBytesWritten; while(len) { if(!WriteFile(hSerial, write_pointer, len, &dwBytesWritten, NULL)) { //error occurred. Report to user return TB_ERROR; //-1; } len -= dwBytesWritten; write_pointer += dwBytesWritten; } write_pointer = "\r"; len = (DWORD)strlen(write_pointer); while(len) { if(!WriteFile(hSerial, write_pointer, len, &dwBytesWritten, NULL)) { //error occurred. Report to user return TB_ERROR; //-1; } len -= dwBytesWritten; write_pointer += dwBytesWritten; } } Sleep(200); DWORD dwBytesRead; char read_buffer[256]; int read_index = 0; while(read_index < sizeof(read_buffer)) { if(!ReadFile(hSerial, &read_buffer[read_index], 1, &dwBytesRead, NULL)) { //error occurred. Report to user return TB_ERROR; //-1; } if(dwBytesRead != 1) { //error occurred. Report to user return TB_ERROR; //-1; } if(read_buffer[read_index] == '\n') { // ignore continue; } if(read_buffer[read_index] == '\r') { // end of message break; } read_index++; } if(read_index == sizeof(read_buffer)) { //error occurred (buffer overflow). Report to user return TB_ERROR; //-1; } read_buffer[read_index] = '\0'; if(read_index > 0) { wchar_t print_buffer[sizeof(read_buffer)]; mbtowc(print_buffer, read_buffer, MB_CUR_MAX); } else { //error occurred. Report to user return TB_ERROR; //-1; } //MessageBox(hwnd, print_buffer, L"ReadFile", MB_OK | MB_ICONINFORMATION); int string_read_laenge = 3; if(read_index < 3) { // Sollte read_index < 3 sein, gibt es einen Fehler, weil der substr nicht klappt. Bei dem substr wird erst ab Feld 3 gearbeitet return TB_ERROR; //-1; } string_parameter_read = read_buffer;
Ich verzweifle![]()
In meinem oben verlinkten RN-Wissen Beispiel setze ich auch die Timeoutparameter. Hast du das auch implementiert ? offenbar wartet ja der PC, bis er dir die Daten übergibt
Code:COMMTIMEOUTS sTo; DCB sDcb; memset(&sDcb,0,sizeof(sDcb)); sDcb.DCBlength = sizeof(sDcb); sDcb.BaudRate = Baud; // 9600 oder eine andere Baudrate sDcb.fParity = FALSE; sDcb.fBinary = TRUE; sDcb.Parity = NOPARITY; sDcb.StopBits = ONESTOPBIT; sDcb.fOutxCtsFlow = FALSE; sDcb.fOutxDsrFlow = FALSE; sDcb.fDtrControl = DTR_CONTROL_ENABLE; sDcb.fRtsControl = RTS_CONTROL_ENABLE; sDcb.fDsrSensitivity = FALSE; sDcb.fAbortOnError = FALSE; sDcb.ByteSize = 8; if(SetCommState(hFile,&sDcb)) { sTo.ReadIntervalTimeout = MAXDWORD; // 0 ms Read-Timeout sTo.ReadTotalTimeoutMultiplier = 0; sTo.ReadTotalTimeoutConstant = 0; sTo.WriteTotalTimeoutMultiplier = 1; // 1*2 ms Write Timeout sTo.WriteTotalTimeoutConstant = 2; if(SetCommTimeouts((HANDLE)hFile,&sTo)) return 1; // O.K. return
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
Ich habe deine Einstellungen übernommen:
Hat leider keine Veränderungen gebrachtCode:memset(&dcbSerialParams,0,sizeof(dcbSerialParams)); dcbSerialParams.DCBlength = sizeof(dcbSerialParams); dcbSerialParams.BaudRate = CBR_128000; // 9600 oder eine andere Baudrate dcbSerialParams.fParity = FALSE; dcbSerialParams.fBinary = TRUE; dcbSerialParams.Parity = NOPARITY; dcbSerialParams.StopBits = ONESTOPBIT; dcbSerialParams.fOutxCtsFlow = FALSE; dcbSerialParams.fOutxDsrFlow = FALSE; dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE; dcbSerialParams.fRtsControl = RTS_CONTROL_ENABLE; dcbSerialParams.fDsrSensitivity = FALSE; dcbSerialParams.fAbortOnError = FALSE; dcbSerialParams.ByteSize = 8; timeouts.ReadIntervalTimeout = MAXDWORD; // 0 ms Read-Timeout timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 1; // 1*2 ms Write Timeout timeouts.WriteTotalTimeoutConstant = 2;
Meine Einstellungen mit dem Timeout waren vorher:
Schwieriges ThemaCode:tbResult InitSerialPort(HWND hwnd) { LPCTSTR SeriellerPort = TEXT("COM4"); hSerial = CreateFile(SeriellerPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if(hSerial==INVALID_HANDLE_VALUE) { if(GetLastError()==ERROR_FILE_NOT_FOUND) { // Generate an error // Fehlercode ausgeben if(!GetProcessId(NULL)) { MessageBox(hwnd, (LPCWSTR)"Fehler bei LGetProcessId", (LPCWSTR)L"Fehler", MB_OK | MB_ICONEXCLAMATION); return TB_ERROR; } //serial port does not exist. Inform user. MessageBox(hwnd, (LPCWSTR)L"Fehler bei CreateFile. Serial Port existiert nicht!", (LPCWSTR)L"Fehler", MB_OK | MB_ICONEXCLAMATION); return TB_ERROR; } //some other error occurred. Inform user MessageBox(hwnd, (LPCWSTR)L"Fehler bei CreateFile. Sonstiger Fehler!", (LPCWSTR)L"Fehler", MB_OK | MB_ICONEXCLAMATION); return TB_ERROR; } if (!GetCommState(hSerial, &dcbSerialParams)) { //error getting state MessageBox(hwnd, (LPCWSTR)L"Fehler bei GetCommState!", (LPCWSTR)L"Fehler", MB_OK | MB_ICONEXCLAMATION); return TB_ERROR; } /* memset(&dcbSerialParams,0,sizeof(dcbSerialParams)); dcbSerialParams.DCBlength = sizeof(dcbSerialParams); dcbSerialParams.BaudRate = CBR_128000; // 9600 oder eine andere Baudrate dcbSerialParams.fParity = FALSE; dcbSerialParams.fBinary = TRUE; dcbSerialParams.Parity = NOPARITY; dcbSerialParams.StopBits = ONESTOPBIT; dcbSerialParams.fOutxCtsFlow = FALSE; dcbSerialParams.fOutxDsrFlow = FALSE; dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE; dcbSerialParams.fRtsControl = RTS_CONTROL_ENABLE; dcbSerialParams.fDsrSensitivity = FALSE; dcbSerialParams.fAbortOnError = FALSE; dcbSerialParams.ByteSize = 8; timeouts.ReadIntervalTimeout = MAXDWORD; // 0 ms Read-Timeout timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 1; // 1*2 ms Write Timeout timeouts.WriteTotalTimeoutConstant = 2; */ dcbSerialParams.BaudRate= CBR_128000; //CBR_57600; dcbSerialParams.ByteSize=8; dcbSerialParams.StopBits=ONESTOPBIT; dcbSerialParams.Parity=NOPARITY; dcbSerialParams.fOutxCtsFlow=0; dcbSerialParams.fOutxDsrFlow=0; if(!SetCommState(hSerial, &dcbSerialParams)) { //error setting serial port state MessageBox(hwnd, (LPCWSTR)L"Fehler bei GetCommState beim Parameter belegen!", (LPCWSTR)L"Fehler", MB_OK | MB_ICONEXCLAMATION); return TB_ERROR; } timeouts.ReadIntervalTimeout=50; timeouts.ReadTotalTimeoutConstant=50; timeouts.ReadTotalTimeoutMultiplier=10; timeouts.WriteTotalTimeoutConstant=50; timeouts.WriteTotalTimeoutMultiplier=10; if(!SetCommTimeouts(hSerial, &timeouts)) { //error occureed. Inform user MessageBox(hwnd, (LPCWSTR)L"Fehler bei Timeout!", (LPCWSTR)L"Fehler", MB_OK | MB_ICONEXCLAMATION); return TB_ERROR; } return TB_OK; }![]()
Ich kenne mich mit C nicht aus aber wenn Am PC Flusskontrolle aktiviert ist, wartet der PC auch auf RTS/CTS (in Hartware). Software Protokoll XON XOF wird auch warten also "Flusskontrolle" = Keine einstellen. Warum allerdings mit starker Verzögerung dann doch etwas kommt? Um zumindest schon einmal auf PC Seite sowie die Verbindungen zu Prüfen das dort alles stimmt, Einfach am µC RXD TXD verbinden und am PC irgend etwas eingeben. Das muss sofort wieder Empfangen werden weil der PC durch (die Brücke) mit sich selber "Redet".Jetzt weiß man wenigstens schon "etwas" mehr.
Diese eigenartige Verzögerung (kann) natürlich auch daran liegen das der µC eine Zeit lang ins Nirwana verschwindet..fehlendes Ret oder Probleme mit dem Stack. Da passiert auch schnell "eigenartiges". Auch und vor Kurzem hatte jemand Stress weil er bei der RS232 Verbindung GND nicht verbunden hatte....
Gruß Richard
Habe ich so gemacht:
Hat aber auch nichts genütztCode:dcbSerialParams.fOutxCtsFlow = FALSE; dcbSerialParams.fOutxDsrFlow = FALSE;
Standartmäßig stehen die Parameter auf 1.
Wenn ich mit Bascom von der Konsole sende und empfange klappts ohne Verzögerung. Also müsste der Controller samt Anschluß in Ordnung sein, oder?
Wie sieht denn der WriteFile bzw. ReadFile in C++ bei euch aus?
Lesezeichen