if Anweisung schachteln C

Gast #3005251
Lesenswert?

Hallo an Alle,

was soll passieren.
 (HW STK 500 Atmega8)

Im Handbetrieb läuft die Pumpe ohne EInfluss irgendwelcher Sonsoren.
Wurde der HAndscahlter NICHT betätigt herscht Automatikbetrieb ( ist ja 
klar ).
Im Auto..modus wird der Füllstand über den Sensor Eingang Fuelstand 
abgefragt. Liegt hier ein HIGH (1) an soll die Pumpe für eine definierte 
Zeit laufen.

Die 2te if Anweisung ( hab schon gesehen if-Schleife)
   if (PIND & (FUELSTAND))
    {
         PORTB = (PUMPE);
     }
macht nun Folgendes:

Die Betätigung des Tasters auf PD5 (HAND) schaltet die Pumpe für die 
definierte Zeit ein.

Wenn die og Anweisung auskommentiert wird ist die Funktion des Programms 
mit meine Wünschen deckungsgleich.

Auf welchem Holzweg befinde ich mich da gerade?
Angehängte Dateien:
Gast #3005279
Lesenswert?

Offen gesagt würde ich mir wünschen das Du erstmal schreibst was 
überhaupt das Problem ist.

Dein Text hat einen Widerspruch den ich mir so ohne weiteres nicht 
erklären kann, denn:

>Wenn die og Anweisung auskommentiert wird ist die Funktion des Programms
>mit meine Wünschen deckungsgleich.

kann ja wohl nicht wahr sein, da der Füllstand keine Einfluss mehr auf 
die Pumpenfunktion hat.

Meine Glaskugel rät mir Dir zu raten mal folgende Tabelle auszufüllen 
und dann das Ganze nochmal zu überdenken.

Taster                  | Füllstand    | Pumpe
------------------------+--------------+-------
betätigt/nicht betätigt | hoch/niedrig | an/aus

Viel Erfolg.
Gast #3005294
Lesenswert?

Ja, leider ist Dein Text nicht verstaendlich.

Zudem die Frage : was soll eine 'if-Schleife' sein.

Vielleicht hilft aber das : Dein Code enthaelt eine etwas unsinnige 
Struktur; vielleicht meintest Du etwas anderes, naemlich aus:

PORTB = (Pumpe);  --> PORTB = (Pumpe) |(betriebA);

ansonsten wuerdest Du ja Betrieb A sofort wieder ausschalten. Aber wie 
gesagt, was Dein Problem ist weiss ich nicht.
Gast #3005297
Lesenswert?

Hallo,
hatte vorhin dein Programm nicht angeschaut
dann machs so:
1
  while(1)
2
  {
3
    if (!(PIND &  (HAND))) // Wenn NICHT Hand betätigt dann 
4
    {
5
      if (PIND & (FUELSTAND)) // PD4 ist der Füllstandsensor
6
      {
7
        PORTB = (betriebA) | (Pumpe); // Automatikbetrieb ist aktiv
8
        _delay_ms(1000);
9
      }
10
      else
11
      {
12
        PORTB = (betriebA) ; // Automatikbetrieb ist aktiv
13
      }    
14

15
    }
16
    else
17
    {
18
      PORTB = (betriebH) | (Pumpe);    // HAndbetrieb aktiv
19
    }
20
  }
Gast #3005418
Lesenswert?

