Startknopf

Das problem ist nicht programm1, das klapt einwandfrei so wie ich es will, aber nur mit der alten variante des startknopfes :

buttonState = digitalRead(knopf1);
  if (buttonState != lastButtonState && buttonState == HIGH) {
    buttonPushCounter++; 
  }
  lastButtonState = buttonState;
  if (buttonPushCounter % 2 == 0 && status == 0) {
    digitalWrite(k[0], HIGH);
  } else {
    programm1();
  }

Aber das problem an dieser variante ist das ich das programm1 nur 1mal anschalten kann, danach kann ich es nicht verlassen oder reseten ich muss erst den ganzen arduino reseten.
Und das ist mein problem nicht programm1 sondern der teil im sketch mit dem startknopf.
Deswegen habe ich versucht mein problem mit bounce zu lösen also so:

if ( bouncer.update() ) {
     if ( bouncer.read() == HIGH) {
       if ( buttonState == LOW ) {
         programm1();
         buttonState = HIGH;
       } else {
         uint8_t i;
  for (i = 0; i < 4; i++) {
    digitalWrite(k[i], HIGH);
  }
    analogWrite(ledPin, 0);
    thresholdMillis = 0;
    nextMillis = 0;
    status = 0;
    
         buttonState = LOW;
       
      }
   }
}

Doch bei dieser variante ist das problem das programm1 sich an und ausschaltet wie es will und das das programm1 nicht läuft k[1] geht zwar beim start des programms an aber weiter geht es nicht.

strohhirn:
Aber das problem an dieser variante ist das ich das programm1 nur 1mal anschalten kann, danach kann ich es nicht verlassen oder reseten ich muss erst den ganzen arduino reseten.

Bei einer Schrittsteuerung machst Du es so, dass jeder Programmschritt eine Nummer bekommt. Gültige Programmschrittnummern sind dann beispielsweise 1 bis 9 und alles andere oder eine bestimmte andere Zahl wird betrachtet als "keinen Programmschritt ausführen".

Für Dich kannst Du z.B. definieren, dass Programmschrittnummer 999 für "Schrittsteuerung wird nicht ausgeführt" steht. "0" könnte man auch nehmen, aber Deine Programmschrittnummer heißt offenbar "status" und die "0" verwendest Du auch bereits als gültigen Programmschritt, also bietet sich 999 schon an für "Schrittsteuerung wird nicht ausgeführt".

Wenn Du nun die Variable "status" in der setup()-Funktion auf 999 setzt:
status=999;
Und dann beim Drücken des Tasters änderst Du den Status auf den ersten auszuführenden Programmschritt:
status=0;
Zwischen den Programmschritten schaltest Du weiter 1, 2, 3, usw. bis zum letzten Programmschritt,
da setzt Du dann am Ende des letzten Programmschritts wieder
status=999;

Und immer wenn in der loop der Status 999 gefunden wird, macht die Schrittsteuerung (Programm1) eben nichts.

Erst wenn beim nächsten Drücken des Tasters wird status wieder auf 0 gesetzt und die Schrittsteuerung läuft wieder neu ab.

Am Ende darf auch kein logischer Fehler in der Schrittabfolge drin sein, sonst laufen einzelne Schritte oder das gesamte Programm mehrfach ab, oder die Schrittsteuerung bleibt stehen und blockiert sich selbst. Damit man keine logischen Fehler einbaut, ist es sinnvoll dem Programm eine klare Struktur zu geben und die Funktionen übersichtlich zu halten.

Programm1() wird nur einmal aufgerufen, wenn der Taster gerade gedrückt wurde. Also kommt es auch nur bis Status 1 ...

Programm starten und beenden ist eine "normale", aber unpassende Sichtweise:

Bei Controllern hört das Programm nie auf, sondern läuft ewig (bis Reset oder Strom aus). Es wird nur festgestellt ob sich was geändert hat, z.B. Zeit abgelaufen, Temperatur erreicht, Taste gedrückt, etc.
Der neue Zustand wird passend gespeichert damit die "Programme" die gerade laufen oder auch nicht, wissen was los ist.
Ein einzelner loop-Durchlauf dauert praktisch keine Zeit. (Na ja, analogRead kostet mehr als 100 µs, aber man sollte sich nicht darauf verlassen, dass im nächsten Durchlauf millis() einen anderen Wert als jetzt hat.)

