PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Kommunikationsparameter



datatom
21.10.2011, 10:38
Hallo zusammen,

passen die Kommunikationsparameter aus meinem C++ -Programm



dcbSerialParams.BaudRate= CBR_128000; //CBR_57600;
dcbSerialParams.ByteSize=8;
dcbSerialParams.StopBits=ONESTOPBIT;
dcbSerialParams.Parity=NOPARITY;


zu denen des Bascom-Programms?


Config Com1 = 128000 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0


Bisher kommen die Daten um ca. 10 Sekunden verzögert vom Controller zum PC an.

Als Anhang auch die Einstellungen des Terminal von Bascom.

Vielen Dank und Grüße

datatom

PicNick
21.10.2011, 10:44
Auf jeden Fall solltest du
"Handshake none"
einstellen.

datatom
21.10.2011, 10:50
Meinst du die Einstellung bei den Terminal settings oder im C++ -Programm?

Bei den Terminal settings habe ich umgestellt, wie es im C++ -Programm geht weiß ich leider nicht genau?

PicNick
21.10.2011, 11:02
Das wären die Terminal Settings. Vielleicht macht es aber eh nix aus, weil sich Xon/Xoff ja nicht in der Hardware abspielt.
Ob COM4 richtig ist, kann ich natürlich nicht sagen.
Ansonsten sollten die Konfigurationen eigentlich passen, denn wenn nicht, käme nur effektiver Müll raus.

128000 ist aber schon flott, probier doch erst einmal (auf beiden) 19200 oder sowas

PicNick
21.10.2011, 11:06
Guck mal da rein, vielleicht hilft das weiter

http://www.rn-wissen.de/index.php/Network_Controller/PC_Praxis#Network_Controller.2FPC_RS232_mit_Window s (http://www.rn-wissen.de/index.php/Network_Controller/PC_Praxis#Network_Controller.2FPC_RS232_mit_Window s)

oberallgeier
21.10.2011, 11:39
Hi datatom,

es kommt auch darauf an, welchen Quarz Du hast (und welchen Controller - beide Angaben wären hier sinnvoll). 1) Der interne Oszillator wird für 128kBd sicher nicht mehr taugen. 2) Unterschiedliche Quarze haben unterschiedliche Baudratenfehler, da der Teiler für den Bittakt eine ganze Zahl ist und irgendwie zum Quarztakt und der gewünschten Baudrate passt oder eben auch nicht. Siehe diese Beispiel für 20MHz oder diesen Beitrag. (https://www.roboternetz.de/community/threads/42185-Baudraten-define-xxx-und-einige-Auswirkungen?p=403120&viewfull=1#post403120)

......http://oberallgeier.ob.funpic.de/baud-01.gif

Aber aus den hier skizzierten Abweichungen kann ich keine Pause von 10 sec ableiten.

radbruch
21.10.2011, 11:56
16000000 / 128000 = 125

Das passt doch optimal, oder übersehe ich da etwas?

Aha: https://www.roboternetz.de/community/threads/55271-Daten-kommen-verz%C3%B6gert-vom-Controller-zur%C3%BCck-zum-PC

oberallgeier
21.10.2011, 12:54
16000000 / 128000 = 125 ... übersehe ich da etwas? ...Diesen anderen Thread kannte ich nicht, der ist hier auch nicht genannt : ( : ( : (

PicNick
21.10.2011, 14:02
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.

datatom
21.10.2011, 14:51
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.

Richtig die Daten kommen korrekt. Die Verzögerung ist das Problem.

Ich habe jetzt die Parameter im C++ -Programm folgendermaßen belegt:


dcbSerialParams.BaudRate= CBR_128000; //CBR_57600;
dcbSerialParams.ByteSize=8;
dcbSerialParams.StopBits=ONESTOPBIT;
dcbSerialParams.Parity=NOPARITY;
dcbSerialParams.fOutxCtsFlow=0;
dcbSerialParams.fOutxDsrFlow=0;


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:



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 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.

Ich verzweifle:(

PicNick
21.10.2011, 16:16
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



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

datatom
21.10.2011, 16:36
Ich habe deine Einstellungen übernommen:


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;


Hat leider keine Veränderungen gebracht:-(

Meine Einstellungen mit dem Timeout waren vorher:


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;
}


Schwieriges Thema:(

Richard
21.10.2011, 18:12
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

datatom
21.10.2011, 18:30
Software Protokoll XON XOF wird auch warten also "Flusskontrolle" = Keine einstellen.

Habe ich so gemacht:



dcbSerialParams.fOutxCtsFlow = FALSE;
dcbSerialParams.fOutxDsrFlow = FALSE;



Hat aber auch nichts genützt:-(

Standartmäßig stehen die Parameter auf 1.



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....


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?

Richard
21.10.2011, 19:17
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?

Ja, dann sollte das OK. sein, bleibt also nur noch ein Bug in der Software. :-( Leider verstehe ich von C zu wenig, mir liegt einfach dessen Syntax und Tastaturbelegung absolut NICHT und bin auch zu faul das alle neu zu erlernen. Eher fange ich wieder mit ASM an, das konnte ich ziemlich gut. Ist ja auch relativ einfach weil sehr Hartware nah, man sieht quasi bei jedem Befehl was man macht b.z.w. was passiert. :-) Aber für relativ kleine Sachen reicht auch Bascom und das lässt sich auch mit einer Deutschen Tastatur und 2 Finger Tipp System noch halbwegs gut schreiben. :-)

Gruß Richard

datatom
01.11.2011, 16:58
Mit welchen Parametern der DCB Struktur kann ich das handshake ausschalten?

Muss ich eigentlich beim verändern der Parameter aud Bascom-Seite auch was verändern?

Bisher habe ich dort folgende Einstellungen:

Config Com4 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

Richard
01.11.2011, 17:46
Mit welchen Parametern der DCB Struktur kann ich das handshake ausschalten?

Muss ich eigentlich beim verändern der Parameter aud Bascom-Seite auch was verändern?

Bisher habe ich dort folgende Einstellungen:

Config Com4 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

µC's arbeiten in der Regel ohne handshake, Terminals wie Hyperterm b.z.w. PC Com Einstellungen überwiegend mit. Das kann man dann in der Systemsteuerung Com Port Eigenschaften auf Flussteuerung "keine" für jeden Port einzeln ändern. :-)

Bei bestimmten Anwendungen (Programm Abläufen) vom µC kann Handshake nötig sein, Das RTS/CTS u.s.w. muss man dann halt selber "basteln" und entsprechende Port Pins dafür einrichten.

Gruß Richard