Variablenwert aus doppelter If Verschachtelung

Ähm, irgendwie scheint es mir, als wenn eine Variable welche innerhalb einer doppelten If Bedingung / Verschachtelung gefüllt wird, diese If Bedingung nicht verlassen kann.

Ich weiß… versteht man wieder nicht was ich will :wink:

Also hier die Codes… ich verstehe nicht, warum die 2te Variante nicht funktioniert.

Würde mich über einen Tipp freuen.

int sampleanzahl;
int d;
int sammel[500];
long durchschnitt; 

void setup() {

  delay(5000);

  analogReference(INTERNAL) ;
  Serial.begin(115200);  

}

void loop() {  
  durchschnitt=0;
  for (d=0;d<500;d++) {
    sammel[d]=analogRead(0);
  }

  sampleanzahl=0;
  for (d=0;d<500;d++) {
    if (sammel[d-1]==0) {
      if (sammel[d]>1) {
        durchschnitt=durchschnitt+sammel[d];
        sampleanzahl++;
      }
    }
    Serial.println(durchschnitt/sampleanzahl);
  }
 

}

Funktioniert soweit, allerdings wird der Wert “durchschnitt/sampleanzahl” natürlich x mal(irgendwas im bereich 500) angezeigt.

Jetzt kommt warum ich es nicht verstehe!!! :wink:

int sampleanzahl;
int d;
int sammel[500];
long durchschnitt; 

void setup() {

  delay(5000);

  analogReference(INTERNAL) ;
  Serial.begin(115200);  

}

void loop() {  
  durchschnitt=0;
  for (d=0;d<500;d++) {
    sammel[d]=analogRead(0);
  }

  sampleanzahl=0;
  for (d=0;d<500;d++) {
    if (sammel[d-1]==0) {
      if (sammel[d]>1) {
        durchschnitt=durchschnitt+sammel[d];
        sampleanzahl++;
      }
    }
//    Serial.println(durchschnitt/sampleanzahl);
  }

    Serial.println(durchschnitt/sampleanzahl);
 
}

Die Serial.print Zeile ist einfach eine Klammer runtergerutscht…
Die “sampleanzahl” muß hier noch einen Wert haben, und “durchschnitt/sampleanzahl” als komulierter Wert auch… so dachte ich…

Allerdings bekomme ich auschließlich 0 als Ausgabe, eine Klammer weiter oben klappt es wie gesagt… .

Und ganz ehrlich, das Problem verstehe ich gerade nicht.

Würde mich über einen Tipp freuen…

Achso, was will er denn machen… :wink:
Ich habe beim zügigen sampeln meiner Werte festgestellt,
daß diese flattern. In der Reihenfolge immer eine niedrige Spannung, 0 Linie, und dann der Wert den ich eigentlich brauche.
Zeitlich allerdings leicht variabel… (ebenfalls flatternd)…

Naja, also addiere ich die Werte welche unmittelbar nach der 0 kommen (sind ja die “gültigen” Messwerte) auf, und dividiere sie durch die Anzahl der “gültigen” Werte um den Durchschnitt zu bekommen.

Da das Null-Signal quasi der Trigger ist, kann ich auf die “ünnutzen” niedrigen Werte verzichten, und habe einfach den getriggerten Durchschnitt. So solls sein, wie gesagt… eine Klammer tiefer bekomme ich allerdings nur 0 als ausgabe, was so nicht stimmt.

Die Variablen sind meines Wissens doch eigentlich immer global…
Naja… hier scheint die Variable nur innerhalb der If Bedingung nutzbar zu sein…

Tipp willkommen…

Lieber Gruß
ChrisS

Und was bekommst Du im oberen Fall ausgegeben?

Den durchschnittlichen Messwert so wie es soll, nur halt zuoft (Sampleanzahl).
Er schreibt ja eine Klammer höher jedesmal wenn er einen Messwert hat den gemittelten Messwert über den Com.
500mal.

Das soll er eben nicht, sondern nachdem er 500mal gesampelt hat, den Druchschnittswert der gültigen Messwerte.

Deshalb muß die Printzeile eben eins nach unten...
oder ich sehe den Wald nicht... :slight_smile:

Lieber Gruß
ChrisS

Jaja, schon klar, aber WAS genau schreibt er denn 500 Mal?

Was genau ist bei den 500 Ausgaben die allerletzte Zeile?

Ähm...

ok, du willst es nicht anders :wink:

500 Zeilen 172... (wenn die Printzeile eine Klammer höher steht)

172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172
172

Im zweiten Beispiel ( Printzeile eine geschlossene Klammer tiefer...)
bekomme ich einmalig -1 pro 500 Messungen.

Wie gesagt, durchschnitt und sampleanzahl sind hier 0.
Obwohl innerhalb der inneren If-Schleife Werte vorhanden sind.

Lieber Gruß
ChrisS

Öhm... :o :smiley:

Hast Du mal probiert, durchschnitt und sampleanzahl einzeln auszugeben?

Wie gesagt, durchschnitt und sampleanzahl sind hier 0.

Schön, daß ich nicht allein bin... dachte schon ich hätte keinen Plan :wink:

Lieber Gruß
Chris

