Interrupting Playcomlpete (Wave Shield)

by Bratan on Mon Nov 26, 2012 9:48 pm

Is there a way to interrupt "playcomplete" function with button press? I know "playfile" can be interrupted but I want playback of the file to be interrupted only by a button press and not by another wave playback.
So if currently wave is playing and next loop cycle tries to play same wave, it will have to wait/skip until current wave finished. But at the same time if I press button at any time wave playback stops.
Basically this is to stop sound from alarm clock...
Bratan
 
Posts: 35
Joined: Sun Mar 25, 2012 1:08 pm

Re: Interrupting Playcomlpete (Wave Shield)

by adafruit_support_bill on Tue Nov 27, 2012 6:13 am

You can modify the Playcomplete() function to check for a stop flag. In the handler for your button-press, just set the flag to stop the playback.

You will need to use interrupts to check the buttons. Either a timer interrupt to poll the button, or a pin-change interrupt on the button pin itself.
User avatar
adafruit_support_bill
 
Posts: 25402
Joined: Sat Feb 07, 2009 9:11 am

Re: Interrupting Playcomlpete (Wave Shield)

by xl97 on Tue Nov 27, 2012 5:06 pm

you can modify the playComplete() function.. (or create another one).. and do as suggested (check for a 'flag' to be set to tell the audio to stop)..


overview/sample code:

1.) set up a button to set a flag/variable to true/false (1/0).. for example:
(at top of sketch)
boolean forceStop = 0;

then in your button of choice that you set up (maybe use the same button set-up array/functions as the waveHC button set-up does?)
you set this flag/variable to true (ie: forceStop = 1;)


2.) in your playComplete() (or new function you want to edit for this)..
original:
Code: Select all
// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
  // call our helper to find and play this name
  playfile(name);
  while (wave.isplaying) {
  // do nothing while its playing
  }
  // now its done playing
}


new function:

Code: Select all

// Plays a full file from beginning to end with no pause.
void playcompleteStopCheck(char *name) {
  // call our helper to find and play this name
  playfile(name);
  while (wave.isplaying) {
       if(forceStop == 1):
           wave.stop();
       }
  }
  // now its done playing
}


make sense? :) hope this help.
xl97
 
Posts: 144
Joined: Mon Jul 27, 2009 11:51 am

Re: Interrupting Playcomlpete (Wave Shield)

by Bratan on Tue Nov 27, 2012 8:03 pm

Brilliant thank you! :)
Works great, and doesn't require interrupt! I'm just checking button state in the main loop, and once it changes:
Code: Select all
if (interruptAlrm) {
     wave.stop();
     return; // Alarm was interrupted with button, exit
Bratan
 
Posts: 35
Joined: Sun Mar 25, 2012 1:08 pm

Re: Interrupting Playcomlpete (Wave Shield)

by xl97 on Tue Nov 27, 2012 8:38 pm

Bratan wrote:Brilliant thank you! :)
Works great, and doesn't require interrupt! I'm just checking button state in the main loop, and once it changes:
Code: Select all
if (interruptAlrm) {
     wave.stop();
     return; // Alarm was interrupted with button, exit



np... just visualizing what was suggested above really..


also.. you already 'are' using the timer/interrupt to execute the 'checkButtons/Switches' function...

you can just slap in that new button you want to use into the array, and make the code you want executed once pressed/released...etc..

(leaving your main loop with less overhead to worry about) :)



(just a suggestion)
xl97
 
Posts: 144
Joined: Mon Jul 27, 2009 11:51 am

Re: Interrupting Playcomlpete (Wave Shield)

by Bratan on Tue Nov 27, 2012 10:54 pm

You will need to use interrupts to check the buttons. Either a timer interrupt to poll the button, or a pin-change interrupt on the button pin itself.

also.. you already 'are' using the timer/interrupt to execute the 'checkButtons/Switches' function...

Ah, I'm so slow, now I get what both of you are saying :) So digitalRead is kind of an "interrupt" right? Below code is part of buttonProc() function that runs from main loop.
Code: Select all
if (digitalRead(MENU_BUTTON_PIN) == HIGH)
  {
    if (soundAlarm) interruptAlrm=true; // Stops Alarm sound
    // "Set time" button was pressed;
    processMenuButton();
  }


