Switch Case problem... ich verzweifle

Hallo!

Ich versuche gerade mehrere Temperatursensoren durch einen Taster durchzuschalten und auf dem 16x2 LCD anzuzeigen. Eigentlich soweit auch schon feritg und funktioniert.

Leider aber bekommen ich im switch case immer nur den momentan-wert "eingfroren" und nicht den kontinuierlichen Wert vom Sensor.

Habe mir auch schon eine Variable vorher im loop gebastelt und dort den tempsensor rein geschrieben und diese dann im swich case verwendet. War auch nichts...

Hat mir jemand eine Idee?

Vielen Dank!

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

const int taster = 2;     // Eingang des Taster der ueber einen pulldown R auf +5V geht

int durchschaltvar = 1;   // Durchschaltvariable fuer Tastereingang
    
int buttonState = 0;   // Var in welche der Buttonstate abgelegt wird

float temp1 = 0;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // LCD Setup

//DS18b20 Tempsensor ist an D13 agneschlossen 
#define DS18B20 13

OneWire ourWire(DS18B20);
DallasTemperature sensors(&ourWire);

void setup()
{
pinMode(taster, INPUT);
//Serial.begin(9600);
delay(1000);
Serial.println("Serial Start");
//start reading
sensors.begin();
//setup the LCD
lcd.begin(16, 2); // start the library
lcd.setCursor(0,0);
lcd.print("VW T5 SensorBox");
delay(3000);    
lcd.clear();  

}




void loop() {


buttonState = digitalRead(taster); //Taster abfragen für switch case



if (buttonState == HIGH) {

    switch (durchschaltvar) {

      case 1: // mach was beim ersten mal drücken
        
        lcd.clear();  
        lcd.setCursor(0, 0);
        lcd.print("Temperatur");
        sensors.requestTemperatures();
        lcd.setCursor(0, 1);
        lcd.print(sensors.getTempCByIndex(0)); // Temp von sensor holen
        lcd.setCursor(8, 1);
        lcd.print("Grad");
        delay(500);
        durchschaltvar++;
        break;

      case 2: 

        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Test fuer Case 2");
        lcd.setCursor(0, 1);
        lcd.print("=-=-=-=-=-=");
        delay(500);
        durchschaltvar++;
        break;

      case 3: 

        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Test fuer Case 3");
        lcd.setCursor(0, 1);
        lcd.print("=-=-=-=-=-=");
        delay(500);
        durchschaltvar++;
        break;

      case 4:

        lcd.clear();
        lcd.setCursor(8, 1);
        lcd.print("Test fuer Case 4");
        delay(500);
        durchschaltvar = 1;
        break;


    }
  }
}

Sicher lässt du nach dem Drücken den Taster wieder los.
Dann wird er nicht mehr von der "if-Anweisung" erfasst.
Du musst in einer Variablen den Tastendruck speichern und danach abfragen.

Und ich hoffe, du hast den Taster entprellt.

Und ich hoffe, du hast den Taster entprellt.

Bei delay(500); braucht @palemrx da nichts weiter zu machen.

Ich würde die Kommentarzeichen bei//Serial.begin(9600); entfernen. Oder das Serial.print() kurz danach auch rausnehmen.

Der switch Zweig wird bei dir nur durchlaufen, solange der Taster gedrückt ist, und dann alle halbe Sekunde weitergeschaltet. Das willst du wohl nicht so. :wink:

Vielen Dank für den eigentlich logischen umbau beim "if"...!! Soweit funktionierts freu nur funktioniert leider mein Schalter jetzt nur noch sehr schlecht und ich denke mir aus es sei weil ich die Temp im Prozessorgeschwindigkeit Abfrage. Kann das sein und wenn ja wie vermeide ich das? Es ist nicht so dass er gar nicht geht aber einfach schlecht, mal springt er erst nach langen drücken mal gar nicht und mal sofort.

Hat mir da auch noch wer eine Idee?

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

const int taster = 2;     // Eingang des Taster der ueber einen pulldown 10kOhm R auf GND geht

int durchschaltvar = 1;   // Durchschaltvariable fuer Tastereingang
    
int buttonState = 0;   // Var in welche der Buttonstate abgelegt wird

float temp1 = 0;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // LCD Setup

//DS18b20 Tempsensor ist an D13 agneschlossen 
#define DS18B20 13

OneWire ourWire(DS18B20);
DallasTemperature sensors(&ourWire);

void setup()
{
pinMode(taster, INPUT);
Serial.begin(9600);
delay(1000);
Serial.println("Serial Start");
//start reading
sensors.begin();
//setup the LCD
lcd.begin(16, 2); // start the library
lcd.setCursor(0,0);
lcd.print("VW T5 SensorBox");
delay(3000);    
lcd.clear();  

}




