0

I use a double called delta and use that to turn off an LCD if delta is larger than the timeout threshold. Once that happens, delta is supposed to set to 0 and then other parts of the program run. However, delta continues to increment and I'm not sure why.

This is causing a problem because delta is used to determine if the device should "sleep". So when I try to wake up the device via button click, delta is always way past the timeout threshold and the device immediately goes back to sleep.

Any thoughts as to why? Thanks in advance.

#include <M5StickC.h>

double BUTTON_PRESS_NEXT_PRESS_TIME= .5; //Time in seconds
double MINIMUM_BUTTON_PRESS_TIME = .05; //Time in seconds
int BUTTON_PRESS_SLEEP = 3; //Time in seconds
int SCREEN_TIMEOUT = 5;
int count;

static int pressCount = 1;
static int nextPress= 1;

static bool buttonIsPressed;

void setup(void) {
  buttonIsPressed = false;
  M5.begin();
  M5.Lcd.setRotation(0);
  M5.Lcd.fillScreen(TFT_BLACK);
  M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);

  // Datum is middle centre
  M5.Lcd.setTextDatum(MC_DATUM);
  M5.Axp.ScreenBreath(100);
  
  updateScreen();      
}

void updateScreen() {
   char tmp[12];
  
  // Datum is middle centre
  M5.Lcd.setTextDatum(MC_DATUM);
  M5.Lcd.drawString(dtostrf(pressCount,4,0,tmp), 80,60,6);
  M5.Lcd.drawString(dtostrf(nextPress,3,0,tmp), 80,100,6);
}

static void evaluatePress(double d) {
   // Evaluate press 
  if (d >= BUTTON_PRESS_NEXT_PRESS_TIME) {
    nextPress++;
    pressCount = 1;
        
    if (nextPress == 19) {
      nextPress= 1;
    }
  }
  else if (d >= MINIMUM_BUTTON_PRESS_TIME && d < BUTTON_PRESS_NEXT_PRESS_TIME) {
    pressCount++;
  }
    
  updateScreen();
}

void sleepLoop() {
  bool bIsPressed = false;
  Serial.println("Sleep 1");
  while(1) {
    Serial.println("Sleep 2");
    if (digitalRead(M5_BUTTON_HOME) == LOW && !bIsPressed) {
      bIsPressed = true;
    }

    if (digitalRead(M5_BUTTON_HOME) == HIGH && bIsPressed){
      Serial.println("BREAKY BREAKY");
      M5.Axp.ScreenBreath(100);

      break;
    }
  }
}

void awakeLoop() {  
  double delta;
  double old_time;
  double current_time;

  Serial.println("Awake 1");
  
  while(1) {
    Serial.println("Awake 2");
     //Calculate delta time
    old_time = current_time;
    current_time =  millis();
    delta = delta + (current_time - old_time)/1000;

    if (digitalRead(M5_BUTTON_HOME) == LOW && !buttonIsPressed) {
      buttonIsPressed = true; 
      delta = 0;
    }

    if(digitalRead(M5_BUTTON_HOME) == HIGH && buttonIsPressed) {
      buttonIsPressed = false;
      evaluatePress(delta);
      delta=0;
    }
 
    if(delta > SCREEN_TIMEOUT && !buttonIsPressed) {
      Serial.println(delta);
      Serial.print("BREAK AWAKE");
      Serial.println(M5.Axp.ScreenBreath(0));
      count = 0;
      break;
    }
    else {
      count++;
    }
  }
  
  delta = 0;
}

void loop() {
  awakeLoop();
  sleepLoop();
}
  • 1
    Sorry, but that's a crazy way of doing a screen timeout. You don't need delta and you certainly don't want it to be a double... Just record current_time = millis() when an action happens and break when (millis() - current_time) > 5000. – Majenko Oct 18 at 14:47
  • Thanks @Majenko. I've stripped out some code so that the question focuses more directly on the problem. I think I can do what you suggested though and will give it a try. What's wrong with a double? – Kyle Oct 19 at 0:57
  • @Kyle double needs floating point operations for every calculation, which the Arduino does not support in its hardware. Thus this has to be done in software, which is very computation expensive. So a general rule is, to only use a floating point type (float or double), when it is really necessary. millis() uses unsigned long, so why not using the same for the variables? – chrisl Oct 19 at 6:32
1

Here:

void awakeLoop(){  
  double delta;
  // The rest of the function body...
  delta = 0;
}

delta is being defined as a variable local to the function awakeLoop() and with automatic storage. This means the variable is created whenever the program enters the function, is not implicitly initialized, and is destroyed when the function returns.

The last statement delta = 0; has no effect, as it is setting a variable that is going to be destroyed right away. The compiler most likely got rid of it.

You most likely want the variable to retain its value across invocations of the function. For this to be the case, it has to be either global (defined outside the function) or local with the static qualifier. In both cases, it will have static storage, i.e. its lifetime will be the whole program run. Also, if you fail to explicitly initialize it, the compiler will implicitly initialize it to zero.

| improve this answer | |
  • Thanks @Edgar Bonet. The problem that I'm having is that delta does not actually get set to 0 or destroyed. I know that I shouldn't/don't need to set delta to 0 at the end of the loop, but I added that line because the program is not acting as I'd expect. The line that prints out delta, right below "Brake awake" always prints out a value that I would expect if the loop were to run continually. – Kyle Oct 19 at 1:08
  • @Kyle: That value is meaningless, as delta has not been initialized. Whether it matches your expectations or not is just chance, and you should not count on it. – Edgar Bonet Oct 19 at 8:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.