merkwürdiges Verhalten

Hallo,

ich habe einen Arduino-Sketch geschrieben, der einie Steuerungen an meiner Espressomaschine übernehmen soll.

Im Großen und Ganzen funktioniert er auch. Allerdings treten seit Gestern einige merkwürdige Dinge auf, die ich mir trotz stundenlangen Probierens und Lesens nicht erklären kann.

Folgendes Setup habe ich.

Arduino Pro mini
2x16 LCD (funktioniert problemlos)
2 Taster einmal an Pin 6 und einmal an Pin 7 jeweils als INPUT_PULLUP (downPin und upPin)
2 Temperatursensoren am 1-wire-bus an Pin 8 (zeigen ordentlich an)

mit einem Taster (upPin) scrolle ich das Menu hoch indem ich den integer menupos hochzähle und in der loop mit printmenu das LCD entsprechend ansteuere. Das klappt auch prima

In den Menustellungen 3 und 5 soll der andere Taster abgefragt und entsprechend eine unterprozedur aufgerufen werden (reinigung() und archiv())
Dazu wird der Tasterzustand in der loop mit digitalRead abgefragt. Die Auswertung falls downBtn == LOW erfolgt dann mit switch case:

interessanterweise funktioniert das bei menupos == 5 für die Unterfunktion reingen() problemlos. Für menupos == 3, reagiert die Sache nicht. Auch nicht, wenn ich code unter default: eingebe. NUR bei 5.

Den Wert von menupos habe ich kontrolliert, indem ich ihn auf dem Display mit anzeigen lasse. Daran kann es nicht liegen. Hier steht eine 3.

Hat jemand eine Idee, woran diese selektive Funktion der switch-case Auswertung liegen kann?
Hier meine loop():

void loop() {
     
  sensoren.requestTemperatures();
  //Hier lesen wir den ersten Sensor (0) aus
  t1 = sensoren.getTempCByIndex(0); //Boilertemperatur
  // und hier den zweiten....
  t2 = sensoren.getTempCByIndex(1); //Brühtemperatur
  
  MVState = digitalRead(MVPin);
  downBtn = digitalRead(downPin);
  upBtn = digitalRead(upPin);
  
  if (downBtn == LOW){
    downBtn = HIGH;
    switch (menupos) {
      case 3:
       archiv();
      break;
      case 5:
        reinigung();
      break;
     default:
      // hier wird eine defaultaktion gestgelegt, derzeit NICHTS
      //archiv();
     break;
     }
  }
  
  if (upBtn == LOW) {
     menuDown();
  } 
 
  printMenu(menupos);
  
  if (MVState == LOW) {
    if (isrunning==false) {
      zeit=millis()/1000;
      isrunning=true;
      shotTemp = t2;
    } else {
     shot = millis()/1000-zeit;
    }
   } else {
     if (isrunning) {
      if (shot < 10) {
        shot = lShotTime;
      } else {
        lShotTime = shot;
        historyShot[lastshot]= shot;
        historyTemp[lastshot]=shotTemp;
        if (++lastshot > 10) {
          lastshot = 1;
        }  
      }
     isrunning = false;
   }
  }
}

fol

Hallo,

wir brauchen den kompletten Sketch, damit wir auch wissen, wie die variablen definiert sind.
Ebenso die Funktionen sind wichtig.

Der Fehler liegt meist im geheimen Teil des Codes. :wink:

Üblicherweise ist der Fehler im weggelassenen Teil, also z.B. in archiv().
Musst du deine Testausgaben evtl. ändern, verfeinern.

Wofür ist

   downBtn = HIGH;

gedacht?
Weggelassene Variablendefinitionen (und warum ist downBtn global?) machen dich auch verdächtig.

gerne, hier der ganze Sketch!

das setzen der Variable auf HIGH habe ich gemacht, um einen definierten Zustand zu haben

// include the library code:

#include <OneWire.h> // f. Thermosensor 1820
#include <DallasTemperature.h> // "
#include <LiquidCrystal.h> // f. Ansteuerung LCD


// define constants

const int MVPin = 9; // für Magnetventil zur Shotmessung
const int downPin = 7; // Up and Down-Button für Menusteuerung
const int upPin = 6;
const int ShotPin = 10; // Pin zum Optokoppler f. Bezugsschalter (wird für Reinigung benötigt)
const int pumpTime = 7000; // Pumpzeit in ms bei Rückspülprogramm
const int waitTime = 30000; // Einweichzeit in ms bei Rückspülprogramm
const int btnPressTime = 500; // Zeit in ms, die Spülbutton gedrückt wird
//const unsigned long Baud_Rate = 9600;
const unsigned char One_Wire_Bus = 8;
 