void loop() {


buttonState = digitalRead(taster); //Taster abfragen für switch case


if (buttonState == HIGH) {
  
  durchschaltvar++; //Wert in der Var um eins erhöhen
 }

sensors.requestTemperatures(); //Temp vom sensor anfordern


temp1 = (sensors.getTempCByIndex(0)); //Temp von Sensor in Var temp1 schreiben


switch (durchschaltvar) {

      case 1: // mach was beim ersten mal drücken
        
        lcd.clear();  
        lcd.setCursor(0, 0);
        lcd.print("Temp Sensor 1");
        lcd.setCursor(0, 1);
        lcd.print(temp1); //Temp anzeigen aus var
        lcd.setCursor(8, 1);
        lcd.print("Grad");
        delay(500);
        break;

      case 2: 

        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Test fuer Case 2");
        lcd.setCursor(0, 1);
        lcd.print("2222");
        delay(500);
        break;

      case 3: 

        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Test fuer Case 3");
        lcd.setCursor(0, 1);
        lcd.print("3333");
        delay(500);
        break;

      case 4:

        //wird nur zur Rückkher auf Case 1 gebraucht
        delay(500);
        durchschaltvar = 1;
        break;


    }

}

Das Problem ist nicht das "schnelle" auslesen des Sensors, sondern die Delays in den einzelnen Case-Verzweigungen. Die brauchst du nicht.

Außerdem brauchst du die Anweisungen "lcd.clear()" nicht. Du überschreibst ja den jeweiligen Inhalt neu.
Durch das clear handelst du dir nur unnötiges Flackern ein.

hier mal ein Auszug für Tastenabfrage gekürzt von vor ein paar Tagen

  int oldbuttonState = 0;

  buttonState = digitalRead(inPin);   // Tasten-Status lesen
  if (buttonState != oldbuttonStatel)          // Tastenstatus geändert ?
  { 
    oldbuttonState = buttonStatel;    // Tasten-Status merken !
    delay(10);              // 10 millisekunden "EntprellZeit"
    if (buttonState = 1)             // Taste wurde gedrückt
    { 
    
    }
    else                    // Taste wurde losgelassen
    {

    }
  }

Das Problem ist das delay in dem request

Vielen Dank für eure Hilfe! Ja das Problem liegt wirklich im sensors.requestTemperatures(); dies verlangsamt meine Code so dass der Taster schlecht anspricht. Mache ich aber ein delay rein macht‘s das auch nicht besser weil man ja dann den Zustand dazwischen treffen muss. Kann man das sensors.requestTemperatures(); nicht verlangsamen, mir würde jede Sekunde eine Abfrage genügen...?!

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

const int taster = 2;     // Eingang des Taster der ueber einen pulldown R auf +5V geht

int durchschaltvar = 1;   // Durchschaltvariable fuer Tastereingang
    
int buttonState = 0;  // Var in welche der Buttonstate abgelegt wird

float temp1 = 0;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // LCD Setup

//DS18b20 Tempsensor ist an D13 agneschlossen 
#define DS18B20 13

OneWire ourWire(DS18B20);
DallasTemperature sensors(&ourWire);

void setup()
{
pinMode(taster, INPUT);
Serial.begin(9600);
delay(1000);
Serial.println("Serial Start");
//start reading
sensors.begin();
//setup the LCD
lcd.begin(16, 2); // start the library
lcd.setCursor(0,0);
lcd.print("VW T5 SensorBox");
delay(3000);    
lcd.clear();  




}




void loop(void) {
  
sensors.requestTemperatures(); //Temp vom sensor anfordern

buttonState = digitalRead(taster);

if (buttonState == HIGH) {
  delay(800);
  lcd.clear(); 
  durchschaltvar++ ; //Wert in der Var um eins erhöhen
 }



temp1 = (sensors.getTempCByIndex(0)); //Temp von Sensor in Var temp1 schreiben


switch (durchschaltvar) {

      case 1: // mach was beim ersten mal drücken
        
    
        lcd.setCursor(0, 0);
        lcd.print("Temp Sensor 1");
        lcd.setCursor(0, 1);
        lcd.print(temp1); //Temp anzeigen aus var
        lcd.setCursor(8, 1);
        lcd.print("Grad");
      
        break;

      case 2: 

   
        lcd.setCursor(0, 0);
        lcd.print("Test fuer Case 2");
        lcd.setCursor(0, 1);
        lcd.print("2222");
      
        break;

      case 3: 

       
        lcd.setCursor(0, 0);
        lcd.print("Test fuer Case 3");
        lcd.setCursor(0, 1);
        lcd.print("3333");
     
        break;

      case 4:

        //wird nur zur Rückkher auf Case 1 gebraucht
     
        durchschaltvar = 1;
        break;


    }
}

Wie lange requestTemperatures() braucht liegt an der eingestellten Auflösung. 94ms bei 9 Bit, 188ms bei 10 Bit, 375ms bei 11 Bit und 750ms bei 12 Bit

Man kann das aber mit der Library auch nicht-blockierend schreiben und dann die nötige Verzögerung zwischen Anforderung und Auslesen a la BlinkWithoutDelay machen

Ok ich verstehe, dann ist aber der Dallas Temp.Sensor nicht so toll?! Aber der DHT11 mochte mich auch nicht überzeugen und analog finde ich etwas zu retro oder was meint ihr dazu?

Ich hab‘s jetzt mal so gelöst funktioniert nicht perfekt aber am besten von allen Versuchen. Ich hole so ohne delay die temp nur alle 2sek per request.

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

