If statement evaluates to false, code still runs

Hello to everyone,
I have been out of the void loop() for quite a while doing other things but have recently dusted off the old IDE and am working on a problem. I am prepared to be embarrassed by the answer but I can't figure out why my attached BWOD routine is not working. The if argument evaluates to false but the code after it is still running. The code is not very compact because I have expanded terms and added print statements in an attempt to hunt down my error. Please take a look and kick me where it counts.
Thank you.
Also, has there been any word on Robin2? I fear the worst but hope he is ok.
Tom

#define usbSerial Serial

int getBlinkInterval();  //get env vbl to set blink rate
unsigned long blinkInterval;

unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long previousBlinkMillis = 0;  
const int checkEnvVblInterval = 1000;  

void setup() {
  usbSerial.begin(115200);
}

void loop() {
  currentMillis = millis();
  blinkInterval = getBlinkInterval();
  usbSerial.print("blinkInterval: ");
  usbSerial.println(blinkInterval);
}

int getBlinkInterval() {
  usbSerial.print("current: ");
  usbSerial.println(currentMillis);
  usbSerial.print("previous: ");
  usbSerial.println(previousBlinkMillis);
  usbSerial.print("checkENVVBL; ");
  usbSerial.println(checkEnvVblInterval);
  usbSerial.print("current - previous: ");
  usbSerial.println(currentMillis - previousBlinkMillis);
  usbSerial.println(currentMillis - previousBlinkMillis >= checkEnvVblInterval);
  unsigned long result = currentMillis - previousBlinkMillis;
  usbSerial.print("result: ");
  usbSerial.println(result);
  if (result >= checkEnvVblInterval)  //(currentMillis - previousBlinkMillis >= checkEnvVblInterval)
  {
    usbSerial.println("checking Env Vbl");
    previousBlinkMillis = currentMillis;

    return (999);
  } else {
    return (0);
  }
}

Are you sure? Why do you think that?

I don't know what that does, I don't know what you think it does, but I suspect that it does something else.

Thanks Perry,
The goal was to print the result of the inequality. It seems to evaluate to false yet instead of returning, the underlying code runs.
I have a blind spot and I just can't see where I'm making my mistake.

Is this bit shifting?

I'm not the best at reading other people's code, as I read it eventually it will be true, after 1000 milliseconds.

That print line is nonsense, I don't know what it will do, and I don't know it it will mess what your code does.

It's not anything sensible.

Yeah, I know it is nonsense. I added it as a diagnostic to see what the argument to the if was returning.

I realize it would have to be >>= but it's unclear what the compiler would do here if its treating it as an operator assignment rather than text.

Could it be doing something to the variable

prior to being evaluated in the 'if' statement?

Fix the obvious problems first, then look deeper.

I'm going to stop now and let someone else have a look, maybe they can see something I can't.

I'll continue to follow and will reply if I think of anything helpful.

1 Like

I don't think so. I thought I was writing a simple blink without delay, which I have done a thousand times making this problem so frustrating. Like looking for the sugar bowl for half an hour and my wife walks in and points out that it is right in front of me. Or looking all over the house for my glasses only to realize they are on my head.

1 Like

Can you be more specific on what exactly happens? I am assuming you mean the code at the end, with return(999)?
If so, what happens?

this line runs: usbSerial.println("checking Env Vbl");
even though the if statement above it is false.

the expression within the print brackets is evaluated, it's a conditional, so type bool (because of operator precedence it's like (currentMillis - previousBlinkMillis) >= checkEnvVblInterval)

the Print class does not know how to print a bool (see what's defined) but it knows how to print an int and C++ has an implicit int promotion for bool where false is promoted into 0 and true is promoted into 1. So The Print method that will be called is the one taking an int as parameter and you should see 0 or 1 on the Serial monitor.

1 Like

Yes, 0 (false) and it prints the env vbl anyway

Ok, then maybe you should print the values of result and checkEnvVblInterval (just above or after usbSerial.println("checking Env Vbl"); )and see if the condition is indeed false?

so the code works, right

you should see tons of 0 and then a 1 and then tons of 0 again and a 1...

your code (cleaned up) is this

const unsigned long checkEnvVblInterval = 1000ul;

int getBlinkInterval() {
  static unsigned long previousBlinkMillis = 0;
  unsigned long currentMillis = millis();
  unsigned long result = currentMillis - previousBlinkMillis;
  if (result >= checkEnvVblInterval) {
    previousBlinkMillis = currentMillis;
    return 999;
  } else {
    return 0;
  }
}


void setup() {
  Serial.begin(115200);
}

void loop() {
  unsigned long blinkInterval = getBlinkInterval();
  Serial.print("blinkInterval: ");
  Serial.println(blinkInterval);
}

1 Like

below are a couple of iterations of the output. Notice that current-previous is less than 1000, the statement "checkENVBL prints.
The board is: * Feather-compatible dev board, powered by an STM32L4+ @ 120 MHz with 2MB of Flash and 640KB of RAM

blinkInterval: 0
current: 74128
previous: 74000
checkENVVBL; 1000
current - previous: 128
0
result: 128
blinkInterval: 0
current: 74129
previous: 74000
checkENVVBL; 1000
current - previous: 129
0
result: 129

That print statement is not part of your if statement

You will notice that this statement

is not being printed, as expected, since it is the one inside the if statement.

1 Like

Rule 0 of debugging!

What output do you get if you try this?