If ... till is there a function?

I have this code for a tone.

#include <TimerInterrupt.h>
TimerInterrupt timer_interrupt;

int zaehler=0;
int digit1=7;
int digit2=6;
int digit3=5;
int digit4=4;
int ds=11;
int sh=12;
int st=13;
int position=0;
int LEDgruen=3;
int buttonrot=A3;
int LEDrot=A4;
int Alarm=9;
int LEDcheck=0;
int Verzoegerung=0;
int AnAus=0;
int Zeit=913;
int Alarmzeit=2020;
int Sekunde;
int Modus=0;
int Segment7position[4] = {
digit1,
digit2,
digit3,
digit4
};

int Segment7zahl[10][8]={
{1,1,1,1,1,1,0,0},//0
{1,1,0,0,0,0,0,0},//1
{1,0,1,1,0,1,1,0},//2
{1,1,1,0,0,1,1,0},//3
{1,1,0,0,1,0,1,0},//4
{0,1,1,0,1,1,1,0},//5
{0,1,1,1,1,1,1,0},//6
{1,1,0,0,0,1,0,0},//7
{1,1,1,1,1,1,1,0},//8
{1,1,1,0,1,1,1,0}//9
};

int Segment7dezimalposition[4] = {
1000,
100,
10,
1
};

int Segment7segmentzahl ( int position , int zahl ) {
return((zahl/(Segment7dezimalposition[position]))%10);
}

void Segment7anzeige ( int position , int dezimalzahl ) {
for(int counter=0;counter<=3;counter++){
if(position!=counter)
digitalWrite(Segment7position[counter],LOW);}

digitalWrite(st,0);
for (int index1=0;index1<=7;index1++)
{
digitalWrite(ds,0);
digitalWrite(sh,0);

digitalWrite(ds,Segment7zahl[dezimalzahl][index1]);
digitalWrite(sh,1);

}
digitalWrite(st,1);

digitalWrite(Segment7position[position], HIGH);
}

ISR(TIMER1_COMPA_vect) {
position=((position+1)%4);
if(Modus==0){
Segment7anzeige(position, Segment7segmentzahl(position,Zeit));}
else if(Modus==1){
Segment7anzeige(position, Segment7segmentzahl(position,Alarmzeit));}
if(Modus==2){
Segment7anzeige(position, Segment7segmentzahl(position,Zeit));}

if ((Verzoegerung++)%200==0){
Uhrwerk();
AnAus=~AnAus;
digitalWrite(LEDgruen, AnAus);
}
}

void Uhrwerk(){
Sekunde=Sekunde+1;
if (Sekunde%60==0){
Zeit=Zeit+1;
if (Zeit%100==60){
Zeit=Zeit+40;};
if (Zeit%2400==0){
Zeit=0;}
}
}

void Uhrwerkein(){
if (digitalRead(8)==HIGH){
Zeit=Zeit+1;
while (digitalRead(8)==HIGH) delay(1);
if (Zeit%100==60){
Alarmzeit=Zeit+40;}
if (Zeit%2400==0){
Zeit=0;}
}

if (digitalRead(10)==HIGH){
Zeit=Zeit+100;
while (digitalRead(10)==HIGH) delay(1);
if (Zeit%100==60){
Alarmzeit=Zeit+40;}
if (Zeit>2400){
Zeit=Zeit-2400;}
}
}
void Alarmzeitein(){
if (digitalRead(8)==HIGH){
Alarmzeit=Alarmzeit+1;
while (digitalRead(8)==HIGH) delay(1);
if (Alarmzeit%100==60){
Alarmzeit=Alarmzeit+40;}
if (Alarmzeit%2400==0){
Alarmzeit=0;}
}

if (digitalRead(10)==HIGH){
Alarmzeit=Alarmzeit+100;
while (digitalRead(10)==HIGH) delay(1);
if (Alarmzeit%100==60){
Alarmzeit=Alarmzeit+40;}
if (Alarmzeit>2400){
Alarmzeit=Alarmzeit-2400;}
}
}

void setup() {
Serial.begin(9600);
pinMode(ds,OUTPUT);
pinMode(sh,OUTPUT);
pinMode(st,OUTPUT);
pinMode(LEDgruen,OUTPUT);
pinMode(LEDrot,OUTPUT);
pinMode(Alarm,OUTPUT);
pinMode(digit1,OUTPUT);
pinMode(digit2,OUTPUT);
pinMode(digit3,OUTPUT);
pinMode(digit4,OUTPUT);
pinMode(2,INPUT);
pinMode(8,INPUT);
pinMode(10,INPUT);
pinMode(buttonrot,INPUT);
digitalWrite(LEDrot,LOW);
cli();//stop interrupts
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;//initialize counter value to 0
OCR1A = 9999;// = (1610^6) / (2008) - 1 (must be <65536)
TCCR1B |= (1 << WGM12);
TCCR1B |= (0 << CS12) | (1 << CS11)| (0 >> CS10);
TIMSK1 |= (1 << OCIE1A);
sei();//allow interrupts
}

