Verschachtelungen entschlacken

OP #4426755
Lesenswert?

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.
Angehängte Dateien:
#4426779
Lesenswert?

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
Moderator (Firma: Titel) Persönliche Seite #4426818
Lesenswert?

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"...
OP #4426838
Lesenswert?

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.
Moderator Persönliche Seite #4426845
Lesenswert?

__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
Gast #4426854
Lesenswert?

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
Angehängte Dateien:
OP #4426885
Lesenswert?

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: ...
.
.
.
Gast #4427039
Lesenswert?

__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.
#4427371
Lesenswert?

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?
OP #4431793
Lesenswert?

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.
#4431977
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren