Forum: Mikrocontroller und Digitale Elektronik verschachtelte if Anweisung


von Schwarz (Gast)


Angehängte Dateien:

Lesenswert?

Auf den STK 500, werden zwei Tasten belegt.
PD5 genannt HAND        Taster STK 500   SW 5
PD4 gennant SENSOR      Taster STK 500   SW 4

Es sind weiter drei Ausgägnge nötig
PB0 genannt betriebA      LED 0
PB1 genannt betriebH      LED 1
PB2 genannt betriebP      LED 2

gewünschte Funktion des Programms
1.)
Wird die Taste HAND gedrückt oder gehalten
soll
betriebH und zeitgelich betriebP aktiv sein > LED 1 und 2 an
2.)
Wird keine Taste gedrückt
soll
betriebA aktiv sein > LED 0
3.)
Nur wärend des betriebA Zustand 2.) kann eine drücken der Taste PD4 
SENSOR
detriebP aktivieren > LED 2 leuchten
betreibP ist über ein simples _delay_ms(1000) auf eine Laufzeit von 
einer Sekunde begrenzt.
und zusätzlich soll betriebA > LED 0 leuchten

Dieser Tread wurde gestern schon von mir gestellt und ist auffrund 
meines Fehlverhaltens in jede erdenklich Richtung gelaufen.

Der gesamter Code ist im Anhang.
Die "Funktion" 1.) und 2.)
ist über diesen Code-Ausschnitt
1
 
2
  while(1)
3
  {
4
    if (!(PIND &  (HAND))) // Wenn NICHT HAND betätigt dann
5
    {
6
      PORTB = (betriebA);
7
    }
8
    else
9
    {
10
      PORTB = (betriebH) | (betriebP);// Handbetrieb aktiv
11
    }
12
13
  }
realisiert.

Der Code wurde um ein if/else erweitert um den Zustand 3.) zu erhalten
1
  while(1)
2
  {
3
    if (!(PIND &  (HAND))) // Wenn NICHT HAND betätigt dann
4
    {
5
      if(PIND & (SENSOR))
6
      {
7
        PORTB = (betriebP);
8
        _delay_ms(1000);
9
        PORTB = (betriebA); 
10
      }
11
      else
12
      {  
13
        PORTB = (betriebA);
14
      }  
15
    }
16
    else
17
    {
18
      PORTB = (betriebH) | (betriebP);
19
    }
20
  }

Was jetzt passiert

Die LED 0 betriebA leuchtet
wird der Taster HAND betätigt (kürzer _ms (1000)ms) leuchtet die LED 1 
betriebP für die definierte Zeit;
zeitgelich erlischt betriebA und bleibt aus.

(PD5 HAND hat nun das Ereignis eingeleitet, welches nur mit PD4 SENSOR 
starten soll)

Wird der Taster HAND länger als die _ms(1000) gehalten blitzt die LED 2
betriebH ganz kurz und schwach ich schätze im Takt _ms(1000);
betreibA erlischt und bleibt aus.

Wird der TAster PD4 SENSOR betätigt ist keine Veränderung der Zustände 
zu erkennen.

Die Zeitvorwahl (Ablaufplan) ist noch nicht implemntiert und soll jatzt 
auch nicht das Thema sain.

von Hmm (Gast)


Lesenswert?

Ach bitte! Nicht den ganzen Sums noch einmal von vorne. 
Beitrag "Re: if Anweisung schachteln C"

Nun denk mal gefälligst selbst nach.

von Stefan (Gast)


Lesenswert?

Sorry, aber die ersten 20 Zeilen verstehe ich überhaupt nicht. Weiter 
habe ich zunächst nicht mehr gelesen. Möglicherweise scheitert das 
Vorhaben auch für Dich daran, dass die Aufgabenstellung nicht klar 
beschrieben ist.

Ich habe mal versucht, die ganze Aufgabenstellung klarer zu formulieren, 
was mir aber nicht gelungen ist. Problematisch finde ich diesen Zusatz:

>> betreibP ist über ein simples _delay_ms(1000) auf eine Laufzeit von
>> einer Sekunde begrenzt. und zusätzlich soll betriebA > LED 0 leuchten.