Karlheinz schrieb:
> if (!(PIND &  (HAND))) // Wenn NICHT Hand betätigt dann
>     {
>       if (PIND & (FUELSTAND)) /

usw.

Also ich bin ehrlich gesagt zu blöd um mir dieses ganze Logikwirrwarr zu 
merken so was mach ich über Statis.

Beispiel in Pseudocode:


// Statis
Handbetrieb = PIND
AutoBetrieb  = !PIND
Voll = Füllstand


// Aktoren
AktivierePumpe = PORTB

wiederhole

  Wenn Handbetrieb und ... dann XYZ
  Wenn AutoBetrieb und Voll dann AktivierePumpe

bis (X == U)

Lässt sich in C prima abbilden
#3005428
Lesenswert?

Man muss man über die einzelnen Pins abstrahieren. z.B. indem man ihnen 
erstmal per #define Namen gibt. Dann abtrahiert man über die Funktion 
der Pins in dem man (z.B. per #define oder echter Funktion) Aktionen und 
Abfragen kapselt. Erst dann kann man sauber programmieren und alles ab 
da, ist erstmal HW-unabhängig und sollte (sofern alles sinnvoll benannt 
ist) sich lesen lassen wie prosa.

was sind "statis"?

gruß cyblord
Gast #3005609
Lesenswert?

Das die Funktion des Programms nicht genügend erläutert wurde bitte ich 
zu entschuldigen.

Ein ständige/zyklische  Überprüfung des Füllstandes, die durch den 
Handbetrieb "überbrückt wird"
Zwei Eingange "HAND" (PD5) und "FUELSTAND" (PD4). Drei Ausgänge
sind ebenfals im Komentar des COdes ersichtlich.

Das Programm; kometierte Version == Eröffungsthread

Kein Taster gedrückt  --> Automatil aktiv ( richtig )
1
if (!(PIND &  (HAND))) //PD5 
2
  {
3
       PORTB = (betriebA);          
4
    /*  
5
    if (PIND & (FUELSTAND)) // PD4 
6
    {
7
          PORTB = (Pumpe);
8
      _delay_ms(1000);
9
    }    
10
                */   
11
}
12
else
13
  {
14
          PORTB = (betriebH) | (Pumpe);  
15
        }
und ohne die innere if-Anweisung
wird bei Betätigung des HAndschalters (PD5) der Ausgang "betriebH" und 
"Pumpe" gesetzt  (STK 500)
(richtig)

Wird nun die innere if-Anweisung hinzugenommen
1
if (!(PIND &  (HAND))) //PD5 
2
  {
3
       PORTB = (betriebA);          
4
      
5
    if (PIND & (FUELSTAND)) // PD4 
6
    {
7
          PORTB = (Pumpe);
8
      _delay_ms(1000);
9
    }    
10
                 
11
}
12
else
13
  {
14
          PORTB = (betriebH) | (Pumpe);  
15
        }

und der Handschalter (PD5) betätigt läuft die Pumpe für eine definierte 
Zeit
"betreibH"  und "betreibA" aus; "Pumpe" an. (falsch)

Also hab ich ein Denkknoten inder verschachtelung der if's


Soll;

Nur im Automatikbetreib darf die Laufzeit der Pumpe mittels 
Füllstandsensor (PD4) aktiviert werden.

Der Vorschlag von
Karlheinz schrieb:
 ging ja schon mal in die Richtung "Kleinere Einheiten pro if bzw else"
vielen Dank für die neue Richtung

Karlheinz schrieb:
1
 while(1)
2
   {
3
     if (!(PIND &  (HAND))) // Wenn NICHT Hand betätigt dann 
4
     {
5
       if (PIND & (FUELSTAND)) // PD4 ist der Füllstandsensor
6
       {
7
         PORTB = (betriebA) | (Pumpe); // Automatikbetrieb ist aktiv
8
         _delay_ms(1000);
9
       }
10
       else
11
       {
12
         PORTB = (betriebA) ; // Automatikbetrieb ist aktiv
13
       }    
14
 
15
     }
16
     else
17
     {
18
       PORTB = (betriebH) | (Pumpe);    // HAndbetrieb aktiv
19
     }
20
   }

Leider keine Änderung der erkennbar, ich bin jedoch sicher hier liegt 
die Lösung
Gast #3005646
Lesenswert?

>Leider keine Änderung der erkennbar,

Das kann schon mal nicht sein, da das Programm ein anderes ist.

Ich möchte noch einmal auf meinen Beitrag 
Beitrag "Re: if Anweisung schachteln C"
verweisen und nimm die Anzeigen mit in die Tabelle auf.

Mir scheint das Problem zu sein, das Du die geplante Funktion des 
Programmes nicht völlig überblickst und hier deswegen Details auslässt.

Z.B kann das hier
>läuft die Pumpe für eine definierte Zeit
entweder so nicht stimmen, denn Du schreibst ja nur etwas von Füllstand 
oder es gibt eine externe Zeitsteuerung von der Du uns noch nichts 
geschrieben hast.

Du solltest zunächst einige Grundlagenpunkte klären.

1. Gehen die LEDs an oder aus, wenn DU an dem entsprechenden Portpin 
eine 1 ausgibst? Das geht aus dem Schaltplan hervor (der hier fehlt).
Geht die Pumpe an oder aus, wenn Du an dem entsprechenden Portpin eine 1 
ausgibst?
Bei den LEDs wäre eine 1 für das Leuchten eher unüblich aber unmöglich 
ist es nicht.

2. Bitmanipulation
1
PORTB = (betriebH) | (Pumpe)
schaltet sowohl die LED als auch die Pumpe ein (falls dies bei 1 
geschieht)
Hingegen schaltet das hier
1
PORTB = (Pumpe)
nur die Pumpe ein und die LEDs aus, was darauf hindeutet das die LEDs 
bei 1 leuchten.

Siehe auch: http://www.mikrocontroller.net/articles/Bitmanipulation

3. Deine Beschreibung hört sich für mich so an:

A) Beim Start sind die LEDs aus und die Pumpe läuft nicht. Der Füllstand 
sei hoch genug das die Pumpe auch nicht laufen sollte.
B) Sinkt der Füllstand unter einen gewissen Wert, dann läuft die Pumpe 
an und die LED "Automatik" leuchtet.
C) Hat sich der Füllstand dann erhöht, dann geht die Pumpe und die LED 
"Automatik" aus.
D) Ausgehend von A): Wird die Taste gedrückt so läuft die Pumpe an und 
die LED "Manuell" geht an.
E) Wird die Taste wieder losgelassen, dann geht die Pumpe und die LED 
aus.

