Hallo Freunde, ich hole mir Daten von einem µC und Sensoren über eine serielle Schnittstelle. Meine Betriebsart ist der sogenannte nonoverlapped-Betrieb. Ich sage dem µC zB.. Schicke mir zwei Byte und dann tut er dies.. Problem ist, wenn er mir die nicht schickt, weil der Stecker rausgezogen wird, wartet mein Programm solange bis dann doch die Antwort kommt.. Nun möchte ich nach jedem Programmdurchlauf (500ms) sagen, dass der Softwarertimer zurrückgesetzt wird.. Erreicht der Timer im Hintergrund zB 1000ms stoppt mein Programm.. Wie bereits im Betreff steht Programmiere ich mit Visual Studio.. Wenn jemand eine bessere Idee hat... Gruß Marr
:
Verschoben durch User
"Visual Studio" ist keine Programmiersprache, sondern eine Entwicklungsumgebung, mit der recht viele völlig unterschiedliche Programmiersprachen verwendet werden können. Timer gibt in einigen davon "einfach so", in anderen muss man auf Betriebssystemfunktionen zurückgreifen, und die können z.B. über die Windows-Messagefunktionen WM_TIMER versenden, oder per Callback eine von Dir definierte Funktion aufrufen. Ohne weitere Details über Dein Programm zu kennen (Programmiersprache? Verwendete Klassenbibliothek o.ä., Konsol- oder Windows-Anwendung?) lässt sich mehr nicht zum Thema sagen.
Wird davon evtl. was gesucht? .net: https://msdn.microsoft.com/de-de/library/system.io.ports.serialport.readtimeout%28v=vs.110%29.aspx WinAPI: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363437(v=vs.85).aspx
Marr schrieb: > Erreicht der Timer im Hintergrund > zB 1000ms stoppt mein Programm.. Wenn du damit als Fehlerbehandlung zufrieden bist, Ok. In Windows gibt es Timer, die bei Ablauf ein Event auslösen. Entweder du nimmst den Timer selbst für den Timeout, oder zu zählst damit z.B. eine Variable Timeout jede 100 ms herunter. Beim Start und bei bei jedem erfolgreichen Empfang setzt du den Wert wieder auf den gewünschten Start-(Timeout-) Wert. Erreicht der Timer oder der Zähler Null, so ist das dein Timeout-Ereignis, und du kannst ein Fenster mit Fehlermeldung anzeigen oder das Programm ganz beenden oder was immer du willst. Es ist keine schlechte Idee, den Timeout-Wert programmierbar zu machen. Georg
Georg schrieb: > Marr schrieb: >> Erreicht der Timer im Hintergrund >> zB 1000ms stoppt mein Programm.. > > Wenn du damit als Fehlerbehandlung zufrieden bist, Ok. In Windows gibt > es Timer, die bei Ablauf ein Event auslösen. Entweder du nimmst den > Timer selbst für den Timeout, oder zu zählst damit z.B. eine Variable > Timeout jede 100 ms herunter. Beim Start und bei bei jedem erfolgreichen > Empfang setzt du den Wert wieder auf den gewünschten Start-(Timeout-) > Wert. Erreicht der Timer oder der Zähler Null, so ist das dein > Timeout-Ereignis, und du kannst ein Fenster mit Fehlermeldung anzeigen > oder das Programm ganz beenden oder was immer du willst. > > Es ist keine schlechte Idee, den Timeout-Wert programmierbar zu machen. > > Georg Joa so möcht ich das machen.. Im Hintergrund läuft ein Timer von 10000ms runter... Wenn der Wert 0 passiert ist möchte ich darauf reagieren.. Mein Programm setzt den Wert jedesma auf 10000 zurrück wenn es durchgelaufen ist.. Das kann doch eig. nicht so schwierig ein oder? Habt ihr ev. ein Beispielprogramm?
Marr schrieb: > Joa so möcht ich das machen.. Was du möchtest: Zuerst mal den Beitrag von Rufus lesen und verstehen ...
WINAPI Timer: https://msdn.microsoft.com/en-US/library/windows/desktop/ff468912(v=vs.85).aspx Timer verwenden: https://msdn.microsoft.com/en-US/library/windows/desktop/ms644901(v=vs.85).aspx#creating_timer
Programmiersprache ist C.. Es soll eine Konsolanwendung werden.. Gibt es da dein fertiges Programm? Bin grad von morgens bis abends auf Montage und habe ehrlich gesagt wenig Zeit mich darein zu arbeiten.. Möchte einfach das nen Timer am Zyklusende (1000ms) zurrückgesetzt wird.. Passiert das nicht, soll etwas passieren..
Marr schrieb: > Programmiersprache ist C.. > Es soll eine Konsolanwendung werden.. Aha. Das sind ja schon mal klare Aussagen. Dann ist für Dich die Win32-API die richtige Baustelle. Mit der Funktion SetTimer kannst Du einen solchen Timer erzeugen. Diese Funktion ist zwar in erster Linie für die Fensterprogrammierung gedacht, kann aber auch in Konsolanwendungen genutzt werden. https://msdn.microsoft.com/en-us/library/windows/desktop/ms644906%28v=vs.85%29.aspx Wie die Dokumentation beschreibt, kann diese Funktion auf vielfältige Weise verwendet werden; ich beschreibe Dir jetzt mal eine davon, nämlich den Gebrauch mit einer Rückruffunktion (Callback).
1 | UINT_PTR WINAPI SetTimer( |
2 | HWND hWnd, |
3 | UINT_PTR nIDEvent, |
4 | UINT uElapse, |
5 | TIMERPROC lpTimerFunc |
6 | );
|
Der erste Parameter muss NULL sein; Du hast kein Fenster, und daher auch kein Fensterhandle. Auch der zweite Parameter sollte NULL sein, Du willst einen neuen Timer erzeugen. Wenn Du den Timer bereits erzeugt hast, ihn aber neu aufziehen willst, musst Du hier den Rückgabewert des vorhergehenden Aufrufs dieser Funktion angeben -- mehr dazu weiter unten. Als dritter Parameter ist die Zeitdauer anzugeben, in Millisekunden. Der vierte Parameter wiederum ist ein Funktionspointer. Hier gibst Du die Adresse einer Funktion an, die aufgerufen wird, wenn der Timer abgelaufen ist. Die Funktion muss den Aufrufkonventionen von TIMERPROC entsprechen, d.h. diesen Funktionsprototypen haben:
1 | VOID CALLBACK TimerProc( |
2 | HWND hwnd, |
3 | UINT uMsg, |
4 | UINT_PTR idEvent, |
5 | DWORD dwTime |
6 | );
|
Der Name ist natürlich egal. Die der Funktion tatsächlich übergebenen Argumente sind bei Deiner Anwedung auch egal; entscheidend ist, daß die Funktion überhaupt aufgerufen wird -- was geschieht, wenn der Timer abgelaufen ist. Wichtig aber ist, daß Du den Rückgabewert von SetTimer aufhebst. Den brauchst Du, wenn Du den Timer abbrechen willst, und der wird dafür Funktion KillTimer übergeben.
@Marr Hast du dir "SetCommTimeouts" schon angesehen? Den Link hat bluppdidupp oben gepostet: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363437%28v=vs.85%29.aspx Hier auch noch ein paar Infos und etwas Code: http://www.codeproject.com/Articles/3061/Creating-a-Serial-communication-on-Win Zu Timern: Den gebräuchlichsten hat Rufus ja schon beschrieben; es existieren noch drei weitere Möglichkeiten (WinAPI), nämlich "Timer Queues", "Waitable Timer Objects" und "Multimedia Timers". https://msdn.microsoft.com/de-de/library/windows/desktop/ms686796%28v=vs.85%29.aspx https://msdn.microsoft.com/en-us/library/windows/desktop/ms687012%28v=vs.85%29.aspx https://msdn.microsoft.com/en-us/library/windows/desktop/dd743609%28v=vs.85%29.aspx "Multimedia Timers" soll man bei neuen Anwendungen allerdings nicht mehr verwenden. Kurzbeschreibung der vier WinAPI-Timer: http://www.codeproject.com/Articles/1236/Timers-Tutorial
Halbleiteravantgardist schrieb: > "Multimedia Timers" soll man bei neuen Anwendungen allerdings nicht mehr > verwenden. Warum? Und: Wer schreibt das?
Warum mit Kanonen auf Spatzen schießen? VS ist .NET. Und das bietet eine Vielzahl von Funktionen auch für die serielle Schnittstelle an. Ich selber programmiere in VB, aber in C dürfte es die gleichen Funktionen geben, nur der Syntax ist anders. C ist allerdings kein Bestandteil von VS, vermutlich meinst du C#. Diese beiden Cs haben aber nichts miteinander zu tun. Wenn ich etwas mit einem Timer laufen lassen will, starte ich einfach einen neuen Timer mit "meinTimer = New Timer". Im Timerevent zähle ich die für mich relevanten Hilfsvariablen hoch und mache die entsprechenden Auswertungen. Serielle Schnittstelle geht aber noch einfacher. Entweder du setzt beim Programmstart die TimeOut-Bedingung und packst die Abfrage der Schnittstelle in einen Try-Catch-Block oder du fragst vorm Lesen der Daten von der Schnittstelle ab, ob es überhaupt was zu lesen gibt (myComPort.BytesToRead). Dritte Möglichkeit währe, dass du deiner seriellen Schnittstelle einen Event spendierst, der beim Empfang von 2 Bytes auslöst. In der Event-Behandlungsroutine liest du dann die zwei Byte aus und machst die Auswertung. Möglickeit 4, 5 und 6 spare ich mir jetzt mal...
Jens schrieb: > VS ist .NET. Nein. VS enthält auch das .Net-Geraffel, aber auch einen echten C++- und C-Compiler. Der C-Compiler ist etwas angestaubt, da er hartnäckig nur C89 unterstützt, der C++-Compiler hingegen ist vorzüglich.
:
Bearbeitet durch User
Rufus Τ. Firefly schrieb: > Nein. VS enthält auch das .Net-Geraffel, aber auch einen echten C++- > und C-Compiler. Oh, das ist mir neu. Aber von mir aus soll der TE sich mit seinem C abquälen während ich mit ein paar Zeilen in Visual Basic des ach so verpönten .Net zum Ergebnis komme. Beispiele siehe oben.
Rufus Τ. Firefly schrieb: > der C++-Compiler hingegen ist vorzüglich. Unterstützt ja nicht mal C++11 bzw. 17 vernünftig. Dann lieber GCC. Ansonsten ist für so ein Projekt .NET deutlich besser geeignet. Mit C/C++ tut man sich da keinen Gefallen...
Rufus ?. Firefly schrieb: >> "Multimedia Timers" soll man bei neuen Anwendungen allerdings nicht mehr >> verwenden. > > Warum? Weil es Probleme mit PulseEvent geben kann (und timeSetEvent PulseEvent verwendet). > Und: Wer schreibt das? Microsoft: https://msdn.microsoft.com/en-us/library/dd757634%28v=vs.85%29.aspx Indirekt deswegen: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684914%28v=vs.85%29.aspx Siehe auch http://blogs.msdn.com/b/larryosterman/archive/2005/09/08/462477.aspx (Larry Osterman gehörte zum Team, das die API enwickelt hat) @Marr Hier ist auch noch etwas zur seriellen Schnittstelle und Timeouts: http://www.codeproject.com/Articles/8860/Non-Overlapped-Serial-Port-Communication-using-Win @Jens >> VS enthält auch das .Net-Geraffel, aber auch einen echten C++- >> und C-Compiler. > Oh, das ist mir neu. Visual Studio gab es schon lange vor .NET; erst in VS 2002 ist .NET dazugekommen. > Aber von mir aus soll der TE sich mit seinem C > abquälen während ich mit ein paar Zeilen in Visual Basic des ach so > verpönten .Net zum Ergebnis komme. Da Marr vermutlich nicht viel Erfahrung mit der WinAPI und offenbar auch wenig Zeit hat, ist das nicht so abwegig. Falls es doch mal unter Linux laufen soll: Auch in Mono gibt es "SerialPort". Wobei ich wegen der Syntax - falls der TO schon länger in C programmiert - und der größeren Anzahl von Beispielen im Netz eher C# empfehlen würde.
Halbwacher schrieb: > Visual Studio gab es schon lange vor .NET; erst in VS 2002 ist .NET > dazugekommen. Wenn ich mich recht erinnere, gab es Funktionen für die serielle Schnittstelle schon in den frühen Versionen von VB, noch ohne .NET. Was ich eigentlich damit sagen will, dass es in den meisten Programmiersprachen umfangreiche Funktionssammlungen aka. Framework gibt, die solche Sachen wesentlich vereinfachen. Zur Not gibt es meist auch ein OS-API. Ich denke mal, dass es Funktionen, welche die Anzahl von Bytes im Empfangspuffer zurückgeben auch in C++ oder was auch immer gibt. Damit dürfte der TE am schnellsten zum Ziel kommen.
Jens schrieb: > Wenn ich mich recht erinnere, gab es Funktionen für die serielle > Schnittstelle schon in den frühen Versionen von VB, noch ohne .NET. Ja, richtig. Über COM (MSCOMM32.OCX, glaube ich). > Ich denke mal, dass es Funktionen, welche die Anzahl > von Bytes im Empfangspuffer zurückgeben auch in C++ oder was auch immer > gibt. In C++ bzw. der Standardbibliothek und der STL nicht, da es systemabhängig ist, aber es existieren entsprechende Bibliotheken, z.B. Boost.Asio (boost::asio::serial_port).
Wenn er nen blockierenden ReadFile macht dann nützt ihm nen timer auch nichts. Die Timeouts der Comm Funktionen nutzen sollte die angestrebte Lösung sein.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.