-1

I am currently writing a program where I need to run a loop that can be interrupted at any time. In this case, a series of tones are playing over and over again but should stop when one of the values from a sensor comes back as HIGH.

At the moment, I've got this:

void loop() {
while(digitalRead(ctsPin) == LOW) {
    // Some code here
  }
}

However, the while loop will only break when the instructions inside it have finished running. Is there a way that I can run these over and over again but stop them at any time, even if it is part-way through?

Thanks in advance.

  • 1
    Do you mean that you want to poll the input more often? Why not add a few `if` checks for the condition inside the loop? You *do* know about the `break` statement? – Some programmer dude Jun 26 '17 at 06:28
  • I do know about the 'break' statement but am looking for something that will stop it at any point, instantly, if that's possible. – Michael Nixon Jun 26 '17 at 06:30
  • 1
    This is not a beginners tutorial site. You're better off [reading a good, introductory book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – juanchopanza Jun 26 '17 at 06:32
  • If `if - break` is not enough, consider looking into how event handlers work. – Jason Stein Jun 26 '17 at 06:34
  • You have to remember that the Arduino environment executes the function `loop` each time it terminates. Then, if you break the function `loop`, it's re-executed immediately. Your program might be an `if else` condition where you verifies the status of the bit you are interested in. – Sir Jo Black Jun 26 '17 at 09:12

4 Answers4

2

I take it that you are actually asking how to immediately break a loop which has many hard-coded delays (tones) in it, no matter what code inside that loop that is currently executing. That isn't possible.

Adding a lot of if statments all over the loop won't help, because that won't prevent delay-based code from playing out the current tone until it is done.

The alternative would be to create some sort of queue/ring buffer containing the items to be played. The PWM interrupt that plays the tones will go through this queue and play them one at a time.

When you wish to stop, you would then simply disable the interrupt and pull the port pin to a silent state. This will cause it to stop immediately, even if the program is playing the part between two edges of the tone signal.

Lundin
  • 195,001
  • 40
  • 254
  • 396
1

The break statement will interrupt the current loop. So you should have a conditional statement for the condition you are monitoring, and if it evaluates to true, call break.

if (digitalRead(ctsPin) == HIGH){ break }

Jason Stein
  • 714
  • 3
  • 10
0

Question is not clear. To stop running the loop you can use break as given below. Check if this is what you're looking for.

   void loop() {
    while(digitalRead(ctsPin) == LOW) {
        // Some code here
        if (digitalRead(ctsPin) == HIGH){
            break;
        }
        // Some code here
      }
    }
9T9
  • 698
  • 2
  • 9
  • 22
0

There are two ways to break "instantly." One is to use an interrupt and the other is to check for the condition more often -- after each instruction if really necessary, and break out then:

void loop()
{
    while(digitalRead(ctsPin) == LOW)
    {
       // code block (or even a single statement)...
       if (digitalRead(ctsPin) == HIGH) break;
       // code block (or even a single statement)...
       if (digitalRead(ctsPin) == HIGH) break;
       // code block (or even a single statement)...
       if (digitalRead(ctsPin) == HIGH) break;
       // etc.
    }
}

If you get too many of these, it may be advisable then to look into an interrupt instead. For an example of how to do that, and the various interrupts available for your target board, I suggest taking a look at Arduino Interrupt Documentation.

If you decide to go that way, give it a try and then if you run into issues, ask a different question and we'll help you out.

TomServo
  • 7,248
  • 5
  • 30
  • 47