you can just slap in that new button you want to use into the array, and make the code you want executed once pressed/released...etc..

(leaving your main loop with less overhead to worry about) :)

Not sure exactly what do you mean by that? :)
Bratan
 
Posts: 35
Joined: Sun Mar 25, 2012 1:08 pm

Re: Interrupting Playcomlpete (Wave Shield)

by xl97 on Tue Nov 27, 2012 11:29 pm

hi-

well now we're getting out my area of comfort..lol


but no.. a digtalRead.. is just that a 'reading' of the state of a digital pin. (your response will be hi or low)..

this is different than an analogRead().. where you get a value of 0-1023


neither of these has anything to do with an 'interrupt' or 'timer'

(this is where you take what I say with a grain of salt.. and wait for an experience member/staff to correct everything I say) LOL

an interrupt is as it implies, it can interrupt the main code, which is usually executed in a sequential manner, instruction by instruction...

a Timer is like a built in clock/counter.. there are Timer0, Timer1, TImer2, they run at different speeds.. and some built in functions depend on these timers to work.. like millis() and delay()... (so it knows for how long..etc)

all that above being said..'somehow' you can configure the timers to execute a 'function'...

Code: Select all
SIGNAL(TIMER2_OVF_vect) {
  check_switches();
}

and this happens 'outside' of the main loop (independent)

Like in the WaveHC lib examples.. the timer (Timer1) is configured to help process/play the audio but it also 'calls/executes' the check_switches() function..

it does this so it can keep an eye on the state of all the buttons you want/have set-up without interfering with the rest of the code/audio playing.


Not sure exactly what do you mean by that? :)


In most/any/all of the WaveHC example sketches.. you'll see this

Code: Select all
// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {5, 6, 3, 9, 15, 16};


(hint: read the comments line above it!)..

this is where you set up all the buttons you want the check_switches function to monitor/watch...


S0 you would add in your new 'break/stop' button there.. to the end (either my variable name or pin number)...
Code: Select all
// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {5, 6, 3, 9, 15, 16, newSwitch};



then in the examples... in the MAIN loop.. you see code that checks each button.. pressed0, pressed1, pressed2...etc..etc..
Code: Select all
if (pressed[4]) {
    playfile("3.WAV");
    while (wave.isplaying && pressed[4]) {
      //Serial.print(".");
    }
    wave.stop();   
  }
  if (pressed[5]) {
    playfile("4.WAV");
    while (wave.isplaying && pressed[5]) {
      //Serial.print(".");
    }
    wave.stop();   
  }


you would need to add anther (conditional) 'check' to see if that button is being pressed....
Code: Select all
if (pressed[5]) {
    wave.stop();   
  }



etc..etc

hope this helps..
xl97
 
Posts: 144
Joined: Mon Jul 27, 2009 11:51 am

Re: Interrupting Playcomlpete (Wave Shield)

by Bratan on Wed Nov 28, 2012 12:04 am

etc..etc

hope this helps..

Totally! :) I think I was confused about "interrupt" definition... From what I read about them is exactly what you are saying (Timer0,Timer1, ISR, scalers, internal, external). I'm just happy my code works without me having to shift bytes and register just so any one of 3 menu buttons I have can stop the alarm sound :D
So I don't think I actually using any interrupts in the code (other then whatever WaveHC library uses to play Wave file in parallel).
Truly genius work on WaveHC library BTW!
Bratan
 
Posts: 35
Joined: Sun Mar 25, 2012 1:08 pm

Re: Interrupting Playcomlpete (Wave Shield)

by kwikcoupe on Thu Dec 27, 2012 3:22 pm

I am not sure if i should start a new thread of add to the existing older thread.

I am trying to use the modulo function of counting to select which input button has been selected to perform the desired function.

I used the last sketch of "6 buttons, 6 sounds, multiple possibilities!" to biuld my sketch. I would like to add a few lines to the end that add/plus one modulo input without a button press to select the next function. this would be done at the end of the song when it completes. It does not loop.

My goal is to have a rest state of my sketch. When the button is pressed it performs the 1st set of actions. When this song is complete it returns to its rest state and waits to be triggered again performing a second set of actions and returning back to rest awaiting the third press. The same would continue as the modulo repeats.

