Eine kleine Frage zu For-Schleifen

Stimmt es, dass man in einer For-Schleife bei den Bedingungen keine Variable benutzen kann?
Ich habe folgendes probiert (nur als Beispiel):

variable = andereVariable + 2;   // Variablen sind im Header deklariert
for (int i = 0; i < variable; i++) {
      // tut was
}

Der Programmteil funktioniert nicht. Könnte die Ursache sein, dass in der For-Schleife keine zweite Variable auftauchen darf? Also anstelle "variable" im obigen Beispiel eine konkrete Zahl nach dem Vergleichsoperator sein muss?

Danke schon mal für die Hilfe.

LG, bq.

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Thanks! Danke! :slight_smile:

Nein!

nein.

Mach ein Testprogramm und poste das Testprogramm.
Beschreibe was es tun soll.
Beschreibe was es statt dessen macht.
Dann bekommst du auch gute Hilfe.
Aber wir brauchen einen vollständigen Sketch.

Danke, dann kann ich das schon mal ausschließen. Man kann also noch eine Variable benutzen. Prima. Dann hab ich da was anderes falsch gemacht.

Der Programmteil soll die Akkuspannung am Pin A0 messen und als Blinksignal am Pin der Led ausgeben. Je voller der Akku, desto häufiger das Blinken. Die Häufigkeit definiert mir der Wert "voltCounter".

voltMess() modifiziert "voltCounter" in gewünschter Weise.
im showVolt() funktioniert die 2. (untere) For-Schleife, die das Ende der Anzeige mit 3 kurzen Flashblitzen angibt.
Aber die 1. For-Schleife mit "voltCounter" funktioniert gar nicht. Es findet kein Blinken statt. Das Programm geht offenbar nicht in die Schleife rein.

Hier der fragliche Programmabschnitt:

void setup() {
  pinMode(Mot, OUTPUT);
  pinMode(Led, OUTPUT);  // für Ausgabe Blinken Voltage-Stärke
  pinMode(Touch1, INPUT);
  pinMode(Touch2, INPUT);
  pinMode(A0, INPUT);  // für Voltage Messung
}

void voltMess() {
  uint32_t Vbatt = 0;
  for (int i = 0; i < 16; i++) {
    Vbatt = Vbatt + analogReadMilliVolts(A0);  // ADC with correction
  }
  float Vbattf = 2 * Vbatt / 16 / 1000.0;  // attenuation ratio 1/2, mV --> V
  float volBatt = Vbattf + volKorr;

  // voltage counter change
  if (volBatt >= 4.1) {
    voltCounter = 5;
  }  // => voll aufgeladen
  if (volBatt >= 3.8 && volBatt < 4.1) {
    voltCounter = 4;
  }  // => fast voll
  if (volBatt >= 3.5 && volBatt < 3.8) {
    voltCounter = 3;
  }  // => mittelvoll
  if (volBatt >= 3.2 && volBatt < 3.5) {
    voltCounter = 2;
  }  // => hält noch ein wenig (wie lange?)
  if (volBatt < 3.2) {
    voltCounter = 1;
  }  // => dringend aufladen!
}


void showVolt() {
  /* Ergebniscode: Blink 5x = Batt voll, 4x = fast voll, 3x = halbleer, 2x = bald leer, 
      Blink 1x = DRINGEND AUFLADEN !!! */

      for (int i = 0; i < voltCounter; i++) {
        Serial.print("ForLoopCounter (in showVolt): "); Serial.println(count);
        count = count + 1;
        digitalWrite(Led, HIGH);
        delay(500);
        digitalWrite(Led, LOW);
        delay(500);
      } 
  delay(2000);

  // Code für Ergebnisanzeigen-Ende: 3x kurzBlitz
  for (int y = 0; y < 3; y++) {
    digitalWrite(Led, HIGH);
    delay(50);
    digitalWrite(Led, LOW);
    delay(350);
  }
  delay(3000);
}

void loop() {
// ...
// wenn was bestimmtes passiert dann mach folgendes:
    voltMess();
   showVolt();
// ...

}

Was ist da falsch?

...der leider nicht ausreicht.
Wo ist voltCounter wie definiert?

Wir brauchen einen compilierfähigen Sketch.

Da passiert nix.
Damit wird auch deine for-Schleife nicht ausgeführt.

sorry. Also hier vorsichtshalber mit komplettem Header:

const int Mot = D6;  // VibrMotor
const int stark = 255;
const int mittel = 200;
const int leicht = 150;  // Vibrationsstärke
const int tacet = 0;     // Vibrationsstärke 0 = no Vibration
bool statMot = true;

int statBeat;

const int Led = D10;
bool statLed;

const int Touch1 = D7, Touch2 = D8;
bool statTouch1, statTouch2;
bool tchWait1, tchWait2;
long tchWaitNow1, tchWaitNow2;
long tchWaitStore1, tchWaitStore2;
int touchDelay = 2000;  // in ms zur Entprellung und Two-Touchkombi