So, ich habs…

ABER: Ich hätte gern von jemandem mit fachlichem KnowHow mal eine kleine “Warum”-Erklärung.

So geht es:

int sampleanzahl;
int d;
int sammel[500];
long durchschnitt; 

void setup() {

  delay(5000);

  analogReference(INTERNAL) ;
  Serial.begin(115200);  
}

void loop() {  
  durchschnitt=0;
  for (d=0;d<500;d++) {
    sammel[d]=analogRead(0);
  }

  sampleanzahl=0;
  for (d=0;d<500;d++) {
    if (sammel[d-1]==0) {
      if (sammel[d]>1) {
        durchschnitt=durchschnitt+sammel[d];
        sampleanzahl++;
      }
    }
   delayMicroseconds(1);
   }
   Serial.println(durchschnitt/sampleanzahl);
  }

Man achte auf die delayMicroseconds an der stelle wo vorher das funktionierende Serial.print stand.

Ich möchte gern wissen warum dort ein delay notwendig ist, damit das ganze funktionert.

Es müsste ja faktisch ein Buffer überlaufen…
vom Array kann ich mir aber nicht vorstellen,
außerdem ist es wichtig zu wissen warum man wo ein delay setzten muß, weil das Proggi auf einmal nicht mehr funktioniert.

1 Microsekunde ist auch nicht besonders lang…

Ich bitte um eine kleine Erklärung vom Fach.

Lieber Gruß
ChrisS

Hmm, dann kann ich mir das nur mit irgendwelchen Nebenläufigkeiten erklären...

Ich kann das hier nicht ausprobieren, aber kennt die Arduino-Umgebung volatile? Wenn ja, dann probier bitte mal

volatile int sampleanzahl;
volatile long durchschnitt;

Gehts dann...?

Lies Dir hierzu bitte mal das hier durch...

Hast Du Dir außerhalb der for, also da, wos mit den anderen zwei Variablen nicht klappt, mal den Inhalt einer Variable aus dem sammel-Array ausgeben lassen? Klappt das?

Nein, mit volatile meldet er ebenfalls -1 .

Grml...

Wenn Du sowohl innerhalb als auch außerhalb den Wert ausgibst, kommt dann immer noch 500 mal "172" und ein Mal "-1"...??

Was passiert, wenn Du statt in der Schleife nach der Schleife den Delay setzt?
Und wenn Du jeweils vor und nach dem Delay den Wert ausgibst?

Ja, der Wert aus dem Sammelarray wird auch ohne Microseconds Bremse richtig angezeigt.

Der Delay muß in die Schleife, außerhalb bekomme ich das Standard "ich bin eine Null" Szenario... switchen der Reihenfolge bringt auch nichts...

Anscheinend muß dort wo der delayMicroseconds sitzt also wirklich eine Verzögerung hin....

Ja, habs nochmal verifiziert.... genauso und nicht anders....

MMh... dann liegt der Hase ja wirklich in der If-Verschachtelung...
mmh... das ist lustig....

Lieber Gruß
ChrisS

Also ich würd das mal für nen Bug halten... :wink:

Oder aber irgendwer hier kann es erklären? Ich wäre höchst begierig den Grund zu erfahren... :slight_smile:

Ohoh....

also ich habe vorhin das volatile nur uf die beiden von Dir genannten Variblen angewandt....

Jetzt als letzte Amtshandlung.... habe ich einfach mal frei Schnauze...
alle existierenden Variablen inkl. dem Array per volatile definiert.

Und jetzt gehts auch ohne delay....

Kannst Du mir noch kurz erklären ob ich volatile richtig verstehe.

volatile:

  • Ablauf der (Variablenzugriffe) Registerprozesse so wie ich es im Programm vorgesehen habe.
  • Erzwingen einer Art synchronität zwischen vorgesehenen Zugriffen und vorgesehenen Speicherinhalten (cache off).

Cool, danke für den Tipp!!!!!

Lieber Gruß
ChrisS

Soweit ich das verstanden hab verbietet volatile dem Compiler, an der Variable "rumzupfuschen" (im Sinne von Optimierungen am Code) und der Code muss jedes Mal direkt auf die Variable zugreifen und darf es nicht über Register cachen.

Das macht die ganze Sache vor allem in Schleifen etwas langsamer, ist aber die einzige saubere Möglichkeit, wenn man Probleme mit Nebenläufigkeit hat.

Jetzt würde mich nur noch interessieren, welche Variable jetzt das volatile wirklich gebraucht hat... :wink:

Na, dann haben wir das Problem eher umgangen... aber es ist auf alle fälle eine Lösung!!!

Dank Dir dafür....

Hatte wirklich nicht die geringste Ahnung warum die Variable hinter der Schleife aufeinmal leer ist....

Für mich fühlt sich das etwas buggy an, aber ich bin Anfänger und werde mich da mal schön zurückhalten :slight_smile:

Dank Dir, ich wünsche einen schönen sonnigen Resttag!!!!

Lieber Gruß
ChrisS

Was das Volatile angeht....

es war die Variable "d".

winki wink

Lieber Gruß
ChrisS

Öhm...

Ja, für mich fühlt sich das auch buggy an.