It is a complicated sketch but it is only the sound part I have problems with.
I need two tones after each other, jusy after "case" but seems like an inpossible task for me.
The only place I can see tone() functions, and the switch case that's giving you problems is the sound() function defined near the end of your sketch.
But the only place I can see the sound() function being called is inside the ISR() function - I'm assuming some clever stuff is going on with interrupts that I don't understand, because I can't see how or when ISR() gets called.
I do know you have to keep interrupt service routines super-short though. Set some flags, update some variables, and return, that kind of thing.
Your ISR calls a bunch of other functions, some of which try to go on for several seconds. I think that's the problem.
Thank you very much for your replies and the energy you have put into this.
Very appreciated.
Yes it is complicated and I did not write it as i'm a newbie with Arduino.
What it does is timing several workout programs.
On the display you choose which workout and then it counts down giving a signal when it is time for a break and time to start training again. And 10 seconds before the time is finished it gives a warning meaning 10 seconds left.
Only I find the tones very poor that is why I want to change the audio signals in 2 tone signals.
But it is difficult to do that and i don;t understand why.
sound() is called from ISR and delay() is called inside sound() which leads to your problem. There is really no reason for you to be using interrupts to keep track of elapsed seconds. Your code seems very over-complicated.
Yes i have heart that before but the problem is I'm not advanced enough to write my own code so I have to use this code and sees how it works for me and I must say I came very far.
I have my lights red en green for train and break working well and some other things working perfect.
as a matter of fact it is already doing all i need but just 1 tone sounds so boring.
I can't test this code where I am at the moment so I've probably missed something.
Up near the top of the sketch, probably after all the #define lines, add a line to declare a global variable called soundToPlay. It needs to be volatile because we're mucking about with interrupts. Like this:
volatile byte soundToPlay = 0;
Then in your ISR,
remove the declaration of soundToPlay.
remove the call to sound() and replace them with lines that modify the soundToPlay flag like this:
ISR(TIMER1_COMPA_vect) // interrupt service routine
{
if (timerMode != TIMER_MODE_DISABLED)
{
//countdown seconds
if (seconds > 0)
{
seconds--;
}
else
{
//disableTimer1Interrupts();
int currInterval = workouts[currentWorkout].currentInterval;
digitalWrite(31, !digitalRead(31));
digitalWrite(33, !digitalRead(33));
// int soundToPlay = MUSIC_BREAK; //this is global now. Don't re-declare it.
soundToPlay = MUSIC_BREAK; //modify the flag
if (digitalRead(led) != HIGH)
{
soundToPlay = MUSIC_TRAIN;
}
if (workouts[currentWorkout].cycle == 0 && workouts[currentWorkout].countOfIntrvals == currInterval + 1) {
soundToPlay = MUSIC_TRAIN;
timerMode = TIMER_MODE_DISABLED;
}
else
{
workouts[currentWorkout].incCurrInterval();
seconds = workouts[currentWorkout].getCurrInterval().duration;
}
// sound(soundToPlay); // Don't do this here
//enableTimer1Interrupts();
}
if (seconds == WARNING_SIGNAL_LIMIT_SECONDS) {
//sound warning
//disableTimer1Interrupts();
// sound(MUSIC_WARN); //don't do this
soundToPlay = MUSIC_WARN; //do this instead
//enableTimer1Interrupts();
}
}
if (regime != REGIME_MENU) {
showTime();
}
}
Then at the end of your main loop add a call to sound().
This looks at the soundToPlay variable and decides what sound to play (or stay silent).
Then reset the flag ready for next time.
The last few lines of the sketch need to look something like this
prevKey = key;
sound(soundToPlay); //play appropriate sound
soundToPlay = 0; //reset flag ready for next time
delay(50);
}
}