int dauer = 1000;  // in ms
long past, present;

float volKorr = 0.18;  // Wert durch Testung ermittelt (bq)
int voltCounter;       // hier als Anzahl Pulse für Batterie-Voltage

int Modus;  // 0 = Reciever (default), 1 = Metronom, 2 = Charge, 3 wäre noch mögl. (noch nicht definiert)



void setup() {
  pinMode(Mot, OUTPUT);
  pinMode(Led, OUTPUT);  // für Ausgabe Blinken Voltage-Stärke
  pinMode(Touch1, INPUT);
  pinMode(Touch2, INPUT);
  pinMode(A0, INPUT);  // für Voltage Messung
}

void voltMess() {
  uint32_t Vbatt = 0;
  for (int i = 0; i < 16; i++) {
    Vbatt = Vbatt + analogReadMilliVolts(A0);  // ADC with correction
  }
  float Vbattf = 2 * Vbatt / 16 / 1000.0;  // attenuation ratio 1/2, mV --> V
  float volBatt = Vbattf + volKorr;

  // voltage counter change
  if (volBatt >= 4.1) {
    voltCounter = 5;
  }  // => voll aufgeladen
  if (volBatt >= 3.8 && volBatt < 4.1) {
    voltCounter = 4;
  }  // => fast voll
  if (volBatt >= 3.5 && volBatt < 3.8) {
    voltCounter = 3;
  }  // => mittelvoll
  if (volBatt >= 3.2 && volBatt < 3.5) {
    voltCounter = 2;
  }  // => hält noch ein wenig (wie lange?)
  if (volBatt < 3.2) {
    voltCounter = 1;
  }  // => dringend aufladen!
}


void showVolt() {
  /* Ergebniscode: Blink 5x = Batt voll, 4x = fast voll, 3x = halbleer, 2x = bald leer, 
      Blink 1x = DRINGEND AUFLADEN !!! */

      for (int i = 0; i < voltCounter; i++) {
        digitalWrite(Led, HIGH);
        delay(500);
        digitalWrite(Led, LOW);
        delay(500);
      } 
  delay(2000);

  // Code für Ergebnisanzeigen-Ende: 3x kurzBlitz
  for (int y = 0; y < 3; y++) {
    digitalWrite(Led, HIGH);
    delay(50);
    digitalWrite(Led, LOW);
    delay(350);
  }
  delay(3000);
}

void loop() {
// ...
// wenn was bestimmtes passiert dann mach folgendes:
  voltMess();
  showVolt();
// ...

}

voltCounter ist im Header als int deklariert.

my_xy_projektKarma: 1200+

8mpost #8

Da passiert nix.
Damit wird auch deine for-Schleife nicht ausgeführt.

wenn beide Touchbutton gleichzeitig berührt werden, wird voidMess() und showVolt aufgerufen. Das funktioniert. Und showVolt() gibt mir ja die drei kurzen Flash-Blitze der 2. For-Schleife aus. Aber eben nicht die langsameren der ersten Schleife. Daher dachte ich, es liegt an der Variable in der Schleifenbedingung.

Hallo,

auf welchen Controller läuft das denn? Weil D6 usw. kennt meine IDE nicht.
Und dann fehlt noch die Deklaration von analogReadMilliVolts().
Der nächste Versuch sollte vollständig sein!

Und was geht jetzt nicht?
Mir fällt als erstes auf, das bei volBatt 4.0 oder 3.5 nix passiert und Dein Counter da nicht gesetzt wird.
Unsinn. Das If-Konstrukt nicht richtig gelesen.

es läuft auf dem Seeeduino ESP32 C3

Der kennt aber

auch nicht von allein - oder?

OK ich mach mich an die Rekonstruktion des kompletten Codes. Das dauert etwas, da ich ja weiterprobiert hatte. Ich hatte es zwischenzeitlich im showVolt() mit switch case zum Laufen gebracht. Und wollte nur noch mal mein Problem mit der For-Schleife verstehen. Aber da ich da scheinbar doch eine richtige Idee hatte (nämlich dei Bedingung als Variable anzupassen). Liegt das Problem woanders. Der hier gepostete Code des "Voids" showVolt() ist eine Nachbildung der nicht funktionierenden Code-Variante. Ich kann auch den kompletten fehlerhaften Code noch mal reproduzieren. Aber das dauert einen Moment....

Das ist direkt von der Website von SeeedStudios. Das ist ein Befehl der angeblichdie eine konkrete Abweichung des konkreten Chips mit abfragt und einbezieht. Meine IDE hat kein Problem mit diesem Befehl.
Denkst du, da ist was faul?

Nein. Ich hab mich nur gewundert, weils das so nicht gibt.
Dann gehört die Funktion zum Board und wird mit den Definitionen mitgeliefert. - Alles ok.

Hallo,

irgendwas wird zwischen ADC einlesen und umrechnen schief gehen.

