Problem with while-loop

Hi,

I think I've made a mistake, but cant find it after watching the code over and over again, maybe you can help.

What I want:
I have a temperature sensor, a RTC module and a LCD Display (16x2) over 74hc595

I would like to have 2 screens on the LCD, changing every x seconds.

Screen 1:
TEXT
Temperature - Time

Screen 2:
Date
Temperature - Time

I cant get it switching to screen 2. And I want the temperature updated during displaying the screens. Thats why I tried to do it with a while loop.

Here is my while code inside of the loop:

var1 = 0;
while(var1 < 2) {
  lcd1.setCursor(0, 0);
   lcd1.print(" TEXT ");

      // ------------------ Temp Sensor -----------------------
        byte i;
        byte present = 0;
        byte type_s;
        byte data[12];
        byte addr[8];
        float celsius, fahrenheit;
        
        if ( !ds.search(addr)) {
          //Serial.println("No more addresses.");
          //Serial.println();
          ds.reset_search();
          return;
        }
        
        //Serial.print("ROM =");
        for( i = 0; i < 8; i++) {
          //Serial.write(' ');
          //Serial.print(addr[i], HEX);
        }
      
        if (OneWire::crc8(addr, 7) != addr[7]) {
            return;
        }
        Serial.println();
       
        // the first ROM byte indicates which chip
        switch (addr[0]) {
          case 0x10:
            type_s = 1;
            break;
          case 0x28:
            type_s = 0;
            break;
          case 0x22:
            type_s = 0;
            break;
          default:
            return;
        } 
      
        ds.reset();
        ds.select(addr);
        ds.write(0x44, 1);        // start conversion, with parasite power on at the end
        
        delay(1000);     // maybe 750ms is enough, maybe not
        
        present = ds.reset();
        ds.select(addr);    
        ds.write(0xBE);         // Read Scratchpad
      
        for ( i = 0; i < 9; i++) {           // we need 9 bytes
          data[i] = ds.read();
        }
      
        int16_t raw = (data[1] << 8) | data[0];
        if (type_s) {
          raw = raw << 3; // 9 bit resolution default
          if (data[7] == 0x10) {
            // "count remain" gives full 12 bit resolution
            raw = (raw & 0xFFF0) + 12 - data[6];
          }
        } else {
          byte cfg = (data[4] & 0x60);
          // at lower res, the low bits are undefined, so let's zero them
          if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
          else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
          else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
          //// default is 12 bit resolution, 750 ms conversion time
        }
        celsius = (float)raw / 16.0;
        fahrenheit = celsius * 1.8 + 32.0;
      
      // ------------------------- Temp Sensor Ende ----------------------------



  lcd1.setCursor(0, 1); 
    lcd1.print(celsius);
    lcd1.print((char)223);
    lcd1.print(' ');
    printTime(local, tcr -> abbrev);
    var1++;
}

// ------------------ LCD Ausgabe 1 -----------------------

// ------------------ LCD Ausgabe 2 -----------------------
var2 = 0;
while(var2 < 2) {
  lcd1.setCursor(0, 0);
   printDate(local, tcr -> abbrev);
   
      // ------------------ Temp Sensor -----------------------
        byte i;
        byte present = 0;
        byte type_s;
        byte data[12];
        byte addr[8];
        float celsius, fahrenheit;
        
        if ( !ds.search(addr)) {
          //Serial.println("No more addresses.");
          //Serial.println();
          ds.reset_search();
          return;
        }
        
        //Serial.print("ROM =");
        for( i = 0; i < 8; i++) {
          //Serial.write(' ');
          //Serial.print(addr[i], HEX);
        }
      
        if (OneWire::crc8(addr, 7) != addr[7]) {
            return;
        }
        Serial.println();
       
        // the first ROM byte indicates which chip
        switch (addr[0]) {
          case 0x10:
            type_s = 1;
            break;
          case 0x28:
            type_s = 0;
            break;
          case 0x22:
            type_s = 0;
            break;
          default:
            return;
        } 
      
        ds.reset();
        ds.select(addr);
        ds.write(0x44, 1);        // start conversion, with parasite power on at the end
        
        delay(1000);     // maybe 750ms is enough, maybe not
        
        present = ds.reset();
        ds.select(addr);    
        ds.write(0xBE);         // Read Scratchpad
      
        for ( i = 0; i < 9; i++) {           // we need 9 bytes
          data[i] = ds.read();
        }
      
        int16_t raw = (data[1] << 8) | data[0];
        if (type_s) {
          raw = raw << 3; // 9 bit resolution default
          if (data[7] == 0x10) {
            // "count remain" gives full 12 bit resolution
            raw = (raw & 0xFFF0) + 12 - data[6];
          }
        } else {
          byte cfg = (data[4] & 0x60);
          // at lower res, the low bits are undefined, so let's zero them
          if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
          else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
          else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
          //// default is 12 bit resolution, 750 ms conversion time
        }
        celsius = (float)raw / 16.0;
        fahrenheit = celsius * 1.8 + 32.0;
      
      // ------------------------- Temp Sensor Ende ----------------------------
   
  lcd1.setCursor(0, 1); 
    lcd1.print(celsius);
    lcd1.print((char)223);
    lcd1.print(' ');
    printTime(local, tcr -> abbrev);
    var2++;
}