Wann genau soll der Timer betriebP begrenzen? Nur nachdem er durch 
SENSOR aktiviert wurde, oder auch wenn der Zustand durch HAND aktiviert 
wurde? Beginnt die Zeitmessung immer wieder neu, wenn HAND oder SENSOR 
betätigt wird, oder nicht? Wann genau soll zusätzlich betriebA leuchten? 
Wenn der Timer abläuft, oder wenn der Timer anläuft oder wenn SENSOR 
betätigt wird? Wann soll betriebA dann wieder aus gehen?

Du siehst, dass die Aufgabenstellung schon unvollständig ist. Wenn Du 
die einfach so herunter programmierst, erhälst Du ein unvollständiges 
Programm, dass nicht funktionieren kann.

von Timm Reinisch (Gast)


Lesenswert?

Hallo,

(Gib dir doch mal etwas mehr Mühe im Ausdruck, mir schwirrt schon 
richtig der Kopf, betreib, detrieb und was noch alles. Chaotischer 
Ausdruck ist ein Zeichen für chaotische Gedanken!)

Zur Sache: Ist dir klar, dass die Taster in gedrücktem Zustand den Pin 
auf low, also 0, legen und in losgelassenem Zustand auf 1?


Vlg

Timm

von Karl H. (kbuchegg)


Lesenswert?

Eventuell wär es auch vernünftig, in Richtung
Statemachine
weiter zu überlegen, anstatt das mit untauglichen Port If-else nach dem 
Prinzip "Versuch und Irrtum" rumzumachen. Du beschreibst ja deine 
gewünschte Funktion sowieso schon in einer Art von Zustandänden. Da 
würde sich sowas ja nahezu aufdrängen.

Das Aufzeichnen einer Statemachine, von Zuständen und durch welche 
Ereignisse die Maschine in andere Zustände wechselt würde dir erst mal 
helfen, deine Gedanken zu ordnen.

Planung und Vorarbeit ist nun mal das halbe Leben.

von Stefan (Gast)


Lesenswert?

Noch eine Frage zum Klären der Aufgabenstellung:

- Genügt es, forlaufend den Zustand der Eingänge (High/Low) abzufragen? 
Oder ist es notwendig, auf Flanken zu reagieren (Wechsel von Low nach 
High, Wechsel von High nach Low). Möglicherweise brauchst Du sogar 
beides.

- Wann wird der Timer gestartet, wann wird er gestoppt? Kann er neu 
gestartet werden, während er läuft? Kann er gestoppt werden, während er 
läuft?

- Wie ist der Ausgangszustand, womit soll die Steuerung starten?

- Da manchmal mehr als EIN Ausgang gleichzeitig aktiv sein soll, gibt es 
offensichtlich mehr als drei Zustände. Dein Text liest sich jedoch so, 
als ob Du von genau drei Zuständen entsprechend 3 LED's ausgehst. 
Hinterfrage also, wie viele Zustände es wirklich gibt. Jede vorgesehene 
Kombination von Ausgängen ist ein Zustand, und der Timer hat auch 
mehrere Zustände (Läuft nicht, läuft, Zeitlimit erreicht).

Liste mal alle Zustände auf, die es gibt. Dann kannst DU daraus schonmla 
das Grundgerüst des Zustandsautomaten programmieren:
1
int zustand='X';  // AUsgangs-Zustand
2
while (1) {
3
  switch (zustand) {
4
    'X': ...
5
         break;
6
    'A': ...
7
         break;
8
    'H': ...
9
         break;
10
    'P': ...
11
         break;
12
  }
13
}

Das wäre mal ein Beispiel für 4 Zustände. Anstelle der drei Punkte 
gehören if-Abfragen für Ereignisse. Nach dem Motto:

Im Zustand X: Wenn Taster HAND gedrückt und SENSOR nicht gedrückt, und 
Timer nicht läuft, dann schalte Ausgang A an. Der nächste Zustand ist 
dann 'A'.

Weiterhin im Zustand X: Wenn ... (andere Bedingung), dann schalte 
Ausgang P an und Ausgang A aus. Der nächste Zustand ist dann 'H'.

Im Zustand A: Wenn ..., dann schalte Ausgang .... Der nächste Zustand 
ist dann '...';

und so weiter.

Formuliere das mal so in dieser Art, dann ist die Umsetzung in ein 
Programm ganz einfach.