void loop () {
digitalWrite(Alarm, LOW);
if ((Alarmzeit==Zeit) && (Modus==0) && (digitalRead(LEDrot)==HIGH)) {
while (digitalRead(LEDrot)==HIGH){
tone(Alarm, 440);
delay(500);
noTone(Alarm);
delay(200);
tone(Alarm, 440);
delay(500);
noTone(Alarm);
delay(200);
tone(Alarm, 440);
delay(500);
noTone(Alarm);
delay(200);
tone(Alarm, 349);
delay(350);
noTone(Alarm);
delay(100);
tone(Alarm, 523);
delay(150);
noTone(Alarm);
delay(50);
tone(Alarm, 440);
delay(500);
noTone(Alarm);
delay(200);
tone(Alarm, 349);
delay(350);
noTone(Alarm);
delay(100);
tone(Alarm, 523);
delay(150);
noTone(Alarm);
delay(50);
tone(Alarm, 440);
delay(650);
noTone(Alarm);
delay(650);

tone(Alarm, 659);
delay(500);
noTone(Alarm);
delay(200);
tone(Alarm, 659);
delay(500);
noTone(Alarm);
delay(200);
tone(Alarm, 659);
delay(500);
noTone(Alarm);
delay(200);
tone(Alarm, 698);
delay(350);
noTone(Alarm);
delay(100);
tone(Alarm, 523);
delay(150);
noTone(Alarm);
delay(50);
tone(Alarm, 415);
delay(500);
noTone(Alarm);
delay(200);
tone(Alarm, 349);
delay(350);
noTone(Alarm);
delay(100);
tone(Alarm, 523);
delay(150);
noTone(Alarm);
delay(50);
tone(Alarm, 440);
delay(650);
noTone(Alarm);
delay(650);

tone(Alarm, 880);
delay(500);
noTone(Alarm);
delay(200);
tone(Alarm, 440);
delay(300);
noTone(Alarm);
delay(100);
tone(Alarm, 440);
delay(150);
noTone(Alarm);
delay(200);
tone(Alarm, 880);
delay(500);
noTone(Alarm);
delay(200);
tone(Alarm, 830);
delay(325);
noTone(Alarm);
delay(100);
tone(Alarm, 784);
delay(175);
noTone(Alarm);
delay(50);
tone(Alarm, 740);
delay(125);
noTone(Alarm);
delay(200);
tone(Alarm, 698);
delay(125);
noTone(Alarm);
delay(200);
tone(Alarm, 740);
delay(250);
noTone(Alarm);
delay(650);

tone(Alarm, 455);
delay(250);
noTone(Alarm);
delay(200);
tone(Alarm, 622);
delay(500);
noTone(Alarm);
delay(200);
tone(Alarm, 587);
delay(325);
noTone(Alarm);
delay(100);
tone(Alarm, 554);
delay(175);
noTone(Alarm);
delay(150);
tone(Alarm, 523);
delay(125);
noTone(Alarm);
delay(200);
tone(Alarm, 466);
delay(125);
noTone(Alarm);
delay(200);
tone(Alarm, 523);
delay(250);
noTone(Alarm);
delay(650);

tone(Alarm, 349);
delay(250);
noTone(Alarm);
delay(200);
tone(Alarm, 415);
delay(500);
noTone(Alarm);
delay(100);
tone(Alarm, 349);
delay(350);
noTone(Alarm);
delay(50);
tone(Alarm, 440);
delay(125);
noTone(Alarm);
delay(200);
tone(Alarm, 523);
delay(500);
noTone(Alarm);
delay(100);
tone(Alarm, 440);
delay(375);
noTone(Alarm);
delay(50);
tone(Alarm, 523);
delay(125);
noTone(Alarm);
delay(200);
tone(Alarm, 659);
delay(650);
noTone(Alarm);
delay(650);

tone(Alarm, 349);
delay(250);
noTone(Alarm);
delay(200);
tone(Alarm, 415);
delay(500);
noTone(Alarm);
delay(100);
tone(Alarm, 349);
delay(350);
noTone(Alarm);
delay(50);
tone(Alarm, 523);
delay(125);
noTone(Alarm);
delay(200);
tone(Alarm, 440);
delay(500);
noTone(Alarm);
delay(100);
tone(Alarm, 349);
delay(375);
noTone(Alarm);
delay(50);
tone(Alarm, 523);
delay(125);
noTone(Alarm);
delay(200);
tone(Alarm, 440);
delay(650);
noTone(Alarm);
delay(650);
}
}

digitalWrite(Alarm, LOW);

if (digitalRead(2)==HIGH) {
Modus=Modus+1;
while (digitalRead(2)==HIGH) delay(1000);
if(Modus==3){
(Modus=0);
}
}

if (Modus==1) {
Alarmzeitein();
}
if (Modus==2) {
Uhrwerkein();
}

if (digitalRead(buttonrot)==HIGH){
if (LEDcheck==0){
LEDcheck=1;
digitalWrite(LEDrot, HIGH);
}
else {
LEDcheck=0;
digitalWrite(LEDrot, LOW);
}
delay(1000);
}

Serial.println(Modus);

}

