1

I am making a police light and siren but the delay on light (); affects the buzzers delay tone

This is the code:

//PIN 9 - Buzzers int f,d; int t =0; void setup() { pinMode(5,OUTPUT); pinMode(6,OUTPUT); pinMode(7,OUTPUT); } void loop() { buzzer (); } void buzzer () { for(f=635;f<=912;f++) { tone(9, f); delay(d); d=10; light (); } for(f=911;f>=634;f--) { light (); tone(9, f); delay(d); d=9; } } void light() { digitalWrite(5,HIGH); delay(t); digitalWrite(5,LOW); delay(t); digitalWrite(5,HIGH); delay(t); digitalWrite(5,LOW); delay(t); digitalWrite(5,HIGH); delay(t); digitalWrite(5,LOW); delay(t); digitalWrite(7,HIGH); delay(t); digitalWrite(7,LOW); delay(t); digitalWrite(7,HIGH); delay(t); digitalWrite(7,LOW); delay(t); digitalWrite(7,HIGH); delay(t); digitalWrite(7,LOW); delay(t); digitalWrite(5,HIGH); digitalWrite(6,HIGH); digitalWrite(7,HIGH); delay(t); digitalWrite(5,LOW); digitalWrite(6,LOW); digitalWrite(7,LOW); delay(t); digitalWrite(5,HIGH); digitalWrite(6,HIGH); digitalWrite(7,HIGH); delay(t); digitalWrite(5,LOW); digitalWrite(6,LOW); digitalWrite(7,LOW); delay(t); digitalWrite(5,HIGH); digitalWrite(6,HIGH); digitalWrite(7,HIGH); delay(t); digitalWrite(5,LOW); digitalWrite(6,LOW); digitalWrite(7,LOW); delay(t); digitalWrite(5,HIGH); delay(t); digitalWrite(5,LOW); digitalWrite(7,HIGH); delay(t); digitalWrite(7,LOW); delay(t); digitalWrite(5,HIGH); delay(t); digitalWrite(5,LOW); digitalWrite(7,HIGH); delay(t); digitalWrite(7,LOW); delay(t); digitalWrite(5,HIGH); delay(t); digitalWrite(5,LOW); digitalWrite(7,HIGH); delay(t); digitalWrite(7,LOW); delay(t); digitalWrite(5,HIGH); delay(t); digitalWrite(5,LOW); digitalWrite(7,HIGH); delay(t); digitalWrite(7,LOW); delay(t); } 
4
  • There are 2 ways. 1) State machine. 2) Use the PWM hardware to create buzzer sound. I would use both. Comment is you need an more complete answer. Commented Nov 18, 2019 at 16:46
  • As t=0 you can safely remove the delay(t) lines ;-) And why do you set d=10 after you used it. Wouldn't it be better to set it before the for loop? You need nearly 300 steps to sweep up and ~ 300 steps to sweep down and for each step you let the LEDs flicker with a patern your eays are not fast enough to see. It that really your intention? I would expect you liked to see the sound sweeps and the LED blinking in parallel. The best way to achieve that is to remove the for loops, and do the things in parallel. See my answer. Commented Nov 18, 2019 at 18:17
  • @st2000, how do you want to make a siren with hardware PWM? Commented Nov 18, 2019 at 18:42
  • My bad @Juraj, the tone() function is already being used. So all this question needs is a state macing. Using the mills() function is a step in the correct direction if not a simple state machine already. A more general state machine solution might benefit the OP as it gives them the bases for more complex software challenges. Commented Nov 18, 2019 at 19:13

2 Answers 2

6

The following Code is not tested. You can take it as an example. If you find errors, it would be nice to report them, so I can correct my prog.