Das ist genau das, was das dritte Program hier: 
Beitrag "Re: if Anweisung schachteln C" tut.

Allerdings ist dieser Ablauf eher unüblich.
1) Normalerweise würde der "Manuell"-Zustand anhalten bis z.B. die Taste 
erneut betätigt wird. Die Pumpe würde dann nicht aufgrund des 
Füllstandes gesteuert werden.
Das würde erfordern, das der Zustand gespeichert wird.

Ich möchte nur sagen, das Deine Erklärung in der Form meiner hier 
gegebenen entsprechen sollte, damit Du und wir uns darüber klar werden 
können, was das Problem ist. Andernfalls könntest DU auch die von mir 
vorgeschlagene Tabelle oder auch ein Zustandsdiagramm oder einen 
Ablaufplan erstellen.

Viel Erfolg.
Gast #3005651
Lesenswert?

Oh, ich sehe gerade:

> Nur im Automatikbetreib darf die Laufzeit der Pumpe mittels
>Füllstandsensor (PD4) aktiviert werden.

Dann musst Du tatsächlich eine Zustandsvariable einführen und Dein 
Problem ist nicht allein die Verschachtelung von ifs.
Gast #3005686
Lesenswert?

Das Flussdiagramm hab ich im Vorfeld erstellt und beinhaltet etwas mehr 
als mit dem geposteten Code erreicht werden kann.

Ich bleib jetzt mal Stur möglicherweise auch bloß blöd.
Ob ich eine 1 oder 0 hab am Ein- oder Ausgang ist erst mal sekundär
weil das HW abhängig ist

Und weil die Simulation auf dem STK 500 läuft ist Pull-up bzw down für 
alle Pin gleich  ---außer--- ich habe Code eingegebnen der an den 
Kriterien HIGH oder LOW was ändert, da behaupte ich nein alle relevanten 
I/O sind gleich

HAND betätigt            |   Pumpe an                 //richtig
HAND betätigt            |   Leuchtmelder Handbetrieb //richtig
Keine Aktion von Außen   |   Leuchtmelder Atomatik    //richtig
1
if (!(PIND &  (HAND))) //PD5 
2
  {
3
       PORTB = (betriebA);          
4
    /*  
5
    if (PIND & (FUELSTAND)) // PD4 
6
    {
7
          PORTB = (Pumpe);
8
      _delay_ms(1000);
9
    }    
10
                */   
11
}
12
else
13
  {
14
          PORTB = (betriebH) | (Pumpe);  
15
    }

und deswegen ist es mich auch momentan egal ob Pin high oder low ist.


jetzt wir dem Programm die innere if Anweisung beigefügt
siehe Oben /* auskommetiert */

HAND betätigt         |        Pumpe läuft               //falsch
                  es soll die Leuchteinrichtung betriebH leuchten
