Text über die Serielle Schnittstelle (COM3) einlesen
-
Hallo,
ich möchte einen Text über die Serielle-Schnittstelle (COM3) einlesen.
Dazu habe ich hier im Forum folgendes Beispiel gefunden:// ConsoleApplication3.cpp : Diese Datei enthält die Funktion "main". Hier beginnt und endet die Ausführung des Programms. // Serielle Schnittstelle ansprechen und Daten senden // https://www.c-plusplus.net/forum/topic/300637/serielle-schnittstelle-ansprechen-und-daten-senden #include <iostream> #include <stdio.h> #include "ComPort.h" ComPort::ComPort(void) { hCom = INVALID_HANDLE_VALUE; } ComPort::~ComPort(void) { CloseHandle(hCom); } void ComPort::InitComPort(void) { DCB Dcb{}; COMMTIMEOUTS Cto{}; //if ((hCom = CreateFile(TEXT("COM3:"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE) if ((hCom = CreateFile(TEXT("\\\\.\\COM3"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE) { Dcb.DCBlength = sizeof(Dcb); GetCommState(hCom, &Dcb); Dcb.BaudRate = 4800; Dcb.fParity = false; Dcb.fNull = false; Dcb.StopBits = ONESTOPBIT; Dcb.Parity = NOPARITY; Dcb.ByteSize = 8; Dcb.EvtChar = 'X'; SetCommState(hCom, &Dcb); Cto.ReadIntervalTimeout = 0; Cto.ReadTotalTimeoutMultiplier = 0; Cto.ReadTotalTimeoutConstant = 0; Cto.WriteTotalTimeoutMultiplier = 0; Cto.WriteTotalTimeoutConstant = 0; SetCommTimeouts(hCom, &Cto); cout << "Port opened" << endl; } else { cout << "Couldn't open Port" << endl << "ERROR: " << GetLastError() << endl; } } int ComPort::Read() const { DWORD mask = 0; DWORD bytesRead = 0; char buf[1024] = ""; char buf_E[1024] = ""; int i = 0; SetCommMask(hCom, EV_RXCHAR | EV_RXFLAG | EV_RXFLAG); while (true) { if (WaitCommEvent(hCom, &mask, 0)) { cout << "mask " << mask << endl; switch (mask) { case EV_RXCHAR: ReadFile(hCom, &buf[i++], 1, &bytesRead, NULL); cout << "Empfangen: " << buf[i - 1] << endl; if (buf[i - 1] == '@') exit; // Einlesen Ende wenn Zeichen '@' gesendet wird break; case EV_ERR: cout << "Fehler beim lesen" << endl; break; case EV_RXFLAG: cout << "Eventchar empfangen" << endl; break; } } } return bytesRead; } int ComPort::Write() const { DWORD BytesWritten = 0; //char buf[] = "Hallo"; char buf[] = "X"; if (!WriteFile(hCom, buf, 1, &BytesWritten, NULL)) { cout << "Error writing to Port" << endl; return -1; } return BytesWritten; } int main() { DWORD BytesRead = 0; ComPort var1; var1.InitComPort(); var1.Write(); // Zeichen 'X' senden BytesRead = var1.Read(); cout << "BytesRead " << BytesRead << endl; system("pause"); return 0; }
// ComPort.h #pragma once #ifndef _COMPORT_H_ #define _COMPORT_H_ #include "windows.h" #include <iostream> using namespace std; class ComPort { public: ComPort(void); ~ComPort(void); void InitComPort(void); int Read() const; int Read_org() const; int Write() const; private: HANDLE hCom; }; #endif
Das Einlesen des Textes funktioniert soweit.
Wie aber kann ich das Einlesen mit "Read()" benden.
Mein Versuch war das Einlesen benden wenn z.B. das Zeichen '@' gesendet wird: " if (buf[i - 1] == '@') exit;".
Funktioniert leider nicht, das Einlesen wird nicht beendet.
Juergen
-
exit;
macht nicht das was du vermutlich willst. Es macht nämlich gar nix.exit
ist nämlich in C++ kein Keyword.exit
ist eine Standard-Library Funktion, die dein Programm beendet. Wenn du diese aufrufen wolltest, müsstest duexit(123);
schreiben, bzw. statt 123 was auch immer der Exit-Code sein soll.Nur
exit
, ohne()
ist kein Funktionsaufruf. Daher läuft dein Programm dann weiter. Nur was istexit
, ohne()
, und warum bekommst du keinen Fehler? Der Grund ist dass du in C++ als "Anweisung" sog. "Expressions" (Ausdrücke) hinschreiben kannst -- auch wenn diese nichts tun. Undexit
ist so ein Ausdruck. Er hat einen Wert (eine Referenz auf dieexit
Funktion), aber keinen Effekt. Macht in diesem Fall keinen Sinn, ist aber erlaubt. Wobei dein Compiler dir hier eine Warning geben sollte. Wie z.B.:<source>:5:5: warning: expression result unused [-Wunused-value] exit;
Wobei vermutlich willst du gar nicht
exit
aufrufen, sondern dass der Programm nach derwhile (true)
Schleife weitermacht. Wie geht das? z.B. mitgoto
:int ComPort::Read() const { ... while (true) { ... if (buf[i - 1] == '@') goto done; // Einlesen Ende wenn Zeichen '@' gesendet wird ... } done: return bytesRead; }
Wobei es einen viel eleganteren Weg gibt: du kannst dort wo du die Funktion verlassen willst einfach direkt
return bytesRead;
hinschreiben. Also einfachint ComPort::Read() const { ... while (true) { ... if (buf[i - 1] == '@') return bytesRead; // Einlesen Ende wenn Zeichen '@' gesendet wird ... } // Hier brauchst du kein return, da diese Stelle sowieso nie erreicht werden kann. }
-
ps: du solltest den Returnwert von
ReadFile
prüfen und Fehler behandeln.