Pages: [1]   Go Down
Author Topic: Interrupt a running pattern with an IR button press  (Read 483 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am playing with patterns at the moment and have the patterns running from my IR remote. The patterns and the IR are working spot on. But the issue I am having is that I have to let the whole pattern run to it's tenth pass before I can tun the pattern attached to button 2.

How to I make it so when I press Button 2 it will stop whatever Button 1 is doing and run the pattern for button 2?

This is prob a simple question for some but as a newbie it's mind numbing!  smiley-lol

I have only posted a partial bit of the code as I dont think the whole code is needed for this question?

Code:
void loop()
  {  
       if (irrecv.decode(&results)) {
     lReceived = results.value ;
     Serial.println(results.value);
       switch (lReceived) {
    
// BUTTON 1        
         case button1:
    
     for (int i=0; i <= 10; i++){
    
  makePattern(Mouth, pattern1, 6);
  makePattern(Mouth, pattern2, 6);
  makePattern(Mouth, pattern3, 6);
  makePattern(Mouth, pattern4, 6);
  makePattern(Mouth, pattern5, 6);
  makePattern(Mouth, pattern6, 6);
  makePattern(Mouth, pattern7, 6);
  makePattern(Mouth, pattern8, 6);
  makePattern(Mouth, pattern9, 6);
  makePattern(Mouth, pattern10, 6);
  makePattern(Mouth, pattern11, 6);
  makePattern(Mouth, pattern12, 6);
     }    
 break;
 {
  
  
// BUTTON 2
  case button2:
       for (int i=0; i <= 10; i++){    
  
  makePattern(Mouth, pattern13, 6);
  makePattern(Mouth, pattern14, 6);
  makePattern(Mouth, pattern15, 6);
  makePattern(Mouth, pattern16, 6);
  makePattern(Mouth, pattern17, 6);
  makePattern(Mouth, pattern18, 6);
  makePattern(Mouth, pattern19, 6);
     }    
 break;

    
  }
       }
    
     irrecv.resume(); // Receive the next value
   }
  }

void makePattern(int leds[], int pattern[], int num)
{
  int delayTime = 100;
  for(int i = 0; i < num; i++)
  {
    digitalWrite(leds[i], pattern[i]);
  }
  delay(delayTime);
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
How to I make it so when I press Button 2 it will stop whatever Button 1 is doing and run the pattern for button 2?
Two possibilities:
1) Get rid of every single delay. Use the blink without delay example as inspiration (as you should have done in the first place).
2) Have makePattern() determine whether it is time to stop doing what it is doing. Have each case also determine whether to stop doing what it is doing (before calling makePattern() again).
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your going to sigh loudly but.......I'm still really struggling with this.

What code do I use to determine whether makepattern() has to stop when calling the next makepattern()?

 smiley-confuse

Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
What code do I use to determine whether makepattern() has to stop when calling the next makepattern()?
It needs to determine whether the IR button was pressed.
Code:
       if (irrecv.decode(&results)) {
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 92
Posts: 4723
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This looks like the heart of your sketch, to turn num leds on or off.

Code:
  for(int i = 0; i < num; i++)
  {
    digitalWrite(leds[i], pattern[i]);
  }

The rest is to read the 'buttons', feed the heart and slow the action down enough to see as other than dimly lit leds.

You have parts;

button read (and feedback to serial):
Code:
       if (irrecv.decode(&results)) {
     lReceived = results.value ;
     Serial.println(results.value);

pattern making feeding the light control 'heart', 1 of 2 such:
Code:
     for (int i=0; i <= 10; i++){
   
  makePattern(Mouth, pattern1, 6);
  makePattern(Mouth, pattern2, 6);
  makePattern(Mouth, pattern3, 6);
  makePattern(Mouth, pattern4, 6);
  makePattern(Mouth, pattern5, 6);
  makePattern(Mouth, pattern6, 6);
  makePattern(Mouth, pattern7, 6);
  makePattern(Mouth, pattern8, 6);
  makePattern(Mouth, pattern9, 6);
  makePattern(Mouth, pattern10, 6);
  makePattern(Mouth, pattern11, 6);
  makePattern(Mouth, pattern12, 6);
     }     

and the actual 'heart' with delay(), the makePattern() function.

There are other details but they seem to support the above from what code you show.

Every time through loop() you try to detect a button and do all the pattern in top-down style. That requires you to put control structures inside control structures, for-next inside for-next inside switch-case inside if... and then if a different button is pressed, get out of it all to do the different thing.
Ordinary top-down coders would add more structures and variables to set up a series of breaks, making the code even more baroque but hey, that can work as can using return instead of break.

For it to be responsive, you need to get rid of the delays and make things happen on a time-passed basis which BlinkWithoutDelay shows the code mechanism to do;
Code:
if ( millis_now - start_millis >= interval_millis ) {
  start_millis = millis_now;
  do_your_thing;
}

However you can tear most all of the structures-inside-structures down and simplify your code.

1) make the button check only set a variable that will signal other code what button was last pressed. This part never gets time-checked and is always first to run in loop().

2) instead of trying to do everything from start to finish in one pass of loop(), have it only do one run through the code in makePattern() with one set of parameters. This part always gets time-checked and should be the last thing to run in loop() and then only as do_your_thing.
2A) after do_your_thing (makePattern), set a variable to tell the thing was done.

3) in the middle, a part that sets the parameters differently each time the variable from 2A has been set, and to clear that same variable since it may be many times through loop() before this part (3) runs again.

Now you have 3 different sections that are only connected by variables each may use/set. No part is 'inside' another. You want to cut in on the dance then all you need do is change the control variables or parameters. You can add conditions and triggers without having to 'fit them in' to ever increasing structure, like user serial I/O or more buttons.

If you keep the amount of code run each time through loop() short then part 1 that reads the buttons will be extremely responsive. The do_your_thing part may be fast enough to respond to frequencies received into 1000's per second if desired with less-structured code.
Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Pages: [1]   Go Up
Jump to: