-1

I want to give a pause to case 0xFF02FD or at least to break from that case by entering the case 0xFFA25D even if the 1st case not finished, when I press power button wich has hexa code ( 0xFFA25D) I turn On the led and when I press playButton(0xFFA25D ) I turn on the piezoo and turn off the led (as you can see in my code) but I can't get out from that case by pressing powerButton again I should wait till it ends .

void loop() {
  if (irrecv.decode(&results)) {
    // If it's been at least 1/4 second since the last
    // IR received, toggle the relay
    Serial.println(results.value,HEX);
    irrecv.resume();
  }

  switch(results.value){
    case 0xFFA25D:
      digitalWrite(redPin,HIGH);
      break;

    case 0xFF02FD:
      digitalWrite(redPin,LOW);
      firstSection();

      //Play second section
      secondSection();

      //Variant 1
      beep(f, 250);  
      beep(gS, 500);  
      beep(f, 350);  
      beep(a, 125);
      beep(cH, 500);
      beep(a, 375);  
      beep(cH, 125);
      beep(eH, 650);

      delay(500);

      //Repeat second section
      secondSection();

      //Variant 2
      beep(f, 250);  
      beep(gS, 500);  
      beep(f, 375);  
      beep(cH, 125);
      beep(a, 500);  
      beep(f, 375);  
      beep(cH, 125);
      beep(a, 650);
      delay(500);       
      break;
  }
}
  • with if (something) break;? – Juraj Feb 22 '18 at 14:41
  • that won't help, if I can break by if condition I can do this just by calling another case, the only way to use if ()break; is by setting the condition before entering that case, which is not effective. – LRH18 Feb 22 '18 at 15:05
  • you want to go to start of loop() ? use return; – Juraj Feb 22 '18 at 15:17
  • for clarity: I know from the start what OP wants. But I answer what he asks, because Google likes StackExchange and people will come here to find an answer to the question, not what OP had in mind. – Juraj Feb 22 '18 at 16:59
  • you need to clarify the problem in your mind ... it actually has nothing to do with the switch/case statement ... the real problem is how to interrupt a long subroutine with a button press.. – jsotola Feb 23 '18 at 17:50
0

You are not asking to simply exit a switch-case statement, but to react to your IR remote button press during the execution of other code. With a normal push button directly connected to the Arduino you would normally do this through an interrupt routine. Maybe the library, that you are using, supports decoding IR signals trough interrupts.

If not, you have one more option: From your code it seems, that the IR receiving part is non-blocking. This means, that it only executes, if there is really something to receive, else it would let the program execute the rest of the code, not blocking the execution. Then you have to program your piezo code (the code in the case 0xFF02FD:) as non-blocking code (maybe using PWM hardware or timer interrupts to output the right frequency and just setting trigger variables in your switch-case statement).

When the piezo code is non-blocking, the decode function of the IR library is executed also during your beep sequence, so your program can react to the results of it.

  • thanks for your answer, so the best thing is to use timer interrupts, is it ok to use timer0 to define an interrupt handler isn't this gonna mess with millis() or delay() ? – LRH18 Feb 22 '18 at 20:24
  • Yes, timer0 is used for millis() and delay() and you cannot simply define your own ISR for it without disabling the one defined somewhere in the avr includes (currently don't remember where exactly). Why not using another timer? The ATmega328P, which is used in Arduino UNO and Nano, has 3 timers. But be sure, that the timer you choose isn't used by the IR library. – chrisl Feb 22 '18 at 23:48
  • actually, the IR library was using timer2 and I change it to timer3 because it was interfering with tone() function. and thank you again. – LRH18 Feb 23 '18 at 11:23
  • If this answered your question, please mark it as the correct answer – chrisl Feb 23 '18 at 13:59
0

Because you only check if (irrecv.decode(&results)) at the top of loop(), that is the only point in your code that you can change your action based on a new IR input.

While not an ideal solution, you could just insert if (irrecv.decode(&results)) {return;}in between all beep() calls.

//Variant 1
beep(f, 250);
if (irrecv.decode(&results)) {return;}
beep(gS, 500);  
if (irrecv.decode(&results)) {return;}
beep(f, 350);
if (irrecv.decode(&results)) {return;}

and so on.

A better solution would be to avoid re-typing the same code by using loops and functions. You call beep() repeatedly with only the note and duration changing. You could put your sequence of notes and durations in an array and writing a new function that calls beep() for one element in the array and then increments a pointer to the next note to play. Your loop() calls this function and checks to see if there is any IR code ready also.

An even better solution would be to set up a hardware timer to produce regular interrupts and the ISR would check if there is IR data ready and set a global flag that is checked in the program.

  • thanks for your help, what I did is I made 4 arrays of frequency and duration of tones and I put them in for loops for every function, and then I insert the irrecv.decode(&results) on this loops, it works but it's a pain in the butt, – LRH18 Feb 22 '18 at 19:43
  • As noted in the other excellent answer by @chrisl, you are mixing non-blocking code and blocking code, but to have the ability to break out at any instant, you would need to have all your code be non-blocking. But beep() is a blocking function -- it doesn't return control until it's done. And to do what it does in a non-blocking way is a bit more complicated. An alternative is to edit IRrecv library so it can call a user function when a code is received, but again -- complicated. – jose can u c Feb 22 '18 at 19:44
  • I want to use timers interrupts but I'm not expert and I'm afraid to mess with delay or millis() ,that's why I was looking for an easy solution . it seems that as you mentioned before using loops and arrays is the easiest thing I can do , so thanks. – LRH18 Feb 22 '18 at 21:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.