Need help with delay function

Somewhat new to arduino. Im currently building an alerting system for our fire house. Basic jist of what im doing is using the alert signal from a pager to trigger the system and close a series of relays and delay based on function of said relay. I have pasted the code below . The only part im looking for help on is if another alert comes in before all delays are satisfied I need the code to start over. The code currently works, however it will ignore any further input until all of the delays have completed. Thank you for any assistance.

}Use code tags to format code for the forum

int SOUND=10;

int ALERTLIGHT=9;

int BUNKLIGHT=8;

int SPEAKER=7;

int alert=2;

int sounddelay=3000;

int alertlightdelay=6000;

int bunkdelay=10000;

void setup() {

// put your setup code here, to run once:

Serial.begin (9600);

pinMode (SOUND, OUTPUT);

pinMode (ALERTLIGHT, OUTPUT);

pinMode (SPEAKER, OUTPUT);

pinMode (BUNKLIGHT, OUTPUT);

pinMode (alert, INPUT);

digitalWrite (SOUND, HIGH);

digitalWrite (ALERTLIGHT, HIGH);

digitalWrite (BUNKLIGHT, HIGH);

digitalWrite (SPEAKER, HIGH);

digitalWrite (alert, HIGH);

}

void loop() {

// put your main code here, to run repeatedly:

byte inputPulse=digitalRead(alert);

if (inputPulse == HIGH){

digitalWrite (SOUND, LOW);

digitalWrite (ALERTLIGHT, LOW);

digitalWrite (BUNKLIGHT, LOW);

digitalWrite (SPEAKER, LOW);

delay(sounddelay);

digitalWrite (SOUND, HIGH);

delay(alertlightdelay);

digitalWrite (ALERTLIGHT, HIGH);

delay(bunkdelay);

digitalWrite (SPEAKER, HIGH);

digitalWrite (BUNKLIGHT, HIGH);

}

}

Welcome to the forum

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the < CODE/ > icon above the compose window) to make it easier to read and copy for examination

https://forum.arduino.cc/t/how-to-get-the-best-out-of-this-forum

This is the easiest way to tidy up the code and add the code tags

Start by tidying up your code by using Tools/Auto Format in the IDE to make it easier to read. Then use Edit/Copy for Forum and paste what was copied in a new reply. Code tags will have been added to the code to make it easy to read in the forum thus making it easier to provide help.

You will need to remove all of the delay()s from your sketch in order to do what you want because during a delay() nothing else can happen

Your code appears to consist of 3 stages or states, each with a different delay period. This could be implemented as a state machine that used millis() to provide non blocking timing. This would allow the input to be read frequently without waiting for the sound/noise/etc to time out

See Using millis() for timing. A beginners guide, Several things at the same time and the BlinkWithoutDelay example in the IDE for examples of how to use millis() for timing

What is your programming experience ?

Very little

int SOUND = 10;
int ALERTLIGHT = 9;
int BUNKLIGHT = 8;
int SPEAKER = 7;
int alert = 2;
int sounddelay = 3000;
int alertlightdelay = 6000;
int bunkdelay = 10000;






void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);
  pinMode(SOUND, OUTPUT);
  pinMode(ALERTLIGHT, OUTPUT);
  pinMode(SPEAKER, OUTPUT);
  pinMode(BUNKLIGHT, OUTPUT);
  pinMode(alert, INPUT);
  digitalWrite(SOUND, HIGH);
  digitalWrite(ALERTLIGHT, HIGH);
  digitalWrite(BUNKLIGHT, HIGH);
  digitalWrite(SPEAKER, HIGH);
  digitalWrite(alert, HIGH);
}

void loop() {
  // put your main code here, to run repeatedly:
  byte inputPulse = digitalRead(alert);
  if (inputPulse == HIGH) {

    digitalWrite(SOUND, LOW);
    digitalWrite(ALERTLIGHT, LOW);
    digitalWrite(BUNKLIGHT, LOW);
    digitalWrite(SPEAKER, LOW);
    delay(sounddelay);
    digitalWrite(SOUND, HIGH);
    delay(alertlightdelay);
    digitalWrite(ALERTLIGHT, HIGH);
    delay(bunkdelay);
    digitalWrite(SPEAKER, HIGH);
    digitalWrite(BUNKLIGHT, HIGH);
  }
}

Start by doing some research on state machines. Basically the program can be in one of several states and only the code for that state is executed along with code that code that is executed unconditionally