Das saubere ausformulieren der Aufgabe ist in der Softwareentwickler die 
eichtigste Aufgabe und nimmt in der Regel deutlich mehr Zeit in 
Anspruch, als das Programmieren. An diesem Punkt entscheidet sich, ob Du 
ein Softwareentwickler oder ein Programmierer bist.

von Stefan (Gast)


Lesenswert?

Boah, ich merke dass ich noch halb schlafe. Man könnte denken, ich 
müsste noch deutsch lernen. Schäm

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:

> Formuliere das mal so in dieser Art, dann ist die Umsetzung in ein
> Programm ganz einfach.

Ich würd sogar noch weiter gehen und das richtig mit Bleistift auf 
Papier aufmalen, so wie das im Link gezeigt ist. Denn dann sind 
Änderungen ganz leicht zu machen.

@TO
Aber nicht so wie das im Eröffnungsposting gemacht ist. Das ist ein 
bunter Mischmasch aus Zuständen, Abfragen, Dingen die wie Anweisungen 
aussehen und Sachen die nach dem Muster "Was ich mir denke" eingefügt 
wurden.
Natürlich muss man die Zustandsübergänge nicht in einer 
Programmiersprache beschreiben. Aber ein wenig im Hinterkopf sollte man 
schon halten, was ein Programm kann und was es nicht kann und man muss 
bei jedem Kriterium für einen Zustandsübergang überlegen, ob da nicht 
ein versteckter Zustand da drinnen steckt. So wie im Link: Im Beispiel 
für den Rolladen gibt es einen Zustand "Rolladen fährt nach oben". Den 
Zustand gibt es da nicht ohne Grund. Genauso steckt in der Zeichnung 
ganz oben, im Kasten rechts unten ein Zustand drinnen "bis der Mensch 
auf Auto schaltet". In einer Statemaschine ist alles, was auch nur 
irgendwie nach warten stinkt, normalerweise ein eigener Zustand.

Auch nicht verzweifeln. Es ist auch nicht ungewöhnlich, dass das erste 
Machwerk auf Papier nicht sauber, nicht vollständig und nicht 
funktionsfähig ist. Dazu macht man es nämlich auch auf Papier. Mit einem 
Radiergummi ist das alles ganz schnell geändert und umgezeichnet, wenn 
man drauf kommt, dass da was nicht stimmt. In der Beziehung ist nämlich 
Papier unschlagbar. Da kannst du dir deine ganze Zeichnungen mit 
Malprogrammen oder sonstigen Hilfen vergleichsweise in die Haare 
schmieren. Erst dann, wenn sich alles stabilisiert hat, kann man das 
erste mal dann eine Version im Rechner zeichnen. Kann man, muss man aber 
nicht. Aber bei den ersten Skizzen kommt es nicht darauf an, dass sie 
schön sind, sondern dass man mit ihnen die Logik überprüfen kann und das 
man sie leicht und ohne viel Aufwand ändern kann. Und das geht nirgends 
so gut, wie mit Papier und Bleistift. Noch nicht mal annähernd so gut 
und so schnell. Ich habs schon erlebt, dass bei Meetings mehr Zeit damit 
vertrödelt wurde, die Fonts richtig zu stellen und die Farben, 
Linienstärken und Pfeilspitzen zu ändern anstatt sich mit dem Problem zu 
beschäftigen. Und am Ende kommt dann eine wunderschöne bunte Grafik 
raus, die man so wie sie ist ausdrucken und in den Papierkorb werfen 
kann :-) Da muss man sagen: Ziel ganz klar verfehlt und Prioritäten 
falsch gesetzt.

> Das saubere ausformulieren der Aufgabe ist in der Softwareentwickler die
> eichtigste Aufgabe und nimmt in der Regel deutlich mehr Zeit in
> Anspruch, als das Programmieren. An diesem Punkt entscheidet sich, ob Du
> ein Softwareentwickler oder ein Programmierer bist.

Ich hätt andere, drastischere Worte benutzt :-)

von Schwarz (Gast)


Lesenswert?

... ok.

Das sieht nach verdammt viel Zeit aus, die Ihr da investiert habt.
Danke dafür.

Ich verdau das mal, versuch den Kopf zu leeren und jede erdenkliche 
Situation auf's Papier zu bringen.

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
Noch kein Account? Hier anmelden.