Edit:
Bau bei dir zum debuggen serielle Ausgaben ein aller Zwischenwerte vom ADC einlesen bis zum umrechnen in Volt. Dann siehst du denke ich wo das Problem liegt.

Mein Testcode.

uint8_t voltCounter;       // hier als Anzahl Pulse für Batterie-Voltage

void setup() {
  Serial.begin(250000);
  pinMode(A0, INPUT);  // für Voltage Messung
}

void voltMess()
{
  uint32_t akku = 0;
  for (uint8_t i = 0; i < 16; i++) {
    akku = akku + analogRead(A0);  
  }
  Serial.print(akku); Serial.println(" Akku Digit"); 
  //              Durchschnitt    AREF   10Bit  mV>V
  float volBatt = (akku / 16.0) * 5000 / 1024 / 1000;  
  Serial.print(volBatt ); Serial.println(" V"); 
  
  // voltage counter change
  if (volBatt >= 4.1) {
    voltCounter = 5;
  }  // => voll aufgeladen
  if (volBatt >= 3.8 && volBatt < 4.1) {
    voltCounter = 4;
  }  // => fast voll
  if (volBatt >= 3.5 && volBatt < 3.8) {
    voltCounter = 3;
  }  // => mittelvoll
  if (volBatt >= 3.2 && volBatt < 3.5) {
    voltCounter = 2;
  }  // => hält noch ein wenig (wie lange?)
  if (volBatt < 3.2) {
    voltCounter = 1;
  }  // => dringend aufladen!
}


void showVolt()
{
  for (uint8_t i = 0; i < voltCounter; i++) {
    Serial.println(i); 
  } 
}

void loop() {
  voltMess();
  showVolt();
  delay(1000);
}

Was soll ich sagen... jetzt geht sowohl die Variante mit switch/case als auch mit der rekonstruierten For-Schleife mit fraglicher Variable als Vergleichsbedingung. Ich muss beim Rekonstruieren einen von mir übersehenen Fehler "ausversehen" korrigiert haben. Dadurch ist ds Problem im Wohlgefallen verschwunden. Was mich aber auch ein wenig blöd dastehen lässt.

Dennoch, war das nicht umsonst. Denn ich habe was gelernt. Danke an alle. Insbesondere Dank an @combie für die knappe aber treffende Antwort bezüglich For-Loop. Das war ja genau gefragt.

Ich hatte die For-Schleife in showVolt() ja sowieso im Verdacht, da es ja ging als ich sie durch eine switch/case - Konstruktion ersetzt hatte.
Die For Schleife war das Problem und das ist gelöst, auch wenn ich nicht weiss, was da ursprünglich falsch geschrieben war.

Dank an @Doc_Arduino: Ja genau so mach ich das, ich taste mich mit Seriellen Monitor- Ausgaben an die Stellen heran, bis ich die finde, wo der Code nicht mehr das macht, was er soll. Das Problem mit dem Seeduino ist aber, dass er als Wifi-Wearable am Handelenk keine USB - Verbindung zum PC haben soll. Man muss bei diesem Microcontroller aber den Serial.begin() entfernen, da sonst das Programm im Setup hängenbleibt, wenn Serial nicht verfügbar ist. Daher dachte ich, ich entferne auch die zugehörigen Serial.print-Befehle, da die ja unnütz dennoch aufgerufen werden und somit Kapazität fressen, oder ist das ein Irrtum?

Es wurde vom Hersteller empfohlen, nicht die analogRead() - Funktion zu verwenden:

The datasheet says nominally 2500mV full scale AD conversion, but there is a large variation from chip to chip, actually ±10%. My chip was 2700mV full scale.

Fortunately, the calibrated correction value for each chip is written in the fuse area, and by using the function alalogReadMilliVolts(), I can read the corrected voltage value without doing anything special.

Ob die Funktion "analogReadMilliVolts()" (Achtung: witziger Schreibfehler im Zitat) tatsächlich korrekte Werte liefert, muss ich erst noch ausprobieren, ich hab das wie gesagt von der Hersteller-Website übernommen. Ich sehe keinen Anlass da mißtrauisch zu sein.
Aber auch für die Messung kann der MC nicht über USB verbunden sein, vermute ich, da er ja dann den Strom über USB bezieht und den Akku auflädt. Die Werte sind jedenfalls andere, wenn der Akku nicht voll ist und mein kleines Gerät nicht am USB hängt.

Falls jemand jetzt dennoch den kompletten Code anschauen möchte, sagt Bescheid, dann poste ich ihn gern. Aber Vorsicht - ist in weiten Teilen noch Baustelle.

Einen wunderbaren Abend an alle.

Hallo,

wegen Serial stimmt. Man kann sich einen Schalter erstellen und damit beeinflussen was kompiliert wird und was nicht.

constexpr bool DEBUG {true};

void setup(void)
{
  if (DEBUG) { Serial.begin(250000); }
  if (DEBUG) { Serial.println(F("\nuC Reset ####")); }
}

void loop(void)
{
  
}
1 Like