A convenient way to program this is by using switch/case where each case is a state in the system. This probably sounds like gobbledegook to you ! I could write the code for your project for you, as could many other users here, but you will learn nothing.

Here is a small sketch demonstrating the use of a state machine. It runs continuously and switches between 2 states. You could run any code in either state but as written all it does is to print a message. You can put any non blocking code that you want into loop() such as reading an input and starting the state machine in any state that you want

unsigned long currentTime;
unsigned long startTime;
unsigned long period;

enum states
{
    actionA,
    actionB
};
byte currentState = actionA;

void setup()
{
    Serial.begin(115200);
    period = 5000;
    Serial.println("starting actionA");
    startTime = millis();
}

void loop()
{
    currentTime = millis();
    switch (currentState)
    {
        case actionA:
            if (currentTime - startTime >= period)  //if the period ended ?
            {
                currentState = actionB;   //switch states
                startTime = currentTime;  //action started now
                period = 2000;            //set the period for the action
                Serial.println("switching to actionB");
            }
            break;

        case actionB:
            if (currentTime - startTime >= period)  //if the period ended ?
            {
                currentState = actionA;   //switch states
                startTime = currentTime;  //action started now
                period = 2000;            //set the period for the action
                Serial.println("switching to actionA");
            }
            break;
    }
}

No doubt you will have questions so feel free to ask

now my mind is mush....appreciate the willingness to help here is my latest attempt which kicked back errors

int SOUND = 10;
int ALERTLIGHT = 9;
int BUNKLIGHT = 8;
int SPEAKER = 7;
int alert = 2;

unsigned long SOUNDOnTIME;
unsigned long ALERTOnTIME;
unsigned long BUNKLIGHTOnTIME;
unsigned long SPEAKEROnTIME;

bool SOUNDOn;
bool ALERTOn;
bool BUNKLIGHTOn;
bool SPEAKEROn;





void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);
  pinMode(SOUND, OUTPUT);
  pinMode(ALERTLIGHT, OUTPUT);
  pinMode(SPEAKER, OUTPUT);
  pinMode(BUNKLIGHT, OUTPUT);
  pinMode(alert, INPUT);


  SOUNDOn = false;
  ALERTOn = false;
  BUNKLIGHTOn = false;
  SPEAKEROn = false;
}

void loop() {
  if (digitalRead(alert) == HIGH) {
    digitalWrite(SOUND, HIGH);
    SOUNDOn = true;
    SOUNDOnTIME = millis(3000);
  }
  if (digitalRead(alert) == HIGH) {
    digitalWrite(ALERTLIGHT, HIGH);
    ALERTOn = true;
    ALERTOnTIME = millis(6000);
  }
  if (digitalRead(alert) == HIGH) {
    digitalWrite(SPEAKER, HIGH);
    SPEAKEROn = true;
    SPEAKEROnTIME = millis(10000);
  }
  if (digitalRead(alert) == HIGH) {
    digitalWrite(BUNKLIGHT, HIGH);
    BUNKLIGHTOn = true;
    BUNKLIGHTOnTIME = millis(10000);
  }
}
C:\Users\dketc\AppData\Local\Temp\.arduinoIDE-unsaved2024224-4268-rdjdqv.ae3jn\sketch_mar24a\sketch_mar24a.ino: In function 'void loop()':
C:\Users\dketc\AppData\Local\Temp\.arduinoIDE-unsaved2024224-4268-rdjdqv.ae3jn\sketch_mar24a\sketch_mar24a.ino:42:30: error: too many arguments to function 'long unsigned int millis()'
     SOUNDOnTIME = millis(3000);
                              ^
In file included from C:\Users\dketc\AppData\Local\Temp\arduino\sketches\D591894DDF2D98349832237E98C87EDC\sketch\sketch_mar24a.ino.cpp:1:0:
C:\Users\dketc\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\cores\arduino/Arduino.h:141:15: note: declared here
 unsigned long millis(void);
               ^~~~~~
C:\Users\dketc\AppData\Local\Temp\.arduinoIDE-unsaved2024224-4268-rdjdqv.ae3jn\sketch_mar24a\sketch_mar24a.ino:47:30: error: too many arguments to function 'long unsigned int millis()'
     ALERTOnTIME = millis(6000);
                              ^
In file included from C:\Users\dketc\AppData\Local\Temp\arduino\sketches\D591894DDF2D98349832237E98C87EDC\sketch\sketch_mar24a.ino.cpp:1:0:
C:\Users\dketc\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\cores\arduino/Arduino.h:141:15: note: declared here
 unsigned long millis(void);
               ^~~~~~