const int taster = 2;     // Eingang des Taster der ueber einen pulldown R auf +5V geht

int durchschaltvar = 1;   // Durchschaltvariable fuer Tastereingang
    
int buttonState = 0;  // Var in welche der Buttonstate abgelegt wird

float temp1 = 0;      // Var für die Temp vom sensor 1

LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // LCD Setup

//DS18b20 Tempsensor ist an D13 agneschlossen 
#define DS18B20 13

OneWire ourWire(DS18B20);
DallasTemperature sensors(&ourWire);




unsigned long previousMillis = 0;        // Speicher für letztes  Abfragen sensor                       
const long interval = 2000;              // Abfrageinterval

void setup()
{
pinMode(taster, INPUT);
Serial.begin(9600);
delay(1000);
Serial.println("Serial Start");
//start reading
sensors.begin();
//setup the LCD
lcd.begin(16, 2); // start the library
lcd.setCursor(0,0);
lcd.print("VW T5 SensorBox");
delay(3000);    
lcd.clear();  




}




void loop(void) {
  
unsigned long currentMillis = millis();   // ohne delay die Temp updaten


buttonState = digitalRead(taster);

if (buttonState == HIGH) {
  delay(400);
  lcd.clear(); 
  durchschaltvar++ ; //Wert in der Var um eins erhöhen
 }



temp1 = (sensors.getTempCByIndex(0)); //Temp von Sensor in Var temp1 schreiben


switch (durchschaltvar) {

      case 1: // mach was beim ersten mal drücken

       if (currentMillis - previousMillis >= interval) {
           previousMillis = currentMillis;
           sensors.requestTemperatures(); //Temp vom sensor anfordern
          }        
        lcd.setCursor(0, 0);
        lcd.print("Temp Sensor 1");
        lcd.setCursor(0, 1);
        lcd.print(temp1); //Temp anzeigen aus var
        lcd.setCursor(8, 1);
        lcd.print("Grad");
        break;

      case 2: 

        //lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Test fuer Case 2");
        lcd.setCursor(0, 1);
        lcd.print("2222");
        break;

      case 3: 

        //lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Test fuer Case 3");
        lcd.setCursor(0, 1);
        lcd.print("3333");
        break;

      case 4:

        //wird nur zur Rückkher auf Case 1 gebraucht
        //delay(500);
        durchschaltvar = 1;
        break;


    }
}

Schau Dir mal das Bibliotheksbeispiel WaitForConversion2.pde mit Wartezeit mit millis() an, das könnte Dir möglicherweise helfen.

palemrx:
Ok ich verstehe, dann ist aber der Dallas Temp.Sensor nicht so toll?!

Der Sensor ist gut. Du musst nur verstehen was da abläuft und was man machen muss. Und dir mal die Library genauer ansehen.

Es gibt auch Anwendung wie die Verzögerung völlig egal ist. z.B. wenn man nur alle paar Minuten misst

Liest alle 1000ms den Sensor nicht-blockierend ein:

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

const unsigned long TEMP_POLLING_INTERVAL = 1000;

OneWire oneWire(2);
DallasTemperature temperatureSensors(&oneWire);

void setup() 
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);

  temperatureSensors.begin();
  temperatureSensors.setResolution(10);
  temperatureSensors.setWaitForConversion(false);
}

void loop() 
{
  static unsigned long previousMillis;

  if (millis() - previousMillis > 500)
  {
    digitalWrite(13, !digitalRead(13));
    previousMillis = millis();
  }
  
  if (readTemperature() == true)
  {
    float temperature = temperatureSensors.getTempCByIndex(0);
    Serial.print(millis()); Serial.print('\t'); Serial.println(temperature);
  }
}

bool readTemperature()
{
  static unsigned long previousPollingMillis;
  static unsigned long previousRequestMillis;
  static bool dataRequested;

  if (dataRequested == true && millis() - previousRequestMillis > 200)
  {
    dataRequested = false;
    return true;
  }

  if (dataRequested == false && millis() - previousPollingMillis > TEMP_POLLING_INTERVAL)
  {
    temperatureSensors.requestTemperaturesByIndex(0);
    
    dataRequested = true;
    previousPollingMillis = millis();
    previousRequestMillis = millis();
  }

  return false;
}

Die millis() Debug Ausgabe ist nicht genau 1000ms. Das wird aber daran liegen dass das in loop() neu ausgelesen wird statt den Wert vor der Anforderung zu speichern. Die 200ms Verzögerung sind für 10 Bit. Für andere Auflösungen muss man das anpassen. Oder aus der Auflösung heraus berechnen.

In loop() blinkt die LED an Pin 13 damit man sieht das während der Zeit auch was anderes gemacht wird

Die Ausgabe der Temperatur könnte man auch in readTemperature() machen. Aber der Code ist aus einem größeren Programm wo das weiter getrennt ist.

man kann es auch viel einfacher mit einem kleinen endlichen Automaten und INTERVAL.h machen, indem man im Automat die Intervalzeit ändert.
Hab gerade aber den Code nicht zur Hand