// ------------------ LCD Ausgabe 2 -----------------------

I would recommend:

  1. Split your displaying code into 2 functions that just updates the screen - one for each display.
  2. Have a variable in your main loop that defines which screen should be displayed.
  3. Constantly update your sensor readings in your main loop
  4. Watch millis() to decide when to change the displayed screen variable.

Something like (in rough pseudo code):

Record time now
Set displayVar 0
Forever:
  Get Sensor Readings

  If displayVar is 0 
    display screen 1
  else 
    display screen 2

  If time now - time recorded is greater than 2000
    set displayVar to 1 - displayVar (<- inverts it; 1 becomes 0, 0 becomes 1)
    record time now

Sounds good! :slight_smile:

Now I have to figure out how to write a function :wink:

redbear79:
Sounds good! :slight_smile:

Now I have to figure out how to write a function :wink:

I think you have to make it this way.

Always out of the void loop

void TextTempTime() {

your_code
}

void DateTempTime() {

your_code
}

And in your void loop () something like

if (ShowScreen==1) {
TextTempTime();
ShowScreen=0;
}

else {
DateTempTime();
ShowScreen=1;
}

Remember you will have to add some delay somewhere, I don't know how to work with LCD but you need to define how many time the screen will be displayed.

Also a good idea would be to change screen, not according to a variable, but perhaps by checking the seconds. From 0 to 14 Screen1, From 15 to 29 Screen2, From 30 to 44 Screen1, From 45 to 59 Screen2, that way you know that always at x time you will see x screen.

It doesnt have to be on the second...

I use the LCD just like the print to serial monitor...

instead of Serial.print("Test") just lcd.print("Test").

You just need to say where to start (like: lcd1.setCursor(0, 0); for column 1 row 1 or lcd1.setCursor(0, 1); for column 1 and row 2)

But I still want to know why he doesnt jumps in the second while loop...

int ShowVar1;
int ShowVar2;

void setup() {
}

void loop() {

ShowVar1 = 0;
ShowVar2 = 0;

while(ShowVar1 < 2) 
{
 lcd.print("Test 1");
 ShowVar1++;
}

while(ShowVar2 < 2) 
{
 lcd.print("Test 2");
 ShowVar2++;
}

}

That just doesnt make a sense...

Can you describe what you think should happen when you run that code and what actually happens ?

Programm starts,

loop starts

while loop 1 runs until <2 is reached
while loop 2 runs until <2 is reached

loop starts again

while loop 1 runs....

i just figured out it does in this simple example, but not with my code. seems to be a problem with the temp sensor script which prevents the while-loop from being executed...

what happens: loop starts, temperature gets updated ever second... but loop 2 doesnt starts (other text in display). it just loops in while loop 1.

In that case you need to use local variables as your loop counters rather than global ones, and I'd suggest using FOR loops rather than WHILE loops.

got it, there was a problem with the onewire lib together with that script.

works fine with the DallasTemperature Lib now. :slight_smile:

Wrote a function for printing on lcd and i set adress and resolution in setup now.

Thx for your help and suggestions! Wouldnt work without.