Problem with DS18B20 refrech in switch case statement

Hello.

This is my first post here, and english isn’t my first language so please forgive me :).
I have a problem with my code.

First my hardware:

  • NodeMCU
  • two DS18B20 sensors attatched to pin D5 and 4k7ohm resistor to 3v
  • OLED display 128x64 ssd1306 i2c
  • momentary switch connected to pin D6 witch 10kohm resistor.

The problem is my temperature won’t refresh. Readings do update just if I cycle trough the cases. I’ve tried using while loop inside case 1 but code stucks there. Could someone push me into right direction?

This is my code:

#include <Wire.h>
#include <SPI.h>
//#include <SimpleTimer.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
//SimpleTimer timer;
#define ONE_WIRE_BUS D5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
uint8_t sensor1[8] = { 0x28, 0x00, 0xF9, 0xD5, 0x13, 0x19, 0x01, 0x65 };
uint8_t sensor2[8] = { 0x28, 0x47, 0x43, 0xDD, 0x13, 0x19, 0x01, 0x7B };

float temp_1;
float temp_2;

const int buttonPin = 12;
boolean buttonState = LOW;
boolean lastButtonState = LOW;
int Display = 1;

unsigned long lastDebounceTime = 0;
long debounceDelay = 50;

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup(){
   
  pinMode(buttonPin, INPUT);
 
  Serial.begin(9600);
  DS18B20.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  Serial.println(Display);
  display.setRotation(1);
  display.clearDisplay();
  displayAnimation();
  display.display();
  

}

void loop(void){
  
Serial.println(Display);
  
  int reading = digitalRead(buttonPin);

  if (reading != lastButtonState) {
    lastDebounceTime = millis();
    }
    if ((millis() - lastDebounceTime) > debounceDelay) {
      if (reading != buttonState) {
      
      buttonState = reading;
        if(reading == HIGH){
        Display ++;
        display.clearDisplay();
        
          if (Display > 3){
          Display = 1;
          } 
             
        Serial.println(Display);
      

        
        switch(Display){
          
        case 1:
        while(Display == 1){

        DS18B20.requestTemperatures();
  
        temp_1 = DS18B20.getTempC(sensor1); 
        temp_2 = DS18B20.getTempC(sensor2);
        Serial.println(temp_1);
        Serial.println(temp_2);
        Serial.println(Display);
                display.clearDisplay();  
        display.drawLine(0,32,64,32,WHITE);
        display.drawLine(0,96,64,96,WHITE);
        display.drawLine(0,64,64,64,WHITE);

        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(2, 9);
        display.println(temp_1);

        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(2, 41);
        display.println(temp_2);

        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(2, 73);
        display.println("--.--");
 
        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(2, 105);
        display.println("--.--");
        display.display();
        delay(1000);
        continue;
        }
         
        break;    
       
        case 2:
        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(2, 41);
        display.println("ekran_2");
        display.display(); 
        break;
        
        case 3:
        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(2, 41);
        display.println("ekran_3");
        display.display(); 
        break;
        
      }
     }
    }    
   }    
   
 lastButtonState = reading;
}

Also when I restart NodeMCU, code stops after animation in void setup. Is there a way to move sequention to case 1: immediately after animation without pressing button?

inside case 1 you have a while() loop that will always be true so you will never get out of it.

Use the auto format feature of the IDE (Ctrl-T) so make your code easier to see and understand. It will properly indent things for you.

Thanks for tip, and quick reply:)

While() loop was only for experimenting purpose. When there is only case 1, program will only execute once. My question is, is there a way to refresh temperature readings inside case 1, or somehow exit while() loop after pressing button?

Updated code:

#include <Wire.h>
#include <SPI.h>
//#include <SimpleTimer.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
//SimpleTimer timer;
#define ONE_WIRE_BUS D5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
uint8_t sensor1[8] = { 0x28, 0x00, 0xF9, 0xD5, 0x13, 0x19, 0x01, 0x65 };
uint8_t sensor2[8] = { 0x28, 0x47, 0x43, 0xDD, 0x13, 0x19, 0x01, 0x7B };

float temp_1;
float temp_2;

const int buttonPin = 12;
boolean buttonState = LOW;
boolean lastButtonState = LOW;
int Display = 1;

unsigned long lastDebounceTime = 0;
long debounceDelay = 50;

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {

  pinMode(buttonPin, INPUT);

  Serial.begin(9600);
  DS18B20.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  Serial.println(Display);
  display.setRotation(1);
  display.clearDisplay();
  displayAnimation();
  display.display();
  delay(100);

  display.clearDisplay();
  display.drawLine(0, 32, 64, 32, WHITE);
  display.drawLine(0, 96, 64, 96, WHITE);
  display.drawLine(0, 64, 64, 64, WHITE);

  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(2, 9);
  display.println(temp_1);

  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(2, 41);
  display.println(temp_2);

  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(2, 73);
  display.println("--.--");

  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(2, 105);
  display.println("--.--");
  display.display();
}

