Hallo. Habe im Anhang eine funktionierendes Programm. Nur finde ich die Verschachtelungen durch folgenden Beingungen(*) sehr aufwendig. Können solch multiple Bedingungs-Verschachtelungen, einfacher programmiert/dargestellt werden? (*) Hier werden je nach Spg-Eingang 3 unterschiedliche LEDs geschaltet. Bei schnellem Zustandswechsel von LED1 zu LED3 (und umgekehrt), muss ein zeitlicher Zwischenschritt über LED2 erfolgen. PS: Rechte beigelegte Datei ist übersichtlicher. Konnte linke Datei nicht mehr löschen.
Bei nur 2 case Anweisungen würde ich auf den switch komplett verzichten und stattdessen if Abfragen nehmen. Zudem setzt du Led auf einen Wert, ohne danach noch etwas damit zu machen. Der Rest sieht doch eigentlich gut aus, oder was wolltest du vereinfachen?
1 | void Led_Ein(uint8_t Led) |
2 | {
|
3 | static uint8_t LetztLed = 0xFF; |
4 | if(LetztLed != Led) |
5 | {
|
6 | if(Led == 1) { |
7 | LED_HIGH; |
8 | } else if(Led == 2) { |
9 | LED_MID; |
10 | Warte(2000); |
11 | } else { |
12 | LED_LOW; |
13 | Led=3; |
14 | }
|
15 | LetztLed=Led; |
16 | }
|
17 | }
|
Edit: Gut beim letzten else brauchts das Led=3
z.B. so
if(MitWert>=OBER_BEREICH)
{
if(Led==3)
Led_Ein(2);
Led_Ein(1);
Led=1;
}
Operator S. schrieb: > oder was wolltest du vereinfachen? Ich würde das hier rausschmeißen: > Warte(2000); > Warte(100); // [mSek], Wartezeit bis nächste Messwertauswertung Ein _delay_ms() (oder hier eben ein Warte()) im Hauptprogramm (also nach der Initialisierung) ist ein Programmfehler und muss behoben werden. Und eine Funktion, die nur der LED-Anzeige dient, darf niemals die Auswertung des Hauptprogramms anhalten. > Bei schnellem Zustandswechsel von LED1 zu LED3 (und umgekehrt), muss ein > zeitlicher Zwischenschritt über LED2 erfolgen. Diese Definition ist halbgar. Was, wenn der Signalverlauf so ist: 1 --> 250ms lang 2 --> 3 Dann wechselt die LED ja über 2 und damit "schnell"...
Lothar M. schrieb: > Was, wenn der Signalverlauf so ist: 1 --> 250ms lang 2 --> 3 > Dann wechselt die LED ja über 2 und damit "schnell"... Durch den "LED2; Warte(2000);" ist immer gewährleistet, dass jegliche Zustandsänderung, min 2 Sek (Testhalber) bei LED2 verbleibt. Lothar M. schrieb: > Warte(100); Der Sinn ist mittlerweile tatsächlich fraglich. Lothar M. schrieb: > Und eine Funktion, die nur der LED-Anzeige dient, darf niemals die > Auswertung des Hauptprogramms anhalten. Meinst du, dass eine _delay_ms()/Warte() immer in main() gehört? Als Ersatz müsste ich aber diese Warteschleife 3 mal ins main() einfügen.
__Son´s B. schrieb: > Meinst du, dass eine _delay_ms()/Warte() immer in main() gehört? Nein. Er meint damit, dass Du der main()-Funktion die Luft zum Atmen nimmst. Bei Deinem Mini-Programm ist das kein Problem. Aber stell Dir vor, Du müsstest noch viele andere Sachen aus main() aufrufen und das alles in einer bestimmten Zeit. Dann bremst Dich die LED-Anzeige-Funktion komplett aus! > Als Ersatz müsste ich aber diese Warteschleife 3 mal ins main() > einfügen. Nein, lies mal hier: Statemachine und Multitasking
Erstmal kann man sortieren, was in main alles passiert: Irgendwas wird 1) gemessen, 2) bewertet (die Vergleiche) und 3) das Ergebnis angezeigt. Das kann man auseinanderziehen und Variablen/Funktionen nach der Absicht und nicht nach dem Inhalt benennen. Siehe Anhang. Jetzt bleibt der Wust mit den LEDs übrig. Da sind momentan zwei Zustandsautomaten geschachtelt. Das kann man analysieren und einen daraus machen: https://www.mikrocontroller.net/articles/Statemachine
Tom schrieb: > Das kann man analysieren und einen > daraus machen: https://www.mikrocontroller.net/articles/Statemachine DANKE, mit diesen Gedanken werde ich mich beschäftigen. Ev. über Auswertetabelle? Bsp: (Achtung nur Gedanken!) (MitWert>=OBER_BEREICH) und (Led==3) dann Led=3 (MitWert>=UNTER_BEREICH und (Led==2) ... (MitWert<=OBER_BEREICH) ... . . . switch(Led) { case 1: ... case 2: ... . . .
__Son´s B. schrieb: > Ev. über Auswertetabelle? Erstmal mit Kästen und Pfeilen. Mir ist klar, dass das nervig ist, aber wenn das in dieser Form geklärt ist, kann man den Code ohne viel zu denken tippen. Wenn man die einzelnen Zustände und ihre Übergänge noch nicht vollständig im Blick hat, sollte man meiner Erfahrung nach keinen Quellcode anfassen.
Was soll den passieren, wenn der Messwert überwiegend die mittlere LED aktiviert, und kurzzeitig mal eine der äusseren? Dann würde im Augenblick die äussere LED für 100ms aufblitzen und dann wieder für 2 Sekunden die mittlere leuchten. Ist das so beabsichtigt, oder sollte dann nicht auch die äussere LED für 2 Sekunden an bleiben?
Tom schrieb: > Wenn man die einzelnen Zustände und ihre Übergänge noch > nicht vollständig im Blick hat, sollte man meiner Erfahrung nach keinen > Quellcode anfassen. (*) Natürlich - vor Jahrzehnten gelernt, aber zunehmend (aus Bequemlichkeit) eingeschlafen... Joe F. schrieb: > Dann würde im Augenblick die äussere LED für 100ms aufblitzen und dann > wieder für 2 Sekunden die mittlere leuchten. Was passiert im Grenzbereich der äusseren Zustände? Stimmt, hatte ich aus dem Blick (*) verloren.
Tom schrieb: > Erstmal mit Kästen und Pfeilen. Mir ist klar, dass das nervig ist, > aber wenn das in dieser Form geklärt ist, kann man den Code ohne viel zu > denken tippen. Mache ich auch so. Selbst wenn man meint, alles im Kopf überblicken zu können, merkt man dann beim Debuggen, daß was vergessen wurde. Also eigentlich immer erst aufmalen, völlig egal, wie popeleinfach die Aufgabe erscheint. Und komplexe Statemachines in mehrere unterteilen.
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.