Break out of a fast while loop with digitalRead?

I have the following while loop…

while(1 == 1){


    index = 1;
    buttonState = digitalRead(buttonPin);  
    if (buttonState == HIGH) { break; } 
    delayMicroseconds(200);
    

    index = 2;
    buttonState = digitalRead(buttonPin);  
    if (buttonState == HIGH) { break; } 
    delayMicroseconds(200);
    

    index = 3;
    buttonState = digitalRead(buttonPin);  
    if (buttonState == HIGH) { break; }     
    delayMicroseconds(200);


    index = 4;
    buttonState = digitalRead(buttonPin);  
    if (buttonState == HIGH) { break; } 
    delayMicroseconds(200);


    index = 5;
    buttonState = digitalRead(buttonPin);  
    if (buttonState == HIGH) { break; } 
    delayMicroseconds(200);


    index = 6;
    buttonState = digitalRead(buttonPin);  
    if (buttonState == HIGH) { break; } 
    delayMicroseconds(200);
    

    index = 7;
    buttonState = digitalRead(buttonPin);  
    if (buttonState == HIGH) { break; } 
    delayMicroseconds(200);
    

    index = 8;
    buttonState = digitalRead(buttonPin);  
    if (buttonState == HIGH) { break; }     
    delayMicroseconds(200);


    index = 9;
    buttonState = digitalRead(buttonPin);  
    if (buttonState == HIGH) { break; } 
    delayMicroseconds(200);


    index = 10;
    buttonState = digitalRead(buttonPin);  
    if (buttonState == HIGH) { break; } 
    delayMicroseconds(200);
}

I’m trying to break out of it when arduino detects a fast 50 microsecond pulse on the button pin; however what with no means to read the button pin in the 200 microsecond delays and the generally slow digitalRead times, the code only seems to break out once in every ten or so times I send the 50 microsecond pulse.

I don’t want to use interrupts if I can help it as my code makes use of SPI to write to a DAC and I don’t want that to get messed up if interrupted while writing to it however I still want to reliably exit this while loop when a digitalRead pin goes high.

I’m a bit stuck so any suggestions on what I could try would be very much appreciated.

Thanks in advance

have you thought about using micros()?

I hadn't heard of that one before, it's definitely an interesting one but I can't imagine how it could break me out of my while loop.

Since he’s not even checking the length of the pulse, he could just remove the delayMicroseconds() calls and I think his code would work…

I’m not saying that’s an advisable way to design a program (ie, longterm you should probably redesign to not use that polling loop, and keep track of the state of the pins in the main loop code using micros()), but in terms of resolving the issue at hand, I think that’s all that’s needed.

You need to get rid of the delay()s and use millis() or micros() to manage timing as illustrated in Several Things at a Time. The demo uses millis() but it works just as well with micros().

In addition, it should not be necessary to read the button multiple times. loop() should repeat fast enough for a single digitalRead() to be sufficient.

It would help if you explain what the overall program is intended to do.

...R

isn't that functional identical to

while (!digitalRead(buttonPin)) {
  index = random(1, 11);
}
buttonState = HIGH;

The above version is less blind and shorter.
Like the original it does not care for the pulses being 50 mS wide.

Can you stretch the input pulse with a diode and capacitor, with a slow bleed resistor across the capacitor to discharge it?

Alternatively, you could leave out the bleed resistor, and drive the pin low for a moment to discharge the cap. (You'd need a series resistor before the diode, to save damaging whatever produces the pulse.)

That whole loop executes in around 2 milliseconds. So a 50ms pulse would easily be detected.

The way you've coded it is odd.

Okay thanks for the advice so far, im trying the blink without delay method instead of the current delay.
I placed the digital read inside the timing loop but still no luck unless i jncrease the pulse time to 500us so im going to look at implementing pin manipulation for faster pin reading.

Wait, is it 50us or 50 ms?

Oddwired:
so im going to look at implementing pin manipulation for faster pin reading.

Its not the speed of digitalRead that hinders you in detecting the 50 mS pulse. :frowning:

DrAzzy:
Wait, is it 50us or 50 ms?

I was wondering that too.

He did say it is a "fast" 50ms pulse. :slight_smile:

jboyton:
I was wondering that too.

He did say it is a "fast" 50ms pulse. :slight_smile:

For some reason, right from the beginning I thought it was 50uS, but looking back now, 50uS has never been mentioned except by inference "unless i jncrease the pulse time to 500us".

Must be time I got new glasses.

I don't think the problem is your eyesight. The whole thing is by inference since the OP didn't really explain what it is he's trying to do.

Oh c**k, sorry, missled you all, bloody cut and paste; yes its microseconds sorry about that one, will go edit the original to kill the confusion.

You want to check for a pulse that is 50us width, but you have a bunch of delay for 200 us ?
Get rid of the delays.

If that is still not fast enough we can change the code to run more quickly.

Just looking at it closely, your code condenses to this:-

  while (1)
  {
    for (index = 1; index < 11; index++)
    {
        buttonState = digitalRead(buttonPin);
        if (buttonState == HIGH)
        {
            flag=1;
            break;
        }
        delayMicroseconds(200);
    }
    if (flag==1)
       break;
  }

Well, almost - you’d need to set a flag to break out of the while loop, (*done), I guess, but in effect this is it.

The odds of picking up a 50uS pulse are pretty slim…

Yes it condenses. But condensing nonsense into more efficient nonsense isn't progress.

What is it that the code is supposed to do? Detect a 50us pulse, we got that. But what if it's 100us? Or 51us? Should it reject it?

jboyton:
Yes it condenses. But condensing nonsense into more efficient nonsense isn’t progress.

Correct, but it’s easier to read. I was just about to say - I don’t get it. It doesn’t do anything useful.

Yes, that is pretty much equal, but I think

 while (1)
  {
    for (index = 1; index < 11; index++)
    { 
      if (digitalRead(buttonPin) == HIGH)
        break;
    }
  }

Would run a bit faster.

And I ask the op, why do you need to increment index from 1 to 11 over and over?

I am getting confused, please show us your total code in code tags, and give us an algorithm of your system.