void loop(void) {

  Serial.println(Display);

  int reading = digitalRead(buttonPin);

  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {

      buttonState = reading;
      if (reading == HIGH) {
        Display ++;
        display.clearDisplay();

        if (Display > 3) {
          Display = 1;
        }

        Serial.println(Display);



        switch (Display) {

          case 1:
            DS18B20.requestTemperatures();

            temp_1 = DS18B20.getTempC(sensor1);
            temp_2 = DS18B20.getTempC(sensor2);
            Serial.println(temp_1);
            Serial.println(temp_2);
            Serial.println(Display);
            display.clearDisplay();
            display.drawLine(0, 32, 64, 32, WHITE);
            display.drawLine(0, 96, 64, 96, WHITE);
            display.drawLine(0, 64, 64, 64, WHITE);

            display.setTextSize(2);
            display.setTextColor(WHITE);
            display.setCursor(2, 9);
            display.println(temp_1);

            display.setTextSize(2);
            display.setTextColor(WHITE);
            display.setCursor(2, 41);
            display.println(temp_2);

            display.setTextSize(2);
            display.setTextColor(WHITE);
            display.setCursor(2, 73);
            display.println("--.--");

            display.setTextSize(2);
            display.setTextColor(WHITE);
            display.setCursor(2, 105);
            display.println("--.--");
            display.display();
            delay(1000);
            break;

          case 2:
            display.setTextSize(2);
            display.setTextColor(WHITE);
            display.setCursor(2, 41);
            display.println("screen_2");
            display.display();
            break;

          case 3:
            display.setTextSize(2);
            display.setTextColor(WHITE);
            display.setCursor(2, 41);
            display.println("screen_3");
            display.display();
            break;

        }
      }
    }
  }

  lastButtonState = reading;
}

Look at the tutorial Several Things at a Time to see how to structure your code so you are constantly iterating over loop() and only reacting to changes.

Thank you very much blh64! :slight_smile: It works! With one little glitch. On screen_1 DallasTemperature library mesure temperatures from sensors. It takes time, so when I’m on this screen I need to hold button until whole loop execute to switch screen. Is there a way to avoid this?

Updated code:

#include <Wire.h>
#include <SPI.h>
//#include <SimpleTimer.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
//SimpleTimer timer;
#define ONE_WIRE_BUS D5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
uint8_t sensor1[8] = { 0x28, 0x00, 0xF9, 0xD5, 0x13, 0x19, 0x01, 0x65 };
uint8_t sensor2[8] = { 0x28, 0x47, 0x43, 0xDD, 0x13, 0x19, 0x01, 0x7B };

float temp_1;
float temp_2;

const int buttonPin = 12;

int buttonState = LOW;
int lastButtonState = LOW;
int Display = 0;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;


Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  Serial.begin(9600);
  Serial.println("Starting TEST_OLED_5.3");
  pinMode(buttonPin, INPUT);
  DS18B20.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.setRotation(1);
}

void loop() {
  readButton();
  displayScreen_0();
  displayScreen_1();
  displayScreen_2();
  displayScreen_3();
}

void readButton() {
  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (reading == HIGH) {
        Display ++;
        display.clearDisplay();
        if (Display > 3) {
          Display = 1;
        }
      }
    }
  }
  lastButtonState = reading;
}

void displayScreen_0 () {
  if (Display == 0) {
    displayAnimation();
    Display++;
  }
}

void displayScreen_1 () {
  if (Display == 1) {
    DS18B20.requestTemperatures();
    temp_1 = DS18B20.getTempC(sensor1);
    temp_2 = DS18B20.getTempC(sensor2);
    Serial.println(temp_1);
    Serial.println(temp_2);
    Serial.println(Display);
    display.clearDisplay();
    display.drawLine(0, 32, 64, 32, WHITE);
    display.drawLine(0, 96, 64, 96, WHITE);
    display.drawLine(0, 64, 64, 64, WHITE);

    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(2, 9);
    display.println(temp_1);

    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(2, 41);
    display.println(temp_2);

    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(2, 73);
    display.println("--.--");

    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(2, 105);
    display.println("--.--");
    display.display();
  }
}

void displayScreen_2() {
  if (Display == 2) {
    Serial.println(Display);
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(2, 9);
    display.println("screen2");
    display.display();
  }
}

void displayScreen_3() {
  if (Display == 3) {
    Serial.println(Display);
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(2, 9);
    display.println("screen3");
    display.display();
  }
}

Look at the WaitForConversion example that comes with the library. It shows you how to do a non-blocking request to read the temperatures.

Once again, thank you very much :slight_smile: Everything is working excellect now. Even blynk server and wi-fi clock :slight_smile:

 #include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <time.h>

#define BLYNK_PRINT Serial
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
//SimpleTimer timer;
#define ONE_WIRE_BUS D5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
uint8_t sensor1[8] = { 0x28, 0x00, 0xF9, 0xD5, 0x13, 0x19, 0x01, 0x65 };
uint8_t sensor2[8] = { 0x28, 0x47, 0x43, 0xDD, 0x13, 0x19, 0x01, 0x7B };