FUELSTAND betätigt    |        keine Änderung            // falsch
Angehängte Dateien:
Gast #3005689
Lesenswert?

Ich mach mal eine Zustandstabelle entsprechend der Beschreibung die ich 
oben gegeben habe.

Taste | Füllstand | Pumpe | LED auto | LED manu |
------+-----------+-------+----------+----------+
n.g.  | egal was  | aus   | ein      | aus      |
gedr. | egal was  | an    | aus      | ein      |
n.g.  | n. pumpen | aus   | ein      | aus      |
n.g.  | pumpen    | ein   | ein      | aus      |

Soll jetzt aber noch gelten:

> Nur im Automatikbetreib darf die Laufzeit der Pumpe mittels
>Füllstandsensor (PD4) aktiviert werden.

dann brauchst Du eine andere Tabelle, unter Umständen mit einer 
Zustandsvariablen.

Du kannst auch ein Diagramm zeichnen, wie hier: 
http://de.wikipedia.org/wiki/Endlicher_Automat

Dein Problem liegt nicht in der Verwendung von if-thens, sondern das Du 
die Funktion noch nicht klar vor Augen hast, denke ich.

Viel Erfolg.
Gast #3005692
Lesenswert?

>Das Flussdiagramm hab ich im Vorfeld erstellt und beinhaltet etwas mehr
>als mit dem geposteten Code erreicht werden kann.

Aaah. Das hättest Du gleich am Anfang posten sollen.

>Ich bleib jetzt mal Stur möglicherweise auch bloß blöd.
>Ob ich eine 1 oder 0 hab am Ein- oder Ausgang ist erst mal sekundär
>weil das HW abhängig ist

Es ist natürlich Deine Wahl ob Du Dich stur und blöd stellst oder nicht. 
Und unsere ob wir einem helfen der sich stur und blöd stellt oder nicht.

Für den Entwurf einer solchen Mimik ist die Polarität gleichgültig aber 
für die Implementierung nicht.
Da wir nur eine unklare Beschreibung hatten und einen Code der nicht wie 
gewünscht funktioniert, war diese Information wichtig.

Also l... m... a... A...!
Gast #3005709
Lesenswert?

Hmm schrieb:
> Es ist natürlich Deine Wahl ob Du Dich stur und blöd stellst oder nicht.
> Und unsere ob wir einem helfen der sich stur und blöd stellt oder nicht.

Sorry, ich vermute mal die falsche Ausdruckweise gewählt zuhaben.

Da es für den Mometn egal ist ob eine LED leuchtet oder ausgeht (sie tut 
ja was).
Und Aktivitäten der Taster erkannnt werden. Die Hardware, wenn nötig auf 
high- oder lowaktiv umgestellt werden kann.

Und ie innere if Anweisung so gar nicht auf PD4 reagiert sonder lieber 
auf PD5 was sie nicht soll, bin ich im Kopf voll auf Fehler in der 
if-Struktur.

@Hmm, vielen Dank für deine Bemühungen, und im Fall mich nicht nach 
deinen Konventionen verhalten zu haben, so bitte ich um Verzeihung
Gast #3005721
Lesenswert?

>Da es für den Mometn egal ist

Ich habe Dir erklärt warum das nicht egal ist bzw. war. Was soll das 
Drum-Herum-Gerede? Ein Ignoranzpunkt.

>bin ich im Kopf voll auf Fehler in der  if-Struktur.
Eben daraus habe ich Dir zu helfen versucht. Zweiter Ignoranzpunkt.

>im Fall mich nicht nach deinen Konventionen verhalten zu haben
Das sind Verfahren die sich in solchen Fällen bewährt haben, also im 
weiteren Sinne "Konventionen". Was soll diese völlig unangebrachte 
Ironie. Dritter Ignoranzpunkt.

Mit dem ganzen Herumgerede verminderst Du nur Deine Chance auf Hilfe. 
Ein Bonus-Ignoranzpunkt.

Sieh' alleine zu wie Du fertig wirst.
Gast #3005732
Lesenswert?

A) Schaltplan!

B) Jedes Teil erklären

C) Abhängigkeit erklären

D) Problem erklären

kann doch nicht so schwer sein.

Beispiel:


>>Im Handbetrieb

Defeniere Handbetrieb? Schalter, Signal, Eingang am Controller etc....