// initialize the Display-library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// initialize Library for DS18S20 Temperaturesensors
OneWire oneWire(One_Wire_Bus);
DallasTemperature sensoren(&oneWire);

// Variablen Deklaration

// define menu
int maxmenu = 5; // Anzahl der MenuEinträge, muss in der folgenden Zeile angepasste werden!
int maxarchiv = 11;


// 10 Speicherplätzte für Zeit und Temperatur der 10 letzten Shots
int historyShot[10]{0,0,0,0,0,0,0,0,0,0};
int historyTemp[10]{0,0,0,0,0,0,0,0,0,0};

// sonstige Variablen

int Anzahl_Sensoren = 0;
int zeit = 0;
int shot = 0;
int lastshot = 0;
int lShotTime = 0;
int menuTime = 0;
int menupos = 1;
int archivpos = 1;
boolean isrunning = false;
int ledState = LOW;
int MVState = HIGH;
int downBtn = HIGH;
int upBtn = HIGH;
float t1 = 0.0;
float t2 = 0.0;
float shotTemp = 0.0;

void setup() {
  
  pinMode(MVPin,INPUT_PULLUP);
  pinMode(upPin,INPUT_PULLUP);  
  pinMode(downPin,INPUT_PULLUP);  
  pinMode(ShotPin,OUTPUT);
  
  sensoren.begin();
//  Serial.begin(Baud_Rate);
 
//Hier schauen wir, wieviel Sensoren angeschlossen sind
Anzahl_Sensoren = sensoren.getDeviceCount();
  

lcd.begin(16, 2);
}

void loop() {
     
  sensoren.requestTemperatures();
  //Hier lesen wir den ersten Sensor (0) aus
  t1 = sensoren.getTempCByIndex(0); //Boilertemperatur
  // und hier den zweiten....
  t2 = sensoren.getTempCByIndex(1); //Brühtemperatur
  
  MVState = digitalRead(MVPin);
  
  upBtn = digitalRead(upPin);
  downBtn = digitalRead(downPin);
  
  if (downBtn==LOW){
      switch (menupos) {
      case 3 :
        archiv();
      break;
      case 5 :
        reinigung();
      break;
     default:
      // hier wird eine defaultaktion gestgelegt, derzeit NICHTS
      //archiv();
     break;
     }
  }
  
  if (upBtn == LOW) {
     menuDown();
  } 
 
 // if ((millis()-menuTime) > 30000) {
  //  menupos = 1;
     //menuTime = millis();
 // }
  
  printMenu(menupos);
  
  if (MVState == LOW) {
    if (isrunning==false) {
      zeit=millis()/1000;
      isrunning=true;
      shotTemp = t2;
    } else {
     shot = millis()/1000-zeit;
    }
   } else {
     if (isrunning) {
      if (shot < 10) {
        shot = lShotTime;
      } else {
        lShotTime = shot;
        historyShot[lastshot]= shot;
        historyTemp[lastshot]=shotTemp;
        if (++lastshot > 10) {
          lastshot = 1;
        }  
      }
     isrunning = false;
   }
  }
} 

void archiv(){
  printArchiv(1);
}

void printArchiv(int pos) {
switch (pos) {
    case 1:
      //do something when var equals 1
      lcd.setCursor(0, 0);
      lcd.print(pos);
      lcd.print(" T=");
      lcd.print(historyTemp[pos]);
      lcd.print(" Z=");
      lcd.print(historyShot[pos]);
     break;
}  
}