I thought that adding a version of
// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
// call our helper to find and play this name
playfile(name);
while (wave.isplaying) {
// do nothing while its playing
}
// now its done playing
}
but having it add one to the remainder and setting up the program so every other number is the rest state would complete my sketch. If this is in the wrong place please move as this is my 1st post.[code][/code]
Attachments
Arduino sketch.txt
(7.05 KiB) Downloaded 27 times
kwikcoupe
 
Posts: 4
Joined: Thu Dec 27, 2012 3:05 pm

Re: Interrupting Playcomlpete (Wave Shield)

by xl97 on Thu Dec 27, 2012 4:04 pm

Isnt that what most of the example sketches already do?

Im confused I guess. :)

1.) maybe this thread will help:
viewtopic.php?f=31&t=34510&start=15

2.) It really depends on what these 'actions' are that you want performed when a button is pressed.. are these actions that are:
a.) supposed to take place AS the audio clip is playing?
b.) are these actions supposed be completed before the audio clip ends? after?


but in general.. if you use/call a playComplete() method.. the pointer/code stays in that function until the audio is done.. and then 'waits' for another button press/input to do something else.
xl97
 
Posts: 144
Joined: Mon Jul 27, 2009 11:51 am

Re: Interrupting Playcomlpete (Wave Shield)

by kwikcoupe on Fri Dec 28, 2012 1:09 am

What currently happens is when a button is pressed 2 relays are triggered in a random order at a random time between a set scale while the audio is playing. What also happens is when the audio stops the relays continue to be triggered until the next time the button is pressed and starts a variation of the same sequence with a different audio track playing.

What I want to happen is for the sketch to be at rest until the button is pressed and the sequence to work only as long as the audio track plays. When the audio track is complete I want the sketch to automatically return to be at rest until the button is pressed again and the second third and forth sequence to be performed each returning to rest until the next button is pressed.

I apologize for my lack of knowledge. I have only been working with code for 2 months and this is my 1st sketch. I have read a lot of sketches and been throigh a lot of tutorials but am still very new to this great world. Thank you for the help.
kwikcoupe
 
Posts: 4
Joined: Thu Dec 27, 2012 3:05 pm

Re: Interrupting Playcomlpete (Wave Shield)

by kwikcoupe on Fri Dec 28, 2012 1:39 am

I think what I am looking for is a way to write in code
When file (xx.wav) is done playing; {
Perform task here
}
kwikcoupe
 
Posts: 4
Joined: Thu Dec 27, 2012 3:05 pm

Re: Interrupting Playcomlpete (Wave Shield)

by adafruit_support_bill on Fri Dec 28, 2012 6:33 am

what I am looking for is a way to write in code
When file (xx.wav) is done playing; {
Perform task here
}

Playcomplete() will play the complete wav file, then proceed to the statements that follow:
Code: Select all
playcomplete(filename);
performtask();
User avatar
adafruit_support_bill
 
Posts: 25402
Joined: Sat Feb 07, 2009 9:11 am

Re: Interrupting Playcomlpete (Wave Shield)

by kwikcoupe on Fri Dec 28, 2012 12:59 pm

so instead of using
playfile(xx.wav);
Perform task here
I will beusing
playcomplete(xx.wav);
if the sequence listed here is to be performed as the audio is playing, How do you tell it to stop when the audio file is complete?
Can you link me to a tutorial so i can learn more about these functions? I cant find the language on the Arduino Website.
kwikcoupe
 
Posts: 4
Joined: Thu Dec 27, 2012 3:05 pm

Re: Interrupting Playcomlpete (Wave Shield)

by adafruit_support_bill on Fri Dec 28, 2012 1:14 pm

if the sequence listed here is to be performed as the audio is playing, How do you tell it to stop when the audio file is complete?

That is not what you asked for in your previous query. You asked how to perform a task when the wav file was complete.

If you want to perform actions while the wav file is playing, you need to use playfile and test for when it is finished:

Code: Select all
playfile(name);
while (wave.isplaying)
{
// Perform some task while it is playing
}
// perform some other task when it is finished playing

User avatar
adafruit_support_bill
 
Posts: 25402
Joined: Sat Feb 07, 2009 9:11 am