// here I just guess (10msec), I think you don't want a delay // of 0 as in your code. int blinkDelay = 10; long lastBlinkTime = 0; int patternSequence[] = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 2, 1, 2, 1, 2, 1, 2 }; int patternSize = 17; int actPattern = 0; int delActive = -1; int frequency = 635; int deltaFreq = 1; int toneDelay = 10; long lastBuzzTime = 0; void setup() { pinMode( 5, OUTPUT ) ; pinMode( 6, OUTPUT ) ; pinMode( 7, OUTPUT ) ; ledsOff(); buzzer( frequency ); } void loop() { int actTime = millis(); if ( ( actTime - lastBlinkTime ) > blinkDelay ) { if ( delActive > 0 ) { ledsOff(); } else { actPattern++; if( actPattern > ( patternSize - 1) ) actPattern = 0; pattern( patternSequence[ actPattern ] ); } delActive *= -1; lastBlinkTime = actTime; } if ( ( actTime - lastBuzzTime ) > toneDelay ) { frequency += deltaFreq; if ( frequency > 911 ) deltaFreq = -1; if ( frequency < 636 ) deltaFreq = 1; buzzer( frequency ); lastBuzzTime = actTime; } } void buzzer( int freq ) { //PIN 9 - Buzzer tone(9, freq); } void ledsOff() { digitalWrite( 5, LOW ); digitalWrite( 6, LOW ); digitalWrite( 7, LOW ); } void pattern( int num ) { switch ( num ) { case 0: ledsOff(); break; case 1: digitalWrite( 5, HIGH ); break; case 2: digitalWrite( 7, HIGH ); break; case 3: digitalWrite( 5, HIGH ); digitalWrite( 6, HIGH ); digitalWrite( 7, HIGH ); break; } } 

Update

I've tested the code at home on my esplora. It worked, but not for a long time. I had to change the timing logic, by using the method millis()directly. Now it works. Below is the new code; tested this time. I also introduced some constants on top, because the their names act as documentation ;-). And I experimented with the values. The actual values are my preferences, But I'm by far no Bethoven and can not say if this relly sounds like a police siren. At least, it sounds not like a german police siren which I know better. (No I'm meither a policement nor his/her customer ;-))

Because I tested the code on my Esplora, I had to change the Pin assignments (now out commented). In this copy I changed back to the original ones.

int blinkDelay = 100; long lastBlinkTime = 0; int patternSequence[] = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 2, 1, 2, 1, 2, 1, 2 }; int patternSize = 17; int actPattern = 0; int clearActive = -1; int lowerFreq = 680; int higherFreq = 840; int deltaFreq = 2; int toneDelay = 20; int toneDelayOffset = -1; long lastBuzzTime = 0; int actFreqStep = deltaFreq; int actFreq = lowerFreq; // orig pins int col1Pin = 5; int col2Pin = 6; int col3Pin = 7; int buzzerPin = 9; // esplora pins // int col1Pin = 5; // int col2Pin = 10; // int col3Pin = 9; // int buzzerPin = 6; void setup() { pinMode( col1Pin, OUTPUT ) ; pinMode( col2Pin, OUTPUT ) ; pinMode( col3Pin, OUTPUT ) ; // initialize LEDs off ledsOff( ); // and buzzer to the act frequency buzzer( actFreq ); } void loop() { if ( ( millis() - lastBlinkTime ) > blinkDelay ) { if ( clearActive > 0 ) { ledsOff(); } else { actPattern++; if( actPattern > ( patternSize - 1) ) actPattern = 0; pattern( patternSequence[ actPattern ] ); } clearActive *= -1; lastBlinkTime = millis(); } if ( ( millis() - lastBuzzTime ) > ( toneDelay + toneDelayOffset ) ) { actFreq += actFreqStep; if ( actFreq >= higherFreq ) { actFreqStep = -1 * deltaFreq; // down sweep is slower toneDelayOffset = -1; } if ( actFreq <= lowerFreq ) { actFreqStep = deltaFreq; toneDelayOffset = 0; } buzzer( actFreq ); lastBuzzTime = millis(); } } void buzzer( int freq ) { tone( buzzerPin, freq ); } void ledsOff() { digitalWrite( col1Pin, LOW ); digitalWrite( col2Pin, LOW ); digitalWrite( col3Pin, LOW ); } void pattern( int num ) { switch ( num ) { case 0: ledsOff(); break; case 1: // red digitalWrite( col1Pin, HIGH ); break; case 2: // blue digitalWrite( col3Pin, HIGH ); break; case 3: // white digitalWrite( col1Pin, HIGH ); digitalWrite( col2Pin, HIGH ); digitalWrite( col3Pin, HIGH ); break; } } 
2
  • It's working just like what I want to happen. Thanks Commented Nov 19, 2019 at 12:09
  • 2
    You're welcome. Please do not just copy and paste the prog. Try to understand why and how it works. The world needs more skilled people and you seems to be interested in the subject. I used some things, I learned in 25 years as a developer and they might be difficult for a beginner. If some of the code is unclear, please fell free to ask me here. I would be happy the help you understand and perhaps you find a hidden error, I've overseen. Commented Nov 19, 2019 at 12:42
3

Don't use delay(). You'll need to rewrite your sketch to use the millis() function to decide when the desired amount of time has passed. Search on "Arduino Blink Without Delay" for information.

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.