while Bedingung beenden

Ich bin blutiger Neuling und habe einen kleinen Aquarium Computer gebaut. Damkt die Dimmung reibungslos und ohne Sprünge abläuft habe ich eine kleine While Schleife vor dem Statement gesetzt. Wie bekomme ich es hin, dass die Bedingung durch einen anderen Parameter beendet wird. Ich würde gerne mit dem Drücken eines Buttons die While Bedingung beenden. Habe schon etwas mit for und den Konditionen expermentiert aber noch kein Erfolg gehabt.

Hier mein Codeschnipsel:

#define Apin 8
#define Bpin 4

#include <LEDFader.h>
#define FADE_TIME 20000
#define DIR_UP 1
#define DIR_DOWN -1
LEDFader led;
LEDFader led2;
int direction = DIR_UP;
bool Button = false;

while (led.update() && led2.update()); //Diese Bedingung durch Button == true beenden

Vlt. könnt ihr Profis einem Noob etwas unter den Armen greifen. Vielen lieben Dank.

Du brauchst keine eigene While-Schleife, Du hast doch loop.

Außerdem sind Befehle außerhalb von Funktionen sinnlos.

Du solltest die Grundlagen lernen, es gibt gute Beispiele in der IDE.

Gruß Tommy

Du meinst mit void auslagern? Ich brauche while, da im Hintergrund noch andere Prozesse (Uhr, Zeitsteuerung und Temp Sensoren) arbeiten.

hast die Klasse

LEDFader

selber gemacht oder irgendwo her kopiert?

Denn eigentlich solltest du einfach deinen zwei Objekten sagen können, "hört auf zu faden".

Obi_wan79: Du meinst mit void auslagern? Ich brauche while, da im Hintergrund noch andere Prozesse (Uhr, Zeitsteuerung und Temp Sensoren) arbeiten.

Nein, die brauchst du nicht. Das läuft alles sehr schön in der Loop wenn du mit einer Statusvariable arbeitest. Auch der Rest wird nicht dadurch beeinflusst.

Habe schon eine If Bedingung versucht: If (Button == false){while while (led.update() && led2.update()); Aber das führt ja nur zur while beendet diese jedoch nicht bei Button true. Dann habe ich versucht: Do {if If (Button == true){break;} while (led.update() && led2.update()); bringst aber auch nicht.

Fader ist aus einer Bibilothek.

Darf man den vollständigen Code posten?

Ja, ist explizit erwünscht.
Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).

Gruß Tommy

Ok hier mein Code. Bitte verzeiht ich bin Anfänger…

Teil 1:

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h> //LIB TFT
#define TFT_DC 6
#define TFT_CS 5
#define TFT_MOSI 11
#define TFT_CLK 13
#define TFT_MISO 12
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_MISO);
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

#include <Wire.h>
#include <DS3231.h>
DS3231 clock;
RTCDateTime dt;

byte DIM = 1;
#define Apin 8
#define Bpin 4
#define KSQ 3
#define KSQ2 9

#include <LEDFader.h>
#define FADE_TIME 20000
#define DIR_UP 1
#define DIR_DOWN -1
LEDFader led;
LEDFader led2;
int direction = DIR_UP;

bool Button = false;

