0

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. – st2000 Nov 18 '19 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. – Peter Paul Kiefer Nov 18 '19 at 18:17
  • @st2000, how do you want to make a siren with hardware PWM? – Juraj Nov 18 '19 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. – st2000 Nov 18 '19 at 19:13
4

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 – Nydigorith Nov 19 '19 at 12:09
  • 1
    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. – Peter Paul Kiefer Nov 19 '19 at 12:42
1

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

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.