>>läuft die Pumpe

Defeniere Pumpe? Wo ist sie angeschlossen, wie ist sie angeschlossen, 
was ist das für eine Pumpe.

>>ohne EInfluss irgendwelcher Sonsoren.

Defeniere Sensoren, welche, wo hängen die dran, wann sind die wichtig.

>>Wurde der HAndscahlter

Was für ein Handschalter, welche Positionen, wo angeschlossen, wieviel 
Stellungen, welche Funktionen sollen erfüllt werden.

>>NICHT betätigt

Definiere nicht betätigt? Gedrückt, getastet, geschaltet? Wo 
angeschlossen?

 >>herscht Automatikbetrieb

Was ist Automatikbetrieb.

Und vor allem Weg, worum gehts überhaupt. Du hast im ersten Satz mehr 
Fragen aufgeworfen als dir jemanls Antworten gegeben werden könnten. Das 
endet immer in diesem Disaster, es wird eine vermeintliche Lösung 
gepostet, dann kommt von dir "ABER" und das ganze geht von vorn wieder 
los....uns so popeln dir alle was aus der Nase...kostet zeit und es ist 
sooo ätzend zu lesen...

JJ
Gast #3005740
Lesenswert?

ach ja, ein Posting mit "was soll passieren" zu beginnen ist eigentlich 
schon immer ein Grund für mich nicht weiter zu lesen...

Wenn dann noch nicht mal beschrieben wird was passieren soll und worum 
es geht suche ich immer die "Löschen" Taste die es hier leider nicht 
gibt...

JJ
#3005756
Lesenswert?

Eigentlich ist das Programm doch extrem simpel:

Man hat eine Taste, einen Füllstandssensor und einen Ausgang für die 
Pumpe. Standardmäßig soll das Programm die Pumpe in Abhängigkeit vom 
Füllstandssensor ein- und ausschalten (Automatikmodus). Mit der Taste 
kann man erzwingen, dass die Pumpe läuft, unabhängig vom Wert des 
Füllstandssensors (Handbetrieb).

Was der Threadersteller uns verschweigt ist, ob man die Taste gedrückt 
halten muss, damit die Pumpe läuft oder ob man sie nur einmal antippen 
muss und die Pumpe laufen soll, bis man die Taste nochmal antippt. Für 
letzteres braucht man eine Zustandsvariable und Entprellung, für den 
ersten Fall nicht. Also bleiben wir mal beim ersten Fall, so wie es 
jetzt implementiert ist.

Die Zustandstabelle sollte also folgendermaßen aussehen:

Taste | Füllstand | Pumpe | LED auto | LED manu |
------+-----------+-------+----------+----------+
gedr. | egal was  | an    | aus      | ein      |
n.g.  | n. pumpen | aus   | ein      | aus      |
n.g.  | pumpen    | ein   | ein      | aus      |

Stimmt das bis hier?

Wenn ich die Fehlerbeschreibung richtig verstehe, verursacht das Drücken 
vom Taster an PD5, dass PD4 (an dem der Füllstandssensor hängen soll) 
kurzzeitig als 1 erkannt wird. Das klingt für mich nach falscher 
Beschaltung bzw. einem floatenden Füllstands-Pin, der zufällig auf das 
Drücken des Schalter reagiert. Ohne den Versuchsaufbau zu kennen ist das 
aber Rätselraten. Vielleicht ist auch die Problembeschreibung oder die 
Erwartung an das Programm schon falsch.
Gast #3005815
Lesenswert?

Hmm schrieb:
> Sieh' alleine zu wie Du fertig wirst.

Bleib mal entspannt. Stell dir ne Klasse mit 25-30 solcher Typen vor und 
sei froh das du ihnen nicht jeden morgen gegenüber stehst ;-).

Der Frager hat die Systematik noch nicht ganz drauf. Merkt man an der 
wirren Herangehensweise. Aber der Weg ist das Ziel, zumal schon ein 
Flussdiagramm existiert.

Meine Empfehlung ist etwas mehr Vorbereitung

Kleines Blockschaltbild der Anlage
Klare Definitionen der Ein- und Ausgänge
Kurze Beschreibung was passieren soll (da mach mir ne 
Bedienungsanleitung wirkt in meinen Augen wunder)

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