D.h. in deinem Fall:

  • entweder loop() muss immer Programm1() aufrufen, und Programm1 stellt fest was zu tun ist: nichts (da eine gerade Anzahl Tastendrucke), oder evtl von status1 nach status2 wechseln ...
  • oder loop weiss, dass gerade Programm1 aktiv ist und ruft es in jedem Durchlauf auf, bis Programm1 "beendet" ist.

Aber das sind Feinheiten und eher philosophischer Natur -- gehört der Taster zu programm1() oder zu loop() ?

edit: wenn schon komplizierte Wörter, dann auch mit richtiger Grammatik

Ich hab das jetzt mal folgendermaßen umgesetzt:

if ( bouncer.update() ) {
     if ( bouncer.read() == HIGH) {
       if ( buttonState == LOW ) {
         uint8_t i;
  for (i = 0; i < 4; i++) {
    digitalWrite(k[i], HIGH);
  }
    analogWrite(ledPin, 0);
    thresholdMillis = 0;
    nextMillis = 0;
    status = 0;
       } else {
         
    status = 20;
         buttonState = LOW;
       
      }
   }
}
programm1();
}  //(endklammer des loops)

Die probleme jetzt sind das das programm1 gleich bei stromanschluss startet.
Das programm1 funktioniert aber wenn ich es ausschalten will (also nochmal auf den knopf drücke) springt das programm1 nur auf status 0 zurück anstatt auf status 20 ( 20 entspricht 999 von jurs).

Was habe ich diesmal falsch gemacht?

Die probleme jetzt sind das das programm1 gleich bei stromanschluss startet.

Dann fehlt vermutlich ein "status = 20;" in Deiner Setup-Routine, wenn 20 jetzt Dein "aus" Status ist.

Das programm1 funktioniert aber wenn ich es ausschalten will (also nochmal auf den knopf drücke)
springt das programm1 nur auf status 0 zurück anstatt auf status 20 ( 20 entspricht 999 von jurs).
Was habe ich diesmal falsch gemacht?

Im Endeffekt mußt Du beim Schalterdrücken entweder mitzählen, wie oft der Taster gedrückt wird.

Ungerade Anzahl mal gedrückt: "status = 0;" setzen, also "starten".
Gerade Anzahl mal gedrückt: "status = 20;" setzen, also "aus".

Erst mal vielen Dank an alle die mitgedacht und mitgeholfen haben.

Dann fehlt vermutlich ein "status = 20;" in Deiner Setup-Routine, wenn 20 jetzt Dein "aus" Status ist.

Ja 20 ist jetzt mein aus status und du hattest recht im setup war status noch auf 0 gesetzt.
Hab jetzt noch mal ein bisschen durchprobiert und jetzt klappt es erst mal endlich wie gewollt. :slight_smile:
Hier mal jetzt das gesamtergebnis:

#include <Bounce.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>


#define ONE_WIRE_BUS 30  // Temperatursensor pin 30
#define FADE_DELAY 3 // Verzögerung beim Faden
LiquidCrystal lcd(22, 23, 24, 25, 26, 27, 28);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

DeviceAddress Sensor[] = {{0x28, 0xCD, 0x9B, 0xDA, 0x03, 0x00, 0x00, 0xF2},
                          {0x28, 0x1F, 0xA3, 0xDA, 0x03, 0x00, 0x00, 0xE2},
                          {0x28, 0x2D, 0xB9, 0xDA, 0x03, 0x00, 0x00, 0xA0},
                          {0x28, 0x37, 0x88, 0xDA, 0x03, 0x00, 0x00, 0x7D}};

int backLight = 29;
uint8_t k[] = {31, 32, 33, 35};   //relais HIGH = Aus; LOW = An

uint8_t knopf1 = 34;
uint8_t buttonState = 0; //knopf
int buttonPushCounter = 0; 
uint8_t lastButtonState = 0;
Bounce bouncer = Bounce( knopf1, 5 );

uint32_t previousMillis = 0;


int   mpxPin =  5; //drucksensor
int   mpx;
float pkPa;