#include <SimpleTimer.h>
SimpleTimer timer;
void RepeatTask() {

  digitalWrite(7, LOW);

}
void setup() {
  pinMode (KSQ, OUTPUT);
  pinMode (KSQ2, OUTPUT);
  led = LEDFader(KSQ);
  led2 = LEDFader(KSQ2);
  Serial.begin(9600);
  timer.setInterval(240000, RepeatTask);
  pinMode(7, OUTPUT);
  digitalWrite(7, HIGH);
  tft.begin();
  tft.setRotation(3);
  tft.fillScreen(ILI9341_BLACK);
  tft.setCursor(60, 80);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(4);
  tft.println ("Garnelen");
  tft.setCursor(60, 120);
  tft.println ("Aquarium");
  tft.setCursor(60, 220);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);
  tft.setCursor(250, 5);
  tft.println ("Version 1.2");
  clock.begin();
  sensors.begin();

  //clock.setDateTime(2018, 10, 6, 18, 06, 00); //Manuelle Zeitzetzung
  //clock.setAlarm1(0, 0, 0, 5, DS3231_MATCH_S);
  //clock.setAlarm2(0, 0, 45,     DS3231_MATCH_M);

  pinMode(Apin, INPUT_PULLUP);
  pinMode(Bpin, INPUT_PULLUP);


  delay (2000);

  tft.fillScreen(ILI9341_BLACK);
  tft.drawLine(0, 89, 320, 89, ILI9341_WHITE);
  tft.drawLine(0, 92, 320, 92, ILI9341_WHITE);
  tft.drawLine(160, 92, 160, 197, ILI9341_WHITE);
  tft.drawRect(0, 0, 320, 240, ILI9341_WHITE);
  tft.drawLine(0, 63, 320, 63, ILI9341_WHITE);
  tft.drawLine(0, 197, 320, 197, ILI9341_WHITE);
  tft.drawLine(0, 200, 320, 200, ILI9341_WHITE);
  tft.drawLine(160, 200, 160, 240, ILI9341_WHITE);
  tft.fillRect(1, 64, 318, 27, ILI9341_BLUE);
  tft.fillRect(1, 198, 318, 2, ILI9341_RED);
  tft.setTextColor(ILI9341_WHITE);
  tft.setCursor(100, 70);
  tft.setTextSize(2);
  tft.print("Temperatur:");
  tft.setCursor(40, 100);
  tft.print("Wasser");
  tft.setCursor(225, 100);
  tft.print("LED");
  tft.setCursor(10, 212);
  tft.print("Dimmung:");
  tft.setCursor(125, 212);
  tft.print("/8");
  tft.fillRect(170, 212, 12, 12, ILI9341_BLUE);
  tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
  tft.setCursor(112, 212);
  tft.print(DIM);
  tft.setTextSize(1);
  tft.setCursor(170, 230);
  tft.print("AUS");
  tft.setCursor(285, 230);
  tft.print("100%");
}

:o fehlt Da nicht loop() komplett?

Teil 2

