do while issue

hi all,
i don't understand why the following code doesn't work:

const int button2 = 6;
const int led3 = 4;

void setup() {
pinMode(button2, INPUT);
pinMode(led3, OUTPUT);
digitalWrite(led3, LOW);
Serial.begin(9600);
}

void loop() {
int reading2 = digitalRead(button2);
if (reading2 == 1) {
do {
digitalWrite(led3, HIGH);
delay(100);
digitalWrite(led3, LOW);
delay(100);
int reading2 = digitalRead(button2);
Serial.println(reading2);
}
while(reading2 == 1);
}
}

one button, one led...
the monitor see the button (reading2) but it doesn't leave the loop.

thanks for any help.

v.

int reading2 = digitalRead(button2);

This line creates a new, different, variable called reading2, which only exists within the curly braces of the loop.

The while test will look at the original, reading2 variable, which not been changed after you read it the first time. Therefore, it will never become false and the loop will not exit.

hi michinyon,
sorry for my stupidity but even with another variable it doesn't work for me.

const int button2 = 6;
const int led3 = 4;
int reading2;
int toto;

void setup() {
  pinMode(button2, INPUT);
  pinMode(led3, OUTPUT);
  digitalWrite(led3, LOW);
  Serial.begin(9600);
}

void loop() 
{
  int reading2 = digitalRead(button2);
  if (reading2 == 1) 
  {
    do 
    {
      blink3();
      toto = digitalRead(button2);
      Serial.println(toto);
    }
     while (toto == 0);
  }  
} 

void blink3()
{
  digitalWrite(led3, HIGH);
  delay(100);
  digitalWrite(led3, LOW);
  delay(100);
}

what is wrong?

it doesn't work for me.

It does something. You have not explained what.

You expect it to do something. You have not explained what.

You have something connected to the input pin. You have not explained what, or how the rest of whatever it is is wired.

You can't seriously expect help.

dear PaulS,
I thought it was sufficently simple to understand.
as I said 'one button, one led'.
when button is pressed, the led blink until button is pressed again.
that's all.
saying 'it doesn't work' means the 2nd press on the button doesn't stop the led.
any idea?

Well your second version solves one problem. What exactly does it do now ?

If you press the button and the first digitalRead( ) is HIGH. [ You are assuming that is equal to 1 ]

then the do...while statement will run at least once. When the blink3( ) has been done the first time, then the loop will continue for as long as it sees that the button is NOT pressed ( toto==0 ).

This seems to be the OPPOSITE logic of what you were trying to do in the original post. Is that what you intended ?

Anyway, the construct

if ( some condition ) do { something } while ( some condition )

is exactly the same as

while ( some condition ) { do something }

except it is more verbose and requires the code to detect and compare the condition, twice.

with the code I posted:

  • led is off
  • one clic on the button -> led blinks
  • one more clic on the button -> led still blinks

in serial monitor, when button is pressed when the led blinks, toto is equal to 1.

if I put while (toto == 1) to exit the loop:

  • led is off
  • led blinks when button is pressed and is off when button is released

I would like:

  • led off
  • one clic -> led blinks
  • one clic more -> led off

I would like:

  • led off
  • one clic -> led blinks
  • one clic more -> led off

You need to detect when the button becomes pressed rather than when it is pressed. Look at the StateChangeDetection example in the IDE to see how to do it.

hi UKHeliBob,

you are the one! lastButtonState is the key.

many thanx!

const int button2 = 6;
const int led3 = 4;

int reading2 = 0;
int lastreading2 = 0;
int counter2 = 1;

void setup() 
{
  pinMode(button2, INPUT);
  pinMode(led3, OUTPUT);
  digitalWrite(led3, LOW);
  Serial.begin(9600);
}

void loop() 
{
  reading2 = digitalRead(button2);
  if (reading2 != lastreading2) 
  {
    if (reading2 == 1)
    {
      counter2++;
      Serial.println("on");
    }
    else
    {
      Serial.println("off");
    }
    delay(50);
  }
  lastreading2 = reading2;  
  
  if (counter2 %2 == 0)
  {
    blink3();
  }
  else
  {
    digitalWrite(led3, LOW);
  }
} 

void blink3()
{
  digitalWrite(led3, HIGH);
  delay(100);
  digitalWrite(led3, LOW);
  delay(100);
}

I am glad it works. Now improve it by writing it without any delay()s that block reading the input for a fifth of a second each time loop() repeats. Learn how to do it now before the use of delay() is ingrained in your programming.

UKHeliBob:
I am glad it works. Now improve it by writing it without any delay()s that block reading the input for a fifth of a second each time loop() repeats. Learn how to do it now before the use of delay() is ingrained in your programming.

See the 'Blink without delay' example in the examples page of this site, or in the IDE.

if I put while (toto == 1) to exit the loop:

Just to be clear, in the do...while loop construct, if the condition at the end evaluates to true, then the loop is repeated again. If the condition is false, the loop exits.