char auth[] = "XXX";

char ssid[] = "XXX";
char pass[] = "XXX";

float temp_1;
float temp_2;

const int buttonPin = 12;

int buttonState = LOW;
int lastButtonState = LOW;
int Display = 1;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

int timezone = 1 * 3600;
int dst = 0;

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

DeviceAddress tempDeviceAddress;

int  resolution = 12;
unsigned long lastTempRequest = 0;
int  delayInMillis = 0;

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.setRotation(1);
  displayAnimation();
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  pinMode(buttonPin, INPUT);
  WiFi.begin(ssid, pass);
  configTime(timezone, dst, "pool.ntp.org", "time.nist.gov");
  sensors.begin();
  sensors.getAddress(tempDeviceAddress, 0);
  sensors.setResolution(tempDeviceAddress, resolution);
  sensors.setWaitForConversion(false);
  sensors.requestTemperatures();
  delayInMillis = 750 / (1 << (12 - resolution));
  lastTempRequest = millis();
}

void loop() {
  readButton();
  displayScreen_1();
  displayScreen_2();
  displayScreen_3();
  Blynk.run();
  getSendData();
}

void readButton() {
  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (reading == HIGH) {
        Display ++;
        display.clearDisplay();
        if (Display > 3) {
          Display = 1;
        }
      }
    }
  }
  lastButtonState = reading;
}

void displayScreen_1 () {
  if (Display == 1) {
    if (millis() - lastTempRequest >= delayInMillis) {


      sensors.setResolution(tempDeviceAddress, resolution);
      sensors.requestTemperatures();
      delayInMillis = 750 / (1 << (12 - resolution));
      lastTempRequest = millis();

      sensors.requestTemperatures();
      temp_1 = sensors.getTempC(sensor1);
      temp_2 = sensors.getTempC(sensor2);
      display.clearDisplay();
      display.drawLine(0, 32, 64, 32, WHITE);
      display.drawLine(0, 96, 64, 96, WHITE);
      display.drawLine(0, 64, 64, 64, WHITE);

      display.setTextColor(WHITE);

      display.setTextSize(1);
      display.setCursor(0, 2);
      display.println("temp_1:");

      display.setCursor(0, 34);
      display.println("temp_2:");

      display.setCursor(0, 66);
      display.println("temp_3:");

      display.setCursor(0, 98);
      display.println("temp_4:");

      display.setTextSize(2);
      display.setCursor(0, 15);
      display.println(temp_1, 1);

      display.setCursor(0, 47);
      display.println(temp_2, 1);

      display.setCursor(0, 79);
      display.println("--.--");

      display.setCursor(0, 111);
      display.println("--.--");

      display.display();
    }
  }
}

void displayScreen_2() {
  if (Display == 2) {
    time_t now = time(nullptr);
    struct tm* p_tm = localtime(&now);

    Serial.print(p_tm->tm_mday);
    Serial.print("/");
    Serial.print(p_tm->tm_mon + 1);
    Serial.print("/");
    Serial.print(p_tm->tm_year + 1900);

    Serial.print(" ");

    Serial.print(p_tm->tm_hour);
    Serial.print(":");
    Serial.print(p_tm->tm_min);
    Serial.print(":");
    Serial.println(p_tm->tm_sec);

    // Clear the buffer.
    display.clearDisplay();

    display.setTextSize(3);
    display.setTextColor(WHITE);

    display.setCursor(0, 0);
    display.print(p_tm->tm_hour);
    //display.print(":");
    display.setCursor(0, 30);
    if ( p_tm->tm_min < 10)
      display.print("0");
    display.print(p_tm->tm_min);

    display.setTextSize(2);
    display.setCursor(0, 60);
    //display.print(".");
    if ( p_tm->tm_sec < 10)
      display.print("0");
    display.print(p_tm->tm_sec);

    display.setTextSize(1);
    display.setCursor(0, 90);
    display.print(p_tm->tm_mday);
    display.print("/");
    display.print(p_tm->tm_mon + 1);
    display.print("/");
    display.print(p_tm->tm_year + 1900);

    display.display();

    //delay(1000); // update every 1 sec
  }
}


void displayScreen_3() {
  if (Display == 3) {
    Serial.println(Display);
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(2, 9);
    display.println("screen3");
    display.display();
  }
}

void getSendData() {
  if (millis() - lastTempRequest >= delayInMillis) {
    sensors.setResolution(tempDeviceAddress, resolution);
    sensors.requestTemperatures();
    delayInMillis = 750 / (1 << (12 - resolution));
    lastTempRequest = millis();

    temp_1 = sensors.getTempC(sensor1);
    temp_2 = sensors.getTempC(sensor2);
    Blynk.virtualWrite(5, temp_1); //virtual pin V5 indoor temp
    Blynk.virtualWrite(6, temp_2); //virtual pin V6 outdoor temp
  }
}