void loop() {
  if (Button == false) {
    timer.run();

    dt = clock.getDateTime();
    sensors.requestTemperatures();
    float Wassertemp = 0;
    float LEDtemp = 0;

    LEDtemp = sensors.getTempCByIndex(0);
    Wassertemp = sensors.getTempCByIndex(1);

    while (led.update() && led2.update());


    tft.setCursor(100, 5);
    tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
    tft.setTextSize(2);
    tft.print(clock.dateFormat("d.m.Y", dt));
    tft.setCursor(70, 27);
    tft.setTextSize(4);
    tft.print(clock.dateFormat("H:i:s", dt));
    if (Wassertemp ++ || Wassertemp --) {

      tft.setCursor(20, 135);
      tft.setTextSize(5);
      if (Wassertemp <= 18 || Wassertemp >= 26) {
        tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
      }
      else if (Wassertemp <= 19 || Wassertemp >= 25) {
        tft.setTextColor(ILI9341_ORANGE, ILI9341_BLACK);
      }
      else if (Wassertemp >= 19 || Wassertemp <= 24) {
        tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
      }
      tft.print(Wassertemp, 1);
    }
    if (LEDtemp ++ || LEDtemp --) {
      tft.setCursor(185, 135);
      tft.setTextSize(5);
      if (LEDtemp >= 60) {
        tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
        DIM = 3;
      }
      else if (LEDtemp >= 55) {
        tft.setTextColor(ILI9341_ORANGE, ILI9341_BLACK);
      }
      else if (LEDtemp <= 55) {
        tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
      }

      tft.print(LEDtemp, 1);
    }


    String Zeit = clock.dateFormat("Hi", dt);
    if (Zeit == "0600")  {
      digitalWrite(7, HIGH);
      return;
    }
    if (Zeit == "1200")  {
      led.fade(10, 10000);
      led2.fade(5, FADE_TIME);
      direction = DIR_UP;
      return;
    }
    if (Zeit == "1220")  {
      led.fade(200, 10000);
      led2.fade(30, FADE_TIME);
      direction = DIR_UP;
      return;
    }
    if (Zeit == "1700")  {
      led.fade(255, 10000);
      led2.fade(40, FADE_TIME);
      direction = DIR_UP;
      return;
    }
    if (Zeit == "2000")  {
      led.fade(15, 10000);
      led2.fade(5, FADE_TIME);
      direction = DIR_DOWN;
      return;
    }
    if (Zeit == "2200") {
      led.fade(0, 900000);
      led2.fade(0, FADE_TIME);
      direction = DIR_DOWN;
      return;
    }
    if (Zeit == "0200") {
      digitalWrite(7, LOW);
      return;
    }
  }
  if (digitalRead(Apin) == HIGH || digitalRead(Bpin) == HIGH)
  {
    Button = false;
  }

  tft.setTextSize(2);
  if (digitalRead(Apin) == LOW)
  { Button = true;




    if (digitalRead(7) == LOW) {
      digitalWrite(7, HIGH);
      delay(1000);
    }
    else {
      tft.setCursor(112, 212);

      tft.print(DIM);
      delay(500);
      switch (DIM) {

        case 1:
          led.fade(0, FADE_TIME);
          led2.fade(0, FADE_TIME);
          direction = DIR_UP;
          tft.fillRect(170, 212, 12, 12, ILI9341_BLUE);
          tft.fillRect(188, 212, 12, 12, ILI9341_BLACK);
          tft.fillRect(206, 212, 12, 12, ILI9341_BLACK);
          tft.fillRect(224, 212, 12, 12, ILI9341_BLACK);
          tft.fillRect(242, 212, 12, 12, ILI9341_BLACK);
          tft.fillRect(260, 212, 12, 12, ILI9341_BLACK);
          tft.fillRect(278, 212, 12, 12, ILI9341_BLACK);
          tft.fillRect(296, 212, 12, 12, ILI9341_BLACK);
          DIM += 1;
          delay (50);
          break;
        case 2:
          led.fade(20, FADE_TIME);
          led2.fade(5, FADE_TIME);
          direction = DIR_UP;
          tft.fillRect(188, 212, 12, 12, ILI9341_BLUE);
          DIM += 1;
          delay (50);
          break;

        case 3:
          led.fade(40, FADE_TIME);
          led2.fade(8, FADE_TIME);
          direction = DIR_UP;
          tft.fillRect(206, 212, 12, 12, ILI9341_BLUE);
          DIM += 1;
          delay (50);
          break;

        case 4:
          led.fade(80, FADE_TIME);
          led2.fade(15, FADE_TIME);
          direction = DIR_UP;
          tft.fillRect(224, 212, 12, 12, ILI9341_ORANGE);
          DIM += 1;
          delay (50);
          break;

        case 5:
          led.fade(120, FADE_TIME);
          led2.fade(20, FADE_TIME);
          direction = DIR_UP;
          tft.fillRect(242, 212, 12, 12, ILI9341_ORANGE);
          DIM += 1;
          delay (50);
          break;

        case 6:
          led.fade(160, FADE_TIME);
          led2.fade(25, FADE_TIME);
          direction = DIR_UP;
          tft.fillRect(260, 212, 12, 12, 0xFFE0);
          DIM += 1;
          delay (50);
          break;

        case 7:
          led.fade(200, FADE_TIME);
          led2.fade(30, FADE_TIME);
          direction = DIR_UP;
          tft.fillRect(278, 212, 12, 12, 0xFFE0);
          DIM += 1;
          delay (50);
          break;

        case 8:
          led.fade(255, FADE_TIME);
          led2.fade(40, FADE_TIME);
          direction = DIR_UP;
          tft.fillRect(296, 212, 12, 12, 0xF800);

          DIM -= 7;
          delay (50);
          break;
      }
    }
  }
  if (digitalRead(Bpin) == LOW)
  { Button = true;

    if (digitalRead(7) == LOW) {
      digitalWrite(7, HIGH);
      delay(1000);
    }
    else {
      tft.setCursor(112, 212);
      tft.print(DIM);
      delay(700);
      switch (DIM) {
        case 1:
          led.fade(0, FADE_TIME);
          led2.fade(0, FADE_TIME);
          direction = DIR_DOWN;
          tft.fillRect(188, 212, 12, 12, ILI9341_BLACK);
          DIM += 7;
          delay (50);
          break;

        case 2:
          led.fade(20, FADE_TIME);
          led2.fade(5, FADE_TIME);
          direction = DIR_DOWN;
          tft.fillRect(206, 212, 12, 12, ILI9341_BLACK);
          DIM -= 1;
          delay (50);
          break;

        case 3:
          led.fade(40, FADE_TIME);
          led2.fade(8, FADE_TIME);
          direction = DIR_DOWN;
          tft.fillRect(224, 212, 12, 12, ILI9341_BLACK);
          DIM -= 1;
          delay (50);
          break;

        case 4:
          led.fade(80, FADE_TIME);
          led2.fade(15, FADE_TIME);
          direction = DIR_DOWN;
          DIM -= 1;
          tft.fillRect(242, 212, 12, 12, ILI9341_BLACK);
          delay (50);
          break;

        case 5:
          led.fade(120, FADE_TIME);
          led2.fade(20, FADE_TIME);
          direction = DIR_DOWN;
          tft.fillRect(260, 212, 12, 12, ILI9341_BLACK);
          DIM -= 1;
          delay (50);
          break;

        case 6:
          led.fade(160, FADE_TIME);
          led2.fade(25, FADE_TIME);
          direction = DIR_DOWN;
          tft.fillRect(278, 212, 12, 12, ILI9341_BLACK);
          DIM -= 1;
          delay (50);
          break;

        case 7:
          led.fade(200, FADE_TIME);
          led2.fade(30, FADE_TIME);
          direction = DIR_DOWN;
          tft.fillRect(296, 212, 12, 12, ILI9341_BLACK);
          DIM -= 1;
          delay (50);
          break;

        case 8:
          led.fade(255, FADE_TIME);
          led2.fade(40, FADE_TIME);
          direction = DIR_DOWN;
          tft.fillRect(170, 212, 12, 12, ILI9341_BLUE);
          tft.fillRect(188, 212, 12, 12, ILI9341_BLUE);
          tft.fillRect(206, 212, 12, 12, ILI9341_BLUE);
          tft.fillRect(224, 212, 12, 12, ILI9341_ORANGE);
          tft.fillRect(242, 212, 12, 12, ILI9341_ORANGE);
          tft.fillRect(260, 212, 12, 12, 0xFFE0);
          tft.fillRect(278, 212, 12, 12, 0xFFE0);
          tft.fillRect(296, 212, 12, 12, 0xF800);
          DIM -= 1;
          delay (50);
          break;
      }
    }
  }



}