void reinigung(){
  delay (400);
  lcd.setCursor(0,0);
  lcd.print("Reinigung Abbr?");
  lcd.setCursor(0,1);
  lcd.print("Blinds. ein! OK?");
  downBtn = HIGH;
  upBtn = HIGH;
    do {
      downBtn = digitalRead(downPin);
      upBtn = digitalRead(upPin);
    } while (downBtn == HIGH && upBtn == HIGH);
  if (upBtn==LOW) {
  }else {
    lcd.setCursor(0,0);
    lcd.print("Reinigung l");
    lcd.write(char(225));
    lcd.print("uft ");
    lcd.setCursor(0,1);
    lcd.print("  Bitte warten! ");
    for (int i=0; i <= 4; i++){
      digitalWrite(ShotPin,HIGH);
      delay(btnPressTime);
      digitalWrite(ShotPin,LOW);
      delay(pumpTime);
      digitalWrite(ShotPin,HIGH);
      delay(btnPressTime);
      digitalWrite(ShotPin,LOW);
      delay(waitTime);
    } 
    lcd.setCursor(0,0);
    lcd.print("Reinigung fertig");
    lcd.setCursor(0,1);
    lcd.print("Blinds. entfern.");
    downBtn = HIGH;
    upBtn = HIGH;
    do {
      downBtn = digitalRead(downPin);
      upBtn = digitalRead(upPin);
    } while (downBtn == HIGH && upBtn == HIGH);
    lcd.setCursor(0,0);
    lcd.print(" Klar sp");
    lcd.write(char(245));
    lcd.print("len... ");
    lcd.setCursor(0,1);
    lcd.print("  Bitte warten! ");
    for (int i=0; i <= 4; i++){
      digitalWrite(ShotPin,HIGH);
      delay(btnPressTime);
      digitalWrite(ShotPin,LOW);
      delay(10000);
      digitalWrite(ShotPin,HIGH);
      delay(btnPressTime);
      digitalWrite(ShotPin,LOW);
      delay(10000);
      menupos = 1;
    }
  }
}



void menuDown(){
  if (--menupos < 1) {
    menupos = maxmenu; 
    menuTime = millis();
  }
  
}

void printMenu(int pos){
switch (pos) {
    case 1:
      //do something when var equals 1
      lcd.setCursor(0, 0);
      lcd.print(menupos);
      lcd.print("Shottime: ");
      lcd.print(shot);
      lcd.print (" sec."); 
      lcd.setCursor(0, 1);
      lcd.print("Br");
      lcd.write(char(245));
      lcd.print("htemp: ");
      lcd.print(t2,1);
      lcd.write(0xDF);
      lcd.print("C ");
      break;
    case 2:
      lcd.setCursor(0, 0);
      lcd.print(menupos);
      lcd.print("Br");
      lcd.write(char(245));
      lcd.print("htemp: ");
      lcd.print(t2,1);
      lcd.write(0xDF);
      lcd.print("C ");
      lcd.setCursor(0, 1);
      lcd.print("Shot-Archiv     ");
      //do something when var equals 2
      break;
    case 3:
      lcd.setCursor(0, 0);
      lcd.print(menupos);
      lcd.print("Shot-Archiv     "); 
      lcd.setCursor(0, 1);
      lcd.print("H2O-Temp.: ");
      lcd.print(t1,0);
      lcd.write(0xDF);
      lcd.print("C  "); 
      break;
    case 4:
      lcd.setCursor(0, 0);
      lcd.print(menupos);
      lcd.print("H2O-Temp.: ");
      lcd.print(t1,0);
      lcd.write(0xDF);
      lcd.print("C  "); 
      lcd.setCursor(0, 1);
      lcd.print("Reinigungsprog. ");
      break;
    case 5:
      lcd.setCursor(0, 0);
      lcd.print(menupos);
      lcd.print("Reinigungsprog. "); 
      lcd.setCursor(0, 1);
      lcd.print("Shottime: ");
      lcd.print(shot);
      lcd.print (" sec.");
      break;
    
    default:
      // if nothing else matches, do the default
      // default is optional
    break;
  }
 }

Für menupos == 3, reagiert die Sache nicht
Den Wert von menupos habe ich kontrolliert, indem ich ihn auf dem Display mit anzeigen lasse. Daran kann es nicht liegen. Hier steht eine 3.

Die Funktion archiv() schreibt erstmal eine 1 oben links aufs LCD und T= ... Z= ....
Das kann man aber nicht sehen, denn danach kommt sofort printMenu(3) dran und überschreibt wieder alles, diesmal mit 3 oben links.

Was funktioniert nun nicht so wie du das willst?

Bringen dich die verschiedenen pos und menupos Variablen durcheinander?
Oder dass der Arduino schneller ist als du schauen kannst? (Das hat auch sein Gutes)

Ich bin ja blöd :o

In der Tat. Hat mich die Geschwindigkeit hier hinters Licht geführt.

Danke michael_x. Der Hinweis war Gold wert.

Der Code im ArchivTeil war ja nur testweise da. Habe völlig versäumt ihn dort mal etwas verweilen zu lassen
Jetzt läuft alles super und ich kann weitermachen.

Ja und Du hast recht. an der Übersichtlichkeit muss ich noch arbeiten :slight_smile: