Hallo Leute, einfaches Problem: Ich möchte eine LED Blinken lassen um den Datenfluss einer Seriellen Schnittstelle zu visualisieren, dabei soll die LED umso schneller Blinken (Sichtbares Blinken), je schneller die Daten kommen Ich finde keine einfache lösung, die den Prozessor nicht zu stark belastet, bitte helft mir
Findest Du denn eine einfache Lösung für das Problem "LED mit konstantem Takt blinken lassen, bei minimaler Prozessorbelastung"?
LED an die RXD- und TXD-Leitung über einen Treiber anschliessen und schon blinken die Dinger, sobald Datenfluß vorhanden ist. Andere Möglichkeit: PortPin in der InterruptServiceRoutine togglen. Oder einen Timer beschreiben, der wiederum das Blinken der LED verursacht. Übrigens 1A-schwammig ausgedrückt: Welche serielle Schnittstelle? Die eines Mikrocontrollers oder die eines PC? So Festplatten-LED mässig...
Ich meine die Serielle Schnittstelle eines AVR und die LEDs sollen SICHTBAR Blinken 115 KBd sind nicht gerade sichtbar !!!
So ist es! Arbeitet Dein Programm auf Timerbasis? Oder gibt es "Delayschleifen" nach Art von "FOR i=0...100000 TueNichts"? Falls die erste Alternative zutrifft, ist Dein Problem relativ leicht lösbar (merke: Timer = schlau, Delayschleifen = doof!). Wie groß (ms) ist das "Tickintervall" des Timers der Dein Programm steuert?
Wie wärs denn mit folgender Überlegung: Wenn die Schnittstelle Aktiv ist dann springst du ja in die entsprechende Routine um die Schnittstelle zu bedienen (Daten Holen/Abliefern) Was spricht dagegen am Afang der Routine die LED einzuschalten und am ende wieder aus ? Je nach Zugrif dürfte sich dann eine art "Pseudo-PWM-Effekt" einstellen. Jedenfalls sieht man wenn die Serielle aktiv ist. Oder du verwendest die Ide von Rahul und verfeinerst sie einwenig in Bezug auf Geschwindigkeitsanzeige. Die Methode kostet dann überhaupt keine Rechenzeit. Probier einfach mal . Ne Transe nebst Widerstand und evtl. Kondensoator hatse ja wohl noch inner Schublade.
Es gibt noch keinen Timer in meinem Programm und nur für eine LED einen Timer verheizen, ich weis nicht Eine Delayschleife geht auch nicht wegen der Prozessorauslastung
Ich will einfach nur den Effekt haben den man bei externen Festplattengehäusen (die LED daran) oder der HDD LED eines PC´s hat, Schneller Datenverkehr --> schnelles Blinken
>Eine Delayschleife geht auch nicht wegen der Prozessorauslastung Richtig! Und deshalb bleibt nur der Timer. Allerdings: Wenn Du nicht nur die UART-Strom-Anzeige-Blink-LED haben willst, sondern z. B. auch noch eine Echtzeituhr in Deine Software integrieren willst, dann brauchst Du nicht je einen Timer für die LED und die Uhr, sondern Du brauchst nur einen Timer für beide Aufgaben! So ein µC hat genügend Leistung, um locker 28 Aufgaben zeitgleich zu bewältigen (1. Echtzeituhr, 2. Temperatursensor auslesen plus Daten loggen, 3. Siebensegmentanzeige im Multiplexverfahren ansteuern, 4. Mit PC über UART kommunizieren, 5. Relais für 1 min einschalten wenn Temperatur zu klein, 6. Zustand einer Pumpe überwachen, 7. ..., 8. ... usw.). Damit das alles geordnet abläuft, muß so ein Multitasking-Programm timergesteuert arbeiten. *Aber*: Du brauchst nicht für jeden Task einen eigenen Timer, sondern bloß einen Timer für alle Tasks. Man könnte sagen, Du hängst praktisch Dein komplettes Programm an einem einzigen Timer auf. Damit relativiert sich das dann auch mit dem "Verheizen" ;-). Jetzt kommt's darauf an, ob Du Dich mit der Timersache anfreunden kannst. Nochmal: Auf Delayschleifenbasis wirst Du die Blink-LED nicht realisieren können.
Mal ne generelle Frage zum Thema: Bei Festplatten geht ne LED an, wenn Daten übertragen werden, bei Netzwerkkarten ist es meist so, dass die LED ausgeht wenn Traffic fliesst, also quasi andersrum wie bei Festplatten. Aber bei beiden zeigt die Blinkfrequenz die Auslastung an - wie wird das da realisiert? Läuft das irgendwie gequantelt mit bestimmten Stufen ab? Bei ein oder zwei Bytes wird vermutlich ja noch kein Blinken zu erkennen sein oder?
ach wenn meine festplatte auf volllast ist blinkt bei mir übrigens nix mehr du hats uns ja sehr genau beschriben wie es blinken soll ????? :) na wenn du nicht programmieren willst bzw. den µC nicht belasten willst bleibt nur noch die digitaltechnik überig bastel dir halt was aus cmos 4xxx bausteinen und hängs an die rdx tdx leitungen hab mir kurz was überlegt siehe anhang
ach hab nen fehler reingebracht das xnor gatter ist ein nor gatter
> und nur für eine LED einen Timer verheizen, ich weis nicht. Wieso "verheizen"? Wer hält dich davon ab, den Timer noch für andere Sachen zu verwenden? > Dass muss doch irgendwie einfacher gehen, ohne timer, ohne extra > Hardware. Ist doch nur ne LED Du willst keine Rechenzeit verbrauchen, keine anderen Ressourcen der MCU, aber auch keine externe Hardware verwenden. Wie soll die LED denn dann wissen, wann sie leuchten soll? Egal. Warum nicht einfach so: In der Interrupt-Routine der Schnittstelle dekrementierst du für jedes übertragene Byte eine Zählvariable, die vorher auf einen vorgegebenen Wert initialisiert war. Wenn sie bei 0 angekommen ist, toggelst du die LED und initialisierst den Zähler wieder neu. Bei vielen Bytes pro Sekunde blinkt sie dann schnell, bei weniger Bytes langsam, und über den Anfangswert des Zählers kannst du das Verhältnis zwischen Datenrate und Blinkgeschwindigkeit leicht anpassen.
Habe ich schon probiert, wenn ich aber mit dem Terminalprogramm einzelne Bytes verschicke, geht garnichts mit der LED da durch die Zählvariable immer nur jedes Hundertste Byte angezeigt wird. ABER dies ist die Lösung die mir bis jetzt am besten gefällt da sie sehr Rechenzeitsparend ist. Mein Problem ist noch: Die LED dienen in den Sendepausen als indikatoren ob die RS232 überhaupt freigeschaltet ist oder nicht (kann vom PC aus gesteuert werden über einen USB Baustein) ALSO: LED an --> RS232 berreit LED aus --> RS232 nicht freigeschaltet LED Blinken --> RS232 arbeitet Mein Problem Die LED soll immer AN sein (wenn rs232 aktiv) und bei Datenverkehr blinken, dies ist aber durch toggeln nicht gewährleistet und wenn ich die LED in der Hauptschleife immer wieder anschalte sieht man kein Blinken mehr, da die Hauptschleife 90% aller Zeit beansprucht
Mal angenommen, ich stelle Dir folgende Aufgabe: -------------------------------------- "Zeitschaltuhr": Beim Drücken einer Taste soll eine LED angehen, 3 Sekunden lang leuchten und danach ausgehen. Das ist alles, was der µC zu erledigen hat. -------------------------------------- Diese Aufgabe ist leicht lösbar, und es gibt sogar zwei Ansätze: Mit Delayschleife oder mit Timer. Voll easy, meinst Du sicher. Aber warte, denn jetzt kommt die nächste Aufgabe: -------------------------------------- "Doppel-Zeitschaltuhr": Es gibt ZWEI Tasten Ta und Tb, und ZWEI LEDs La und Lb. Beim Drücken der Taste Ta soll die LED La angehen, 3 Sekunden lang leuchten und danach ausgehen. Genauso soll es sich mit Tb und Lb verhalten. Beide Zeitschaltuhren sollen völlig unabhängig voneinander sein (genau so, als liefe jede auf einem eigenen µC). -------------------------------------- So, und jetzt denk mal darüber nach, wie kompliziert oder einfach das ist, wenn Du die Einzel_Zeitschlatuhr mit Delayschleifen realisiert hast, und wie kompliziert oder einfach es ist, wenn Du sie mit einem Timer realisiert hast. Wie lauten Deine Antworten?
@Jochen: Bei mir blinkt keine LED mehr, wenn die Festplatte läuft. Zumidest sehe ich es nicht, weil sie im Gehäuse liegt...
Hallo Mr Bolle, wiso sprichst du immer in Rätseln??? Natürlich wird deine aufgabe mit doppelter Zeitschaltuhr nur mit Timer(n) möglich sein die einen Interrupt auslösen. Aber was heisst das für meinen Fall. Wie würdest du das Konkret Regeln für eine Serielle Schnittstelle mit RX und TX Kanal die Beide eine LED Blinken lassen sollen bei Datenverkehr???
Zähle die Bytes pro Timerumlauf, nimm diese Zahl X und subtrahiere sie von einer anderen Zahl Y, die Du alle paar Timerumläufe auf 255 initialisierst (an die gewünschte Blinkfrequenz anpassen). Durch diese Zahl Y teilst Du die umlaufende Timerfrequenz in einem Softwarezähler, den Du in der Timer-ISR mit decrementierst und was dabei ´rauskommt, gibst Du auf die LED. Wenn kein Byte transferiert wird und Zahl Y immer 255 ist, ist die LED an (Vergleich auf 255 ausführen). Wenn ein Byte transferiert wurde und Y demzufolge 254 ist, dann soll der Teil-Zähler in der Timer-ISR loslaufen und die LED blinkt 1 mal. Ist danach Y wieder 255, dann war´s das mit blinken, wenn nicht, blinkt´s weiter. Je kleiner Y wird, weil mehr Bytes pro Timerdurchlauf transferiert wurden, desto öfter und schneller blinkt´s. Die an/aus-Zeiten der LED kann man in dem Softwarezähler durch Vergleiche festlegen.
machs so wie rolf und ein timer kannst dazu verwenden die LED nach entsprechender zeit wieder auf high zu setzen z.b. timer hat T=1ms flag für verkehr während des letzten 1ms wenn verkehr flag zurücksetzten wenn kein verkehr LED high setzen evtl. auch zähler in den isr der rs232 rücksetzen da du leider nicht angibts ab wann was blinken soll .... T bestimmt hier die zeit in der ein byte übertragen werden muss damit es als verkehr/arbeit durchkommt ach ja und ich würde sofort bei ner isr der rs232 das LED low setzen nähmlich wenns nur ein byte war wird es spätesten eben nach T=1ms zurückgesetzt und das ist eher weniger sichtbar
Wie wär's hiermit: //------------------------------// #define OFF 0 // #define ON 1 // // #define BLINK_MAX 100 // Gesamtzyklen #define BLINK_ON 50 // Zyklen fuer On-Zeit // unsigned char uiCount; // Zaehlregister unsigned char ucState; // Statusregister // //------------------------------// void v_Blink (void) // { // uiCount++; // Zaehlregister inkrementieren if(uiCount <= BLINK_ON) // ON waehrend On-Zeit ucState = ON; // else { // if(uiCount < BLINK_MAX) // OFF waehrend Off-Zeit ucState = OFF; // else { // uiCount = 0x00; // Zaehlregister ruecksetzen ucState = OFF; // } // } // } // //------------------------------// void main (void) // { // while(1) // { // v_Blink(); // // } // } // //------------------------------// Du brauchst jetzt nur noch das Statusregister ucState, verknüpft mit dem Status der Schnittstelle, auf den LED-Port zu geben und schon blinkt Deine LED. Außerdem müssen noch die Anzahl der Zyklen an die while-Schleife angepasst werden. Gruss, Jan
Wie wär's hiermit: //------------------------------// #define OFF 0 // #define ON 1 // // #define BLINK_MAX 100 // Gesamtzyklen #define BLINK_ON 50 // Zyklen fuer On-Zeit // unsigned char uiCount; // Zaehlregister unsigned char ucState; // Statusregister // //------------------------------// void v_Blink (void) // { // uiCount++; // Zaehlregister inkrementieren if(uiCount <= BLINK_ON) // ON waehrend On-Zeit ucState = ON; // else { // if(uiCount < BLINK_MAX) // OFF waehrend Off-Zeit ucState = OFF; // else { // uiCount = 0x00; // Zaehlregister ruecksetzen ucState = OFF; // } // } // } // //------------------------------// void main (void) // { // while(1) // { // v_Blink(); // // } // } // //------------------------------// Du brauchst jetzt nur noch das Statusregister ucState, verknüpft mit dem Status der Schnittstelle, auf den LED-Port zu geben und schon blinkt Deine LED. Außerdem müssen noch die Anzahl der Zyklen an die while-Schleife angepasst werden. Gruss, Jan
Ich denke wenn diese Schleife mit einem Prozessor an 14745600 Hz durchlaufen wird, blinkts ganz schoen schnell, oder nicht ?? Wie meinst du dass mit dem Verknüpfen der Seriellen Schnittstelle und ucState, und wo gehe ich auf den PORT der LED ???
> wiso sprichst du immer in Rätseln??? Es gibt hier eine Menge anti-timer-eingestellte User. "Timer? Braucht man nicht! Nur Verschwendung wertvoller Ressourcen! Geht alles mit Delayschleifen! Ich will doch nur [irgendeine Aufgabenstellung, die darauf hinausläuft, daß mehrere Tasks gleichzeitig parallel ausgeführt werden sollen], aber ich möchte es auf jeden Fall mit Delayschleifen programmieren, denn die kenne ich, damit kam ich bisher prima zurecht, weshalb ich nicht sehe, wozu ich mich jetzt mit Timern beschäftigen sollte (nur unnötig kompliziert...)". Ich wollte Dir mit dem Doppelt-Zeitschaltuhr-Beispiel verdeutlichen, daß mit Delayschleifen eben nicht alles geht, sondern im Gegenteil, daß der Delayschleifen-Ansatz extrem begrenzt ist: Schon bei zwei unabhängigen Zeitschaltuhren ists Essig. Wie kann man dann aber eine Anwendung realisieren, bei der es gefordert ist, daß der Controller 5 oder 12 oder 30 Aufgaben parallel bewältigt? Delayschleifen? Keine Chance! Wenn dem aber so ist, dann bleibt nur noch der Timeransatz. Weiter oben im Thread habe ich schon mal geschrieben "Timer = schlau, Delayschleifen = doof". "Schlau" weil mit Timern alle Multitasking-Möglichkeiten offenstehen. Damit ich Dir helfen kann, mußt Du das jedoch erstmal verstanden haben. >Natürlich wird deine aufgabe mit doppelter Zeitschaltuhr nur mit >Timer(n) möglich sein die einen Interrupt auslösen. Ja! Aber wieviele Timer benötigt man? Zwei? Oder geht es auch mit einem? Wieviele Timer würde man für eine Zehnfach-Zeitschaltuhr benötigen? Zehn oder einen? Wüßtest Du eine Lösung, die nur einen Timer benötigt? Wie sähe sie aus? Die Antworten auf diese Fragen sind wichtig. >Wie würdest du das Konkret Regeln für eine Serielle Schnittstelle mit >RX und TX Kanal die Beide eine LED Blinken lassen sollen bei >Datenverkehr??? Soviel vorweg: Mit Timer ist die Aufgabe ein Klacks.
Schon wiedr Rätsel ;)
Also zu deinen Zehn Zeitschaltuhren:
Zehn Zählvariablen die bei Tastendruck freigegeben werden durch Meker
(Strom --> AN)
und dann in EINER Timerroutine hochgezählt werden bis zum Zielwert
(Strom-->wieder aus)
Also war dass Korrekt???
>Soviel vorweg: Mit Timer ist die Aufgabe ein Klacks.
Jetzt kannst du mir ja mal deine Klacks verraten
Schon wiedr Rätsel ;) >Also zu deinen Zehn Zeitschaltuhren: > >Zehn Zählvariablen die bei Tastendruck freigegeben werden durch Meker > >(Strom --> AN) > >und dann in EINER Timerroutine hochgezählt werden bis zum Zielwert > >(Strom-->wieder aus) > >Also war dass Korrekt??? Korrekter geht's gar nicht. Verstehst Du, daß sich die Zählvariablen sozusagen als *Software*-Timer interpretieren lassen? Jede Zeitschaltuhr stellt einen Task dar, und jeder der Tasks hat seinen eigenen Software-Timer (je nach Anwendung könnte es natürlich auch Tasks geben, die mehrere Softwaretimer haben). Software-Timer sind nämlich keine knappe Ressource, sie benötigen ja nur RAM-Speicher. Hardware-Timer stellen eine knappe Ressource dar (der ATMega8 hat z. B. nur drei Stück), aber dafür benötigt man nur einen Hardware-Timer, der die 28 Software-Timer (oder wieviele alle Tasks halt zusammen haben) "antreibt". Wichtig ist auch, verstanden zu haben, daß der Hardware-Timer, der die 28 Software-Timer in einem timergesteuerten Programm treibt, niemals gestoppt werden muß. Er läuft permanent. Gestartet und gestoppt werden nur die Software-Timer; für sie gibt es den Zustand "läuft"/"aktiv" und den Zustand "läuft nicht"/"inaktiv" (Deine "Merker"-Variable dient dazu, diesen Zustand zu speichern). Eine Frage bleibt noch: Mit welcher Frequenz soll der Hardware-Timer laufen? Dazu kann man nur sagen: Sie darf nicht zu hoch und nicht zu niedrig sein. Sie darf nicht zu hoch sei, damit der µC noch eine gewisse Anzahl von Befehlen abarbeiten kann, bevor er die Timer-Interruptroutine wieder verläßt. Und sie darf nicht zu niedrig sein, damit das Programm noch genügend schnell auf z. B. Tastendrücke reagiert. Damit ist man in der Praxis ganz grob auf den Bereich 1 ms ...100 ms eingeschränkt. Während 1 ms schafft ein ATMega8 bei 4 MHz noch ca. 2000 Instruktionen; bei 10 Tasks darf dann jeder immerhin noch 200 Instruktionen rechnen. So, jetzt bist Du bestens vorbereitet. >Jetzt kannst du mir ja mal deine Klacks verraten Die Aufgabe besteht offensichtlich aus zwei Tasks: 1. Der Pro-Zeiteinheit-eintreffende-UART-Daten-Zähl-Task ("PZEUD-Task"), und 2. Der LED-Blink-Task ("LB-Task"). In den Interrupt-Handler des Hardware-Timers, der Dein Programm steuert, fügst Du also zu der Liste der Tasks, die dort schon stehen, folgende Unterroutinen hinzu: Run_PZEUD_Task Run_LB_Task Der PZEUD-Task hat wie schon erwähnt die Aufgabe, die pro Zeiteinheit eintreffenden UART-Daten zu zählen. "Pro Zeiteinheit" deutet schwer darauf hin, daß der Task einen Software-Timer benötigt. Ich nenne ihn "k". k zählt ununterbrochen von 0 bis zu einem Maximalwert und startet danach wieder bei Null. Der Maxwert definiert die Zeiteinheit ("Torzeit"). Sie könnte z. B. bei 250 ms liegen. Kommt nun über den UART ein Byte hereingeschneit, dann muß das registriert werden, in einer Zählvariable "DataInAkku". In den USART-Receive-Interrupt mußt Du also ein "Inc(DataInAkku)" einfügen. Jedesmal, wenn der k-Zähler nun seinen Max-Stand erreicht hat (d. h. es sind mal wieder 250 ms um), wird der DataInAkku-Zähler in einer Variable "DataInCount" abgespeichert, und danach auf Null resettet. Sinn des Ganzen: DataInCount enthält dann zu jedem Zeitpunkt (!) die Anzahl der über den UART während der letzten Torzeit empfangenen Bytes. Er stellt somit ein Maß dafür dar, wieviel gerade auf der UART-Receive-Leitung los ist. Und er wird mit einem Takt von 250 ms laufend geupdatet. Nun zum LB-Task. Er kümmert sich um die LED. Da die LED gemütlich blinken soll (Sekundentakt), der Hardware-Timer aber rast, brauchen wir hier ebenfalls einen Software-Timer, repräsentiert durch die Variable "BlinkIntervalAkku". BlinkIntervalAkku wird laufend inkrementiert bis zu einem Max-Stand, dann auf Null resettet und die LED getoggelt. Man könnte nun stets um 1 inkrementieren; dann bestimmt der Max-Stand die Blinkfrequenz. Es steht aber nirgendwo, daß wir nicht z. B. auch um 8 inkrementieren dürfen; bei 8-fachem Max-Stand führt das zur selben Blinkfrequenz. Bei gleichem Max-Stand führt die Inkrementation mit 8 jedoch zur 8-fach schnelleren Blinkfrequenz! Also: Max-Stand wird auf einen Wert festgelegt und niemals verändert; der Inkrementationsschritt i aber ist nicht immer derselbe: i = 1 -> Langsames Blinken, i = 2 -> doppelt so schnelles Blinken, i = 5 -> fünffach so schnelles Blinken. Im Grunde wird hier übrigens eine Division durchgeführt, und zwar Max-Stand/i. Und jetzt kommt der Clou: Du verwendest als Inkrementationsschritt die DataInCount-Variable aus dem PZEUD-Task! Damit bist Du praktisch fertig. Eine gesonderte Behandlung benötigt nur noch der Fall, daß mal während einer Torzeit kein einziges Byte empfangen wird. Dann würde der BlinkIntervalAkku auf der Stelle verharren, und die LED ginge gar nicht mehr an, wenn sie gerade aus ist und umgekehrt, was nicht erwünscht sein dürfte. Dagegen läßt sich aber leicht was tun. Studiere mal diesen Code: //------------------------------- // Run_PZEUD_Task //------------------------------- Inc(k); IF (k=...) { // wird alle 250 ms ausgeführt k := 0; DataInCount := DataInAkku; DataInAkku := 0; } //------------------------------- // Run_LB_Task //------------------------------- IF (BlinkIntervalAkku=-1) AND (DataInAkku=1) { [LED aus] } ELSE { IF (DataInCount=0) { [LED ein]; BlinkIntervalAkku := -1 } ELSE { Inc(BlinkIntervalAkku, DataInCount); IF (BlinkIntervalAkku>=...) { [LED togglen]; BlinkIntervalAkku = 0 } } Dort wo "..." stehen, mußt Du passende Werte einsetzen (hängen u. a. ab vom Tickintervall Deines Hardware-Timers). War's einigermaßen verständlich? Ansonsten einfach fragen. Dann bekommst Du weitere Rätsel ;-).
Denn Cod ehabe ich fast verstanden sind da vieleicht noch einpaar schreibfehler drin in den Zeilen: > ... > IF (BlinkIntervalAkku=-1) AND (DataInAkku=1) > ... > > [LED ein]; > BlinkIntervalAkku := -1 > ... ICH verstehe nicht warum du diese Variablen auf 1 bzw -1 abprüft. Was bedeutet := ist dass eine Zuweisung? also nur = ??? Ansonsten vielen Dank für die Hilfe werde dass heute Abend mal testen ____________________________ Ich habe übrigens währenddessen folgende Lösung gefunden und muss sie mit deiner vergleichen welche schneller ist: led1_ctr wird in der interruptroutine der Schnittstelle erhöht und Zählt die bytes softctr1 ist ein Softwarcounter und die Merker brauche ich für einen definierten durchlauf der if bedingungen Dass ganze steht in einem Timmerinterrupt alle 30 ms und funktioniert schon recht ordentlich. // Variable Blinkfrequenz LED1 if ( led1_ctr ) { softctr1 += led1_ctr; if ( (softctr1 > 100) && (merker1 == 2) ) { led1_ctr = 0; softctr1 = 0; merker1 = 0; } else if ( (softctr1 > 50) && (merker1 == 1) ) { merker1 = 2; led1_on(); } else if (merker1 == 0) { merker1 = 1; led1_off(); } }
> ... > IF (BlinkIntervalAkku=-1) AND (DataInAkku=1) > ... > > [LED ein]; > BlinkIntervalAkku := -1 > ... ICH verstehe nicht warum du diese Variablen auf 1 bzw -1 abprüft. Was bedeutet := ist dass eine Zuweisung? also nur = ??? Ja, ":=" ist eine Zuweisung (üblich z. B. in Pascal). Der Zweck der von Dir angeführten Zeilen ist in der Tat nicht offensichtlich. Sorry, hab ich nicht dran gedacht. Hier also die Erklärung. IF (DataInCount=0) { [LED ein]; Das sollte noch klar sein. Wenn während eines Torzeit-Intervalls einmal kein einziges Byte reingekommen ist ("Zero-Traffic"), dann soll die LED an gehen, und zwar sofort, und danach soll sie dauerhaft an bleiben, um den "Schnittstelle-Eingeschaltet"-Zustand zu signalisieren. Besteht der Zero-Traffic für 5 Minuten, dann ist die LED wie gewünscht 5 Minuten an. Prima. Aber dann kommt ein einziges Byte herein! Du kannst Dir überlegen, daß ein solches einzelnes Byte bei diesem Algorithmus unter Umständen nicht reicht, um das LED-Blinken "auszulösen". Es wäre also der Fall denkbar, daß Du - z. B. zu Testzwecken - einzelne Bytes im Sekundenabstand von Deinem PC zu dem Modul sendest, die LED das aber nicht anzeigen würde; sie würde einfach konstant an sein. Das ist nun blöd. Es wäre sicher toll, wenn bei so einem "einzelnen Byte" die LED kurz ausgehen würde, um den Eingang zu signalisieren. Genau dies ist der Sinn hinter dem BlinkIntervalAkku := -1. Wenn einmal Zero-Traffic detektiert wurde (DataInCount=0), wird BlinkIntervalAkku auf den "Zero-Traffic-Spezialwert" -1 gesetzt, und behält ihn auch, weil "Inc(BlinkIntervalAkku, DataInCount)" keine Wirkung hat bei DataInCount=0. Kommt während einer der Zero-Traffic-Phase ein einzelnes Byte, dann ist die Bedingung "IF (BlinkIntervalAkku=-1) AND (DataInAkku=1)" erfüllt, und die LED wird sofort ausgeschaltet. Damit sie wieder an geht, ist keine weitere Extra-Maßnahme erforderlich, das läuft ganz normal über den schon vorhandenen Mechanismus. Interessant ist, daß diese lächerlichen paar Zeilen in der Praxis verblüffend gut funktionieren. Ich hatte mit dieser Aufgabenstellung mal vor längerer Zeit in eigener Sache zu tun, und den Algorithmus zu Testzwecken in einem Delphi-Programm simuliert. Du findest es im Anhang. Das Eintreffen eines UART-Bytes simulierst Du durch Drücken irgendeiner Taste. Die angezeigte Zahl ist der DataInCount-Wert. Das Timer-Intervall beträgt 20 ms, die Torzeit 500 ms. >Ich habe übrigens währenddessen folgende Lösung gefunden und muss sie >mit deiner vergleichen welche schneller ist: Äh schneller? Das verstehe ich jetzt nicht. Inwiefern soll hier eine Lösung schneller sein, als die andere? Ich habe Deine Lösung aus Zeitgründen nur überflogen; ich bitte um Verständnis. Wenn ich es richtig gesehen habe, verwendest Du keine feste Torzeit. Ich weiß nicht, ob das gut ist.
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.