Obi_wan79: da im Hintergrund noch andere Prozesse (Uhr, Zeitsteuerung und Temp Sensoren) arbeiten.

Gerade das spricht doch gegen blockierende Schleifen

postmaster-ino: :o fehlt Da nicht loop() komplett?

@postmaster-ino wieso so kleinlich? Setup ist ja wenigstens vorhanden. ;) ;) ;) ;)

Grüße Uwe

Wäre nicht die Zeichenbegrenzung hätte ich alles aufeinmal gepostet. Daher Teil 1 und Teil 2 ;)

Habe es zunächst auch ohne while laufen gehabt - aber dann ruckelt die Dimmung im Ergebnis und dimmt nicht sanft!

https://ibb.co/dfozML

Mit den Buttons kann mann manuell die Dimmstufen auswählen. Ohne while kann ich mit dem Switch problemlos mit dem Button wechseln. Jedoch ruckelt ohne while Dimmung, da der Loop zu lange braucht um an den led.update(); und led2.update(); wieder anzukommen. Mit while habe ich eine schöne Dimmung, muss aber dann warten bis die Dimmung durch das while natürlichabgeschlossen ist. Ich würde jedoch gerne auch während der Dimmung die Dimmstufe wechseln ohne abzuwarten.

Hi
resized-20181007-130214.jpg
Habe mir gestattet, das 3MB-Bild auf eine haldlichere Größe zu Reduzieren und ggf. dafür zu sorgen, daß Dieses auch in zwei Wochen noch zu sehen ist.

Schaut doch ganz nett aus!

MfG

PS: Wie soll Deine loop() schnell sein, wenn Du Millionen an Zeilen an das Display schickst und auch noch mit delay (mindestens Eins) als Anker sämtliche Funktionen ausbremst?

Die Zeilen schicke ich doch nur im Setup. Dort ist auch das Delay für mein "Start Bildschirm". Im loop geht es um die Darstellung der Variabeln. Hier habe ich nur die Delays um die Button auszubremsen.

Obi_wan79: Die Zeilen schicke ich doch nur im Setup. Dort ist auch das Delay für mein "Start Bildschirm". Im loop geht es um die Darstellung der Variabeln. Hier habe ich nur die Delays um die Button auszubremsen.

Du solltest dir allerdings die Frage stellen, ob es wirklich notwendig ist, in jedem loop-Durchlauf das Display zu aktualisieren und die Temperatursensoren abzufragen. Das vergrößert die loop-Durchlaufzeit nämlich auch. Eine Aktualisierung im Sekundentakt sollte meines Erachtens mehr als ausreichend sein.

Obi_wan79: Die Zeilen schicke ich doch nur im Setup. Dort ist auch das Delay für mein "Start Bildschirm". Im loop geht es um die Darstellung der Variabeln. Hier habe ich nur die Delays um die Button auszubremsen.

Ich habe mir deinen Code mal angesehen...