uint8_t ledPin = 9; // (kemo)
uint8_t fade;
uint8_t status;

 uint32_t nextMillis = 0;
 uint32_t thresholdMillis = 0;

void setup() {
  pinMode(backLight, OUTPUT);
  digitalWrite(backLight, HIGH);
  lcd.begin(20, 4);
  sensors.begin();
  uint8_t i;
  for (i = 0; i < 4; i++) {
    pinMode(k[i], OUTPUT);
    digitalWrite(k[i], HIGH);
  }
  pinMode(knopf1, INPUT);
  
  status=20; // 20 = aus
  sensors.setWaitForConversion(false);
  sensors.requestTemperatures();
}

void loop(){
  // check if conversion is done
  if (oneWire.read_bit()) {
    
    uint8_t i;
    for (i = 0; i < 4; i++) {
      lcd.setCursor(0, i);
      lcd.print("T");
      lcd.print(i+1, DEC);
      lcd.print(":");
      if (sensors.isConnected(Sensor[i])) {
        lcd.print(sensors.getTempC(Sensor[i]));
        lcd.print("C");
      } else {
        lcd.print("AUS   ");
      }
    }
    // start next conversion
    sensors.requestTemperatures();
  
    mpx = analogRead(mpxPin);
    pkPa = (mpx/1023.0-0.04)/0.0018;
    lcd.setCursor(10, 0);
    lcd.print(pkPa);
    lcd.print("mb   ");
    lcd.setCursor(10, 1);
    lcd.print(fade);
  }
    
  
  
  if ( bouncer.update() ) {
     if ( bouncer.read() == HIGH) {
       if ( buttonState == LOW ) {
         uint8_t i;
         for (i = 0; i < 4; i++) {
          digitalWrite(k[i], HIGH);
          }
         analogWrite(ledPin, 0);
         thresholdMillis = 0;
         nextMillis = 0;
         
         status = 0;
         
         buttonState = HIGH;
       } else {
         
         status = 20; // programm1 aus
         uint8_t i;
         for (i = 0; i < 4; i++) {
          digitalWrite(k[i], HIGH);
          }
         analogWrite(ledPin, 0);
         thresholdMillis = 0;
         nextMillis = 0;
    
         buttonState = LOW;
      }
    }
  }
  programm1();
} // endklammer des loops

void programm1() {
  
 if (status == 0){
    digitalWrite(k[0], LOW);
    status = 1;
  } else if (sensors.getTempC(Sensor[0]) >= 23.0 && status == 1) {
    digitalWrite(k[0], HIGH);
    status = 2;
    nextMillis = millis() + 30000L;
  } else if (status == 2 && millis() > nextMillis) {
    digitalWrite(k[1], LOW);
    digitalWrite(k[2], LOW);
    digitalWrite(k[3], LOW);
    fade = 0;
    analogWrite(ledPin, fade);
    fade = 51;
    analogWrite(ledPin, fade);
  
		status = 3;
		nextMillis = millis() + 30000L;
	
  } else if (status == 3 && millis() > nextMillis) {
    fade = 102;
    analogWrite(ledPin, fade);
      status = 4;
      nextMillis = millis() + 30000L;
  } else if (status == 4 && millis() > nextMillis) {
    fade = 153;
    analogWrite(ledPin, fade);
  
      status = 5;
      nextMillis = millis() + 30000L;
    
  } else if (status == 5 && millis() > nextMillis) {
    fade = 255;
      status = 6;
    
  }
  if (sensors.getTempC(Sensor[0]) >= 25.0 && thresholdMillis == 0) {
    digitalWrite(k[1], HIGH);
    thresholdMillis = millis() + 30000L;
  } else if (thresholdMillis && millis() > thresholdMillis) {
    digitalWrite(k[2], HIGH);
    digitalWrite(k[3], HIGH);
    analogWrite(ledPin, 0);
    thresholdMillis = 0;
    nextMillis = 0;
    fade = 0;
    
    status = 20;
  }   
}

Als nächstes will ich noch einen pausenknopf, um programm1 anhalten und fortführen zu können, einbauen, aber das versuch ich erstmal selbst zu machen.

Noch mal vielen Dank, besonders an jurs der sehr aktiv und interesiert mitgewirkt hat.

Mfg

strohhirn