Datenempfang RS232 mit C++

Gast #200473
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
Angehängte Dateien:
Gast #200474
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

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.