While function not repeatedly checking state

Hi All, I am relatively new to arduino. Thought I would at least be able to understand the while function though!
My code is attached.
Basically I am using a very simple while code to detect the state of a pin. While that pin is low, I want to turn off a relay, by outputting HIGH and the while the pin is high, i want to turn on the relay with a LOW output.
The input signal is generated via a push button, which sends signals of either 0v or 5v.
If i press the button once, it sends a low signal and turns on the relay, but does not then turn it off once the pin state changes back to its previous.
I need to use while, as I want to develop the code to wait for a specific signal before running the rest of the code.
Any help would be much appreciated.
While_Low-While_High.ino (627 Bytes)

post your code in code tags.

  while (val == LOW)
  {
    digitalWrite(ledPin, HIGH);
    Serial.println("VAL = LOW");
  }

Once the while loop has been entered the value of val will never change so the while loop will never end

Thanks for your reply. How can I get it to end the while loop?

You don't reread the button state within the whlie loop. Therefore val will never change in the while loop.

What has to be done before loop starts should be done in setup().

Do something in the while loop that changes the value of val, such as a digitalRead()

To be honest, if you are using a "while" loop, you are almost certainly doing it wrong. :roll_eyes:

I can't see your code as you have not posted it into the thread by following the forum instructions, but you should simply be checking your input in the loop and taking action - or not taking action - depending on that criterion and using one or more "flag" variables to decide whether you should be doing something else instead. :grin:

Please.

int val = 0;
const int buttonPin = 29;
const int ledPin = 22;
const int relayPin = 20;

void setup() {

pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
pinMode(relayPin, OUTPUT);
Serial.begin(9600);
digitalWrite(20, HIGH); //Output Pins set to High to avoid floating voltage signals
digitalWrite(22, HIGH);
}

void loop() {
val = digitalRead(buttonPin);
while (val == LOW)
{
digitalWrite(ledPin, HIGH);
Serial.println("VAL = LOW");
}
val = digitalRead(buttonPin);
while (val == HIGH)
{
Serial.println("VAL = HIGH");
digitalWrite(ledPin, LOW);
}
}

Better, but still no code tags

See How to get the best out of this forum

Sorry, I'm so new, I don't even know how to do that. Will have a look at the instructions

int val = 0;
const int buttonPin = 29;
const int ledPin = 22;
const int relayPin = 20;


void setup() {

  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(relayPin, OUTPUT);
  Serial.begin(9600);
  digitalWrite(20, HIGH);  //Output Pins set to High to avoid floating voltage signals
  digitalWrite(22, HIGH);
}

void loop() {
  val = digitalRead(buttonPin);
  while (val == LOW)
  {
    digitalWrite(ledPin, HIGH);
    Serial.println("VAL = LOW");
  }
  val = digitalRead(buttonPin);
  while (val == HIGH)
  {
    Serial.println("VAL = HIGH");
    digitalWrite(ledPin, LOW);
  }
}
1 Like

Please!
You can edit your post: Mark your code and click on the </> button above.

P.S. too late :wink: - Thanks.

But your problem was already addressed in earlier posts.

It's such a common noob mistake, there should be a name for it, although this isn't a classic example.

Ppl think that

  val = digitalRead(buttonPin);

establishes an all-time linkage between the port pin buttonPin and the variable val.

I'm sure there are constructs that do this, at the very least in other languages.

But here it is step-by-step procedural, so val gets the value at the pin when execution goes through that line of code; if the pin changes, val does not track it. Only another digitalRead, however it comes up in the code, will change that.

I see it alla time, can't remember the classic, but ISTR it involved # define somehow.

a7

Why not this?

void loop() {
  static int lastval = !digitalRead(buttonPin);
  int val = digitalRead(buttonPin);

  if (val != lastval)
  {
    if (val == LOW)
    {
      digitalWrite(ledPin, HIGH);
      Serial.println("VAL = LOW");
    }
    else
    {
      digitalWrite(ledPin, LOW);
      Serial.println("VAL = HIGH");
    }
    lastval = val;
  }
}

How does that code record the last value when you are reading the not of the current value.

or
Press button relay on, release button relay off.

void loop() {
    if ( digitalRead(buttonPin) )
    {
      digitalWrite(ledPin, HIGH);
      Serial.println("VAL = LOW");
    }
    else
    {
      digitalWrite(ledPin, LOW);
      Serial.println("VAL = HIGH");
    }
}

It is a static so lastval is only initialized once. I initialized lastval with the not of the input to force the code to set the LED the first time through loop(). This limits scope of val and lastval to loop().

1 Like