If the conditions are given i want the tone to start but as soon as i press the button, so when digitalRead(buttonrot)==HIGH, I want it to stop.

Is there something like a "till"?

Thanks for your help

Do you mean that you want the tone to start when the button becomes pressed then turned off the next time it becomes pressed or do you mean that you want the tone to sound while the button is pressed ?

The tone starts from something different(didn´t put it up here because it´s quite long)
So the tone starts from something I programmed (tried it and it works).
Now I want it to stop when pressing the button once.

What is it that keeps it sounding ?

Normally you would control whether it sounds or not based on the state of a boolean variable. The code will check every time through loop() whether the boolean is true and sound the tone if it is true, otherwise it will stop the tone

Should anything happen to set the boolean to false, such as button press being detected, then the tone will stop

All of this depends on the code running freely with no code blocking loop() repeating very frequently which is good programming practice in any case

Sorry for the bad description.
So this is a clock.
At xx:xx´o clock the tone (alarm) will start trough a loop(). It will sound for about 1min30s.
I want to use the butten as a button on an alarm-clock, so it should interupt the alarm and stop it.

Hi,
So you have TWO inputs.
ONE trips the alarm
THE OTHER, a button resets the alarm.

What do you want to do if when you RESET the ALARM input is still triggering?
What model Arduino are you using?

Can you post a circuit showing how the two connections are made to the controller?

Tom.... :smiley: :+1: :coffee: :australia:

Arduino Uno R3
So the button doesn´t reset the alarm. It should just stop the tone while the alarm runs (24h later it would sound again)
I just thought that there is something like "till" so i can say do this but when i do that then stop this.

Because i did something like turn on alarm while LEDred on but i can´t turn it off while the alarm sounds.

do . . . while

But that just stops the loop() at the end. I want the sound to be stopped when i press.
Something with an interrupt() but i don´t know how.

You posted a longer sketch earlier, I can't find it again now. But it was a very long sequence of tone(), noTone() and delay() calls. The problem with that is if you want to stop that sequence at any point is a button is pressed, you would need to put a line of code after every one of those lines, or after every few lines, to check the button and finish the sequence at that point. It's all going to get very long indeed.

A better approach would be to put the notes and times into data arrays and play them with a loop. Then, not only is your code much shorter, but you can easily terminate the loop at any point if the button is pressed.

2 Likes

Possibly have the interrupt set a global variable and the loop code include that variable in the flow control?

Doesn't get around the fact that you have to code that check in 50 places. You need to re-code so that the check only has to be done in one place. Then it makes no difference if you use an interrupt or not. You check the button once and stop the sequence.

1 Like

Yeah, that would work but as you said would be looong.
So you mean to put the tone sequence out of void loop() and put it in another void?
How exactly is that possible?
I posted my sketch again at the top

The thing is that when it is inside the tone it plays it does nothing else till the end of that sequence

Look at this first part

tone(Alarm, 440);
delay(500);
noTone(Alarm);
delay(200);
tone(Alarm, 440);
delay(500);
noTone(Alarm);
delay(200);
tone(Alarm, 440);
delay(500);
noTone(Alarm);
delay(200);
tone(Alarm, 349);
delay(350);
noTone(Alarm);
delay(100);
tone(Alarm, 523);
delay(150);
noTone(Alarm);
delay(50);

This is the same 4 lines repeated over and over. Only the numbers change. Those numbers could be stored in arrays:

const int note[] = {440, 440, 440, 349, 523, ...};
const int duration[] = {500, 500, 500, 350, 150, ...};
const int pause[] = {200, 200, 200, 100, 50, ...};

Then, the loop can play them back:

if ((Alarmzeit==Zeit) && (Modus==0) && (digitalRead(LEDrot)==HIGH)) {
  int n = 0;
  while (digitalRead(LEDrot)==HIGH && n < sizeof(note)/sizeof(note[0])){
    tone(Alarm, note[n]);
    delay(duration[n]);
    noTone(Alarm);
    delay(pause[n]);
    n++;
  }
}

The loop stops when it has played all the notes or the button is pressed.

1 Like

Thanks
thats it.
I will try that one

Hi,
So you just want to "mute" the alarm?

Tom... :smiley: :+1: :coffee: :australia:

yes
the button should stop the tone, mute, but no reset the whole clock
PaulRBs code does that now

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.