Das was mir auffällt, ist, dass du loop() zu einer Art Gottfunktion aufgeblasen hast...

Ich finde es besser(habe mir zur Regel gemacht), in "Zuständigkeiten" zu denken und auch das Programm so aufzuteilen.

Vorschlag: Jeder Teilbereich bekommt einen eigenständigen endlichen Automaten. Die Automaten senden sich gegenseitig Nachrichten. Erstmal, den vollständigen Verzicht auf Delay umsetzen.

Ziele: Das Display wird nur aktualisiert, wenn sich was ändert. Die Temperaturmessung blockiert nicht mehr, bis sie ein Ergebnis hat. Tasten werden immer ausgewertet, auch während des Dimmens (ohne while Unterbrechung)

loop() ist dann nur noch dafür zuständig, dass jeder dieser Automaten an die Reihe kommt. Es delegiert nur noch

Ablaufsteuerung Meine Standardantwort zu Ablaufsteuerungen:

Eine Stichworte Sammlung für Google Suchen: Endlicher Automat, State Machine, Multitasking, Coroutinen, Ablaufsteuerung, Schrittkette,

BlinkWithoutDelay,

Blink Without Delay

Der Wachmann

Multitasking Macros Intervall Macro

Hallo zusammen,

habe versucht eure Tips zu beherzigen und habe drei Intervalle (Blink without Delay :wink: )in meinen Sketch eingebaut. Die Temperaturen werden jetzt alle 2 Sek abgefragt und es findet im Anschluss ein Abgleich mit dem alten Sensorwert statt. Erst wenn dieser nicht mit dem Altwert übereinstimmt, wird das Display mit den neuen Wert aktualisiert. Die RTC Abfrage ist jetzt innerhalb eines 1 Sek Intervall. Die Zeitsteuerung wird alle 20 Sek abgefragt. Erstes unfertiges Ergebnis: Ich muss nicht mehr mit der Betätigung der Buttons die anderen Routinen stoppen damit der Wechsel in akzeptablen Zeitrahmen stattfindet. Die Dimmung der LED ist jetzt auch OHNE While flüssiger und blockiert nicht mehr die anderen Prozesse.

Daher vielen Dank!!!

Auszug aus dem Sketch:

if (currentMillis - previousMillis >= interval2) {   //Neu eingbautes Intervall
    sensors.requestTemperatures();
    float Wassertemp = 0;
    float LEDtemp = 0;
    LEDtemp = sensors.getTempCByIndex(0);
    Wassertemp = sensors.getTempCByIndex(1);
    if (Wassertempalt != Wassertemp) {               // Abgleich Neu mit Alt Wert
      tft.setCursor(20, 135);
      tft.setTextSize(5);
      if (Wassertemp <= 18 || Wassertemp >= 26) {
        tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
      }
      else if (Wassertemp <= 19 || Wassertemp >= 25) {
        tft.setTextColor(ILI9341_ORANGE, ILI9341_BLACK);
      }
      else if (Wassertemp >= 19 || Wassertemp <= 24) {
        tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
      }
      tft.print(Wassertemp, 1);
    }

    if (LEDtempalt != LEDtemp) {                              // Abgleich Neu mit Alt Wert
      tft.setCursor(185, 135);
      tft.setTextSize(5);
      if (LEDtemp >= 60) {
        tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
        DIM = 3;
      }
      else if (LEDtemp >= 55) {
        tft.setTextColor(ILI9341_ORANGE, ILI9341_BLACK);
      }
      else if (LEDtemp <= 55) {
        tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
      }

      tft.print(LEDtemp, 1);
    }
  Wassertempalt = Wassertemp;                     //Setzten der "neuen" Alt Werte
   LEDtempalt = LEDtemp;
  }

Habt ihr Tips wie man Variablen aus anderen Skopes an andere übergeben kann?

Habt ihr Tips wie man Variablen aus anderen Skopes an andere übergeben kann?

Im Grunde ja…
Aber da gibts so viele Möglichkeiten…
Und ein C++ Buch möchte ich dir jetzt nicht vorlesen.

Suchtipp:
Sichtbarkeit, oder “Geltungsbereich von Variablen in C++”


Zeige doch mal ein minimal Beispiel.

Wenn es unterschiedliche und unabhängige Intervalle sind, brauchst du jeweils ein eigenes previousMillis dafür.

unsigned long previousMillis2; // global oder static
...
if (currentMillis - previousMillis2 >= interval2) {
   previousMillis2 = currentMillis;  // oder:  previousMillis2 += interval2
   ...
}