Forum: PC-Programmierung Datenempfang RS232 mit C++


von Martin (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

folgendes Problem:
Ich sende mit einem AVR ATmega16 (mit externem Quarz ohne Beschaltung
direkt angeschlossen) per serieller Schnittstelle einzelne Bytes, im
Abstand von einer einstellbaren Pausenzeit.

Diese Daten kommen auch am PC an, werden also im Terminalprogramm
richtig angezeigt.

Nun möchte ich diese Daten in mit einem C++ Programm verwenden. Also
einfach nur: immer wenn ein Byte auf der RS232 ankommt, soll das
Programm es aufnehmen und speichern.


Ich habe dazu ein Programm geschrieben, was genau diese Aufgabe auch
erfüllt. (siehe empfangenPC.cpp im Anhang zum Beitrag)

ABER:

Das klappt nur, wenn die Bytes in großem zeitlichen Abstand ankommen.
Wenn ich den Abstand verringere, sind die empfangenen Bytes nur
manchmal richtig, bei sehr kleinem Abstand fast immer falsch. Es werden
also falsche Zahlen abgespeichert und ausgegeben.
Damit meine ich nicht die Veränderung der Baudrate!! Bei 1200 und 9600
Baud tritt derselbe Fehler auf, wobei im Terminalprogramm immer alles
richtig ankommt.

Hat jemand eine Idee, woran das liegen könnte?

Ich habe scheinbar noch nicht alles verstanden, eingefallen ist mir
nur, folgende Befehle in verschiedenen Kombinationen mit einzufügen
(teilweise gefunden bei der Forenrecherche), was aber bisher alles
nicht zum Erfolg führte:

------------
SetCommMask (com1port, EV_RXCHAR);
------------
//if (WaitCommEvent(com1port, &dwCom1Status, 0))
//{
//  ReadFile (com1port, txt, 1, &bytes_read, NULL);
//}
------------
ClearCommError(com1port, &dwError, NULL);
if (WaitCommEvent(com1port,&dwCom1Status, NULL))
{
    ReadFile (com1port, txt, 1, &bytes_read, NULL);
}
else
  cout << "\nFehler bei WaitCommEvent";
break;
------------
//if (dwCom1Status & EV_RXCHAR)
//{
//    ReadFile (com1port, txt, 1, &bytes_read, NULL);
//}


Ich würde mich sehr freuen, wenn mir jemand einen Tipp geben kann.

Vielen Dank!
Martin

von AndreasH (Gast)


Lesenswert?

Ich weiss jetzt ohne nachzusehen nicht was das:
COMMTIMEOUTS timeouts = {0,0,0,0,0};
macht.

Ich vermute mal ohne Timeout das ganze ablaufen lassen.
Das kann nicht funktionieren.

Wenn Dein Programm startet und der Controller sendet, das ist Zufall
wenn das übereinstimmt.

Zum Testen mach einfach mal folgendes.

Timeout mal auf 1/2 oder 1 Sekunde setzen.

Solange Schnittstelle abfragen bis das erste Zeichen gekommen ist.
Dann die restlichen 4 Zeichen einlesen.
Wenn es dan geht, kannst Du die Timeoutzeit immer noch runter setzen.
Wobei das egal ist. Die ist nur dann wichtig, wenn kein Zeichen kommt.
Sobald eins gekommen ist, kommt Readfile sowieso zurück.
Du müsstest dann nur einen Abbruch während dem Warten auf dem ersten
Zeichen ermöglichen.

Ich vermute, dass es dann geht.
Wenn es Commtimeouts auf unendlich steht dann vergiss das ganze.

Grüße
Andreas

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.