C:\Users\dketc\AppData\Local\Temp\.arduinoIDE-unsaved2024224-4268-rdjdqv.ae3jn\sketch_mar24a\sketch_mar24a.ino:52:33: error: too many arguments to function 'long unsigned int millis()'
     SPEAKEROnTIME = millis(10000);
                                 ^
In file included from C:\Users\dketc\AppData\Local\Temp\arduino\sketches\D591894DDF2D98349832237E98C87EDC\sketch\sketch_mar24a.ino.cpp:1:0:
C:\Users\dketc\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\cores\arduino/Arduino.h:141:15: note: declared here
 unsigned long millis(void);
               ^~~~~~
C:\Users\dketc\AppData\Local\Temp\.arduinoIDE-unsaved2024224-4268-rdjdqv.ae3jn\sketch_mar24a\sketch_mar24a.ino:57:35: error: too many arguments to function 'long unsigned int millis()'
     BUNKLIGHTOnTIME = millis(10000);
                                   ^
In file included from C:\Users\dketc\AppData\Local\Temp\arduino\sketches\D591894DDF2D98349832237E98C87EDC\sketch\sketch_mar24a.ino.cpp:1:0:
C:\Users\dketc\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\cores\arduino/Arduino.h:141:15: note: declared here
 unsigned long millis(void);
               ^~~~~~

exit status 1

Compilation error: too many arguments to function 'long unsigned int millis()'

Look closely at my example to see how to set the start time

Hi @dketcham ,

Welcome to the forum..

maybe something like this..

int SOUND = 10;
int ALERTLIGHT = 9;
int BUNKLIGHT = 8;
int SPEAKER = 7;
int alert = 2;
int sounddelay = 3000;
int alertlightdelay = 6000;
int bunkdelay = 10000;



byte sysState = 0; //0 = off
unsigned long lastDelay = 0;
byte lastPulse = 0;


void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);
  pinMode(SOUND, OUTPUT);
  pinMode(ALERTLIGHT, OUTPUT);
  pinMode(SPEAKER, OUTPUT);
  pinMode(BUNKLIGHT, OUTPUT);
  pinMode(alert, INPUT);// button needs pull down resistor..
  digitalWrite(SOUND, HIGH);
  digitalWrite(ALERTLIGHT, HIGH);
  digitalWrite(BUNKLIGHT, HIGH);
  digitalWrite(SPEAKER, HIGH);
  //digitalWrite(alert, HIGH); no,no..
}

void loop() {
  // put your main code here, to run repeatedly:

unsigned long now = millis();

  byte inputPulse = digitalRead(alert);
  if (inputPulse != lastPulse) {
    lastPulse = inputPulse;
    if (inputPulse == HIGH){
      sysState = 1;
    }
  } 

if (sysState > 0){
    switch (sysState){
      case 1: digitalWrite(SOUND, LOW);
              digitalWrite(ALERTLIGHT, LOW);
              digitalWrite(BUNKLIGHT, LOW);
              digitalWrite(SPEAKER, LOW);
              sysState++;
              lastDelay = now;
             break;
      case 2: if (now - lastDelay >= sounddelay){sysState++;} break;
      case 3: digitalWrite(SOUND, HIGH); sysState++; lastDelay = now; break;
      case 4: if (now - lastDelay >= alertlightdelay){ sysState++;} break;
      case 5: digitalWrite(ALERTLIGHT, HIGH); sysState++; ;lastDelay = now; break;
      case 6: if (now - lastDelay >= bunkdelay){ sysState++;} break;
      case 7: digitalWrite(SPEAKER, HIGH);
              digitalWrite(BUNKLIGHT, HIGH);
              sysState = 0;
              break;
    } //switch
} //if state > 0
}

good luck.. ~q

That worked , thank you. Now time to read and understand it so in the future I know what the hell im looking at ! Thanks again

1 Like

Thank you for the assistance. Lots of reading to do to fully understand it

running in to an issue where the last set of relays (speaker and bunklight are not switching off). If I adjust the delay down to say 2000 miliseconds it works, if i go over the thousand mark (to 10000 or above ) the relays stay closed

are you overflowing the int, make it a long instead??

~q

so make it an unsigned long is what you're saying?

or just long..
int on uno or mega is 2 bytes..
unsigned int might do it too..

~q

ok ill see if i can figure that out

Thanks again for your input

you're welcome..

can add some serial prints to see what's going on inside..
aides in debugging things..

project in a simulator..

good luck.. ~q

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