Delay without using delay

Hi there,

I'm trying to construct two functions with delay lines, unfortunately this will stop everything. I have cut out everything but the actual lines that need modification.

I know about the millis() function, but how do i override the if(digitalRead(x) == LOW) function while waiting for the millis?

le code:

void setup() {
pinMode(4, INPUT);
digitalWrite(5, HIGH);
pinMode(5, INPUT);
digitalWrite(5, HIGH);
pinMode(8, OUTPUT);
digitalWrite(8, LOW);
pinMode(9, OUTPUT);
digitalWrite(9, LOW);
pinMode(10, OUTPUT);
digitalWrite(10, LOW);
pinMode(11, OUTPUT);
digitalWrite(11, LOW);
}

void loop() {
if (digitalRead(5) == LOW) {
digitalWrite(8, HIGH);
delay(40);
digitalWrite(8, LOW);
delay(75);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
delay(20);
digitalWrite(10, LOW);
digitalWrite(9, LOW);}

if (digitalRead(4) == LOW) {
digitalWrite(9, HIGH);
delay(40);
digitalWrite(9, LOW);
delay(75);
digitalWrite(10, HIGH);
digitalWrite(8, HIGH);
delay(20);
digitalWrite(10, LOW);
digitalWrite(8, LOW);}
}

An example to stir the juices:

//Blink without Delay skeleton 
//4 examples demonstrated
//

//LED wiring options
//=============================================
//Depending which way your LEDs are wired, uncomment the next line.
//#define PlusEqualsON 

#ifdef PlusEqualsON
//wired so +5V turns LED ON
#define ledON  HIGH
#define ledOFF LOW
//=========================
#else
//wired so +5V turns LED OFF
#define ledON  LOW
#define ledOFF HIGH
//=========================
#endif

//switch wiring options
//=============================================
//Depending which way your switches are wired, uncomment the next line.
#define PushEqualsLOW 

#ifdef PushEqualsLOW 
//pushing the switch makes pin LOW
#define Pushed   LOW
#define Released HIGH
//=========================
#else
//pushing the switch makes pin HIGH
#define Pushed   HIGH
#define Released LOW
//=========================
#endif

//=============================================
unsigned long currentMillis;
unsigned long pin13Millis;
unsigned long pin12Millis;
unsigned long pin11Millis;
unsigned long SwitchMillis;

//if these are not changed in the sketch, they can be const
unsigned long debounceMillis = 100UL;     //100ms
unsigned long ledOnTime      = 5*1000UL;  //5 seconds

byte laststartSwitchState    = HIGH;
byte buttonState             = HIGH;
byte counter                 = 0;

//the following are enable/disable flags
//some of these might not be used in this sketch
boolean flag13 = true;
boolean flag12 = true;
boolean flag11 = true;
boolean flag10 = true;

const byte startSwitch = 2; //pushed = LOW
const byte testSwitch  = 3; //pushed = LOW

//**********************************************************************

void setup()
{
  Serial.begin(9600);
  
  digitalWrite(13,ledOFF);
  pinMode(13, OUTPUT); 

  digitalWrite(12,ledOFF);
  pinMode(12, OUTPUT);

  digitalWrite(11,ledOFF);
  pinMode(11, OUTPUT);
  
  digitalWrite(10,ledOFF);
  pinMode(10, OUTPUT);

  pinMode(startSwitch, INPUT_PULLUP); //pushed = LOW
  pinMode(testSwitch,  INPUT_PULLUP); //pushed = LOW

} //  >>>>>>>>>>>>>> E N D  O F  s e t u p ( ) <<<<<<<<<<<<<<<<<

void loop()
{
  //save the current time
  currentMillis = millis();

  //************************************* E x a m p l e  1
  //toggle pin 13 every 200mS
  //has 200ms or more gone by?
  if (currentMillis - pin13Millis >= 200UL)
  {
    //code here runs every 200ms
    //get ready for next iteration
    pin13Millis = pin13Millis + 200UL;
    //toggle pin 13
    digitalWrite(13,!digitalRead(13));
  }

  //************************************* E x a m p l e  2
  //at power up, pin 12 LED goes ON, after 3 seconds goes OFF and stays OFF
  //could be used as a powerup reset signal
  if (flag12 == true && currentMillis - pin12Millis <= 3000UL)
  {
    //code here runs for 3 seconds after power up, then stops
    digitalWrite(12,ledON);
  }
  else
  {
    digitalWrite(12,ledOFF);
    //disable further pin 12 control
    flag12 = false;
  }

  //************************************* E x a m p l e  3
  //if testSwitch is pushed and released
  //pin 11 LED goes ON for 5 seconds, then goes OFF 
  buttonState = digitalRead(testSwitch);
  
  //are we are allowed to check the switch and is it pressed?
  if(flag11 == true && buttonState == Pushed)
  {    
    //enable timing of LED on pin 11
    flag11 = false; //false --> timing is enabled
    //turn LED ON
    digitalWrite(11,ledON);
    //record the time LED turned ON
    pin11Millis = currentMillis;
  }
    
  //are we allowed and is it time to control pin 11
  if (flag11 == false && currentMillis - pin11Millis >= ledOnTime)
  {
    //if enabled, code here runs after ledOnTime ms goes by
    digitalWrite(11,ledOFF);
    //allow switch press detection again
    flag11 = true; //true --> switch monitoring is enabled
  }

  //************************************* E x a m p l e  4
  //is it time to check the switches?
  //in particular, pushing startSwitch will turn ON/OFF (toggle) an output pin 10
  //is it time to check the switches
  if (currentMillis - SwitchMillis >= debounceMillis)
  {
    //code here runs every debounceMillis ms
    //get ready for the next iteration
    SwitchMillis += debounceMillis; 
    //go and check the switches
    checkSwitches();    
  } 

  //*********************************
  //put other non-blocking stuff here
  //*********************************

} //  >>>>>>>>>>>>>> E N D  O F  l o o p ( ) <<<<<<<<<<<<<<<<<


//======================================================================
//                      F U N C T I O N S
//======================================================================


//****************** c h e c k S w i t c h e s ( ) *********************
//switches are checked every debounceValue milli seconds 
//no minimum switch press time is validated with this code (i.e. No glitch filter)
void checkSwitches()  
{
  //re-usable for all the switches  
  boolean thisState;    

  //************************************* E x a m p l e  Push ON push OFF (toggle)   
  //check if this switch has changed state
  thisState = digitalRead(startSwitch);
  if (thisState != laststartSwitchState)
  {  
    //update the switch state
    laststartSwitchState = thisState;  

    //this switch position has changed so do some stuff

    //"HIGH condition code"
    //switch went from LOW to HIGH
    if(thisState == HIGH)        
    {
      //Do some HIGH switch stuff here
    }

    //"LOW condition code"
    //switch went from HIGH to LOW
    else                          
    {
      //Do some LOW switch stuff here  
      digitalWrite(10, !digitalRead(10));
      //print number of pushes
      counter++;
      Serial.println(counter);
    }

  } //END of startSwitch code

  //*****************************************  
  //similar code for other switches goes here 
  //*****************************************  

} //END of checkSwitches()

//**********************************************************************

//======================================================================
//                      E N D  O F  C O D E
//======================================================================

Your sequence is missing a delay after the delay(20) sequence to prevent it from starting over immediately I added a delay till 1 second to help with the rapid switching of LED’s
The delays are in milliseconds and your entire sequence is over in 135 milliseconds which is faster than most can comprehend.
here is my code with lots of examples of no delay() timer in use with your sequence Hope this helps and you can have fun fitting it into your project
My altered sequence is:

  • nothing will happen until pin 4 or 5 is LOW
  • Pins 4&5 have a 1/2 second debounce delay before retesting
  • Pin 5 has a latch that requires you to release pin 5 before you can trigger pin 5 again
  • Pin 4 will automatically retrigger after debounce delay
  • Modes can switch at any time by just triggering the other pin or can be reset also
void setup() {
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(8, OUTPUT);
  digitalWrite(8, LOW);
  pinMode(9, OUTPUT);
  digitalWrite(9, LOW);
  pinMode(10, OUTPUT);
  digitalWrite(10, LOW);
  pinMode(11, OUTPUT);
  digitalWrite(11, LOW);

  Serial.begin(115200);
  Serial.println("Fast Mode no delay timers");
  delay(1000);
}

void loop() {
  static int Counter;
  static int Mode;
  static unsigned long MillisTimer;
  if ((unsigned long) (millis() - MillisTimer) >= (1)) { // each Millisecond
    MillisTimer += (1);
    Counter++;
  }

  static unsigned long SpamTimer;
  if ( (unsigned long)(millis() - SpamTimer) >= (100)) { // 10 times a second
    SpamTimer = millis();
    Serial.print("4:");
    Serial.print(digitalRead(4));
    Serial.print(" 5:");
    Serial.print(digitalRead(5));
    Serial.print(" 8:");
    Serial.print(digitalRead(8));
    Serial.print(" 9:");
    Serial.print(digitalRead(9));
    Serial.print(" 10:");
    Serial.print(digitalRead(10));
    Serial.print(" 11:");
    Serial.print(digitalRead(11));
    Serial.print("\t Mode:");
    Serial.print(Mode);
    Serial.print("\t Counter:");
    Serial.print(Counter);
    Serial.println();
  }
  static int Pin5Latch;
  static unsigned long DebounceTimer;
  if ((!Pin5Latch) && (digitalRead(5) == LOW) && ((unsigned long)(millis() - DebounceTimer) >= (500))) { // half a second
    DebounceTimer = millis();
    Mode = 1;
    Counter = 0;
    Pin5Latch = 1;
    Serial.println("Pin 5 LOW");
  } else if(digitalRead(5) == HIGH) Pin5Latch = 0; 
  if ((digitalRead(4) == LOW) && ((unsigned long)(millis() - DebounceTimer) >= (500))) { // half a second
    DebounceTimer = millis();
    Mode = 2;
    Counter = 0;
    Serial.println("Pin 4 LOW");
  } 

  if (Mode == 1) {
    switch (Counter) {
      case 0:
      case 1:
        digitalWrite(8, HIGH);
        break;
      case 40: //  delay(40);
        digitalWrite(8, LOW);
        break;
      case 115: // 40 + 75 delay(75);
        digitalWrite(10, HIGH);
        digitalWrite(9, HIGH);
        break;
      case 135: // 40 + 75 + 20 delay(20);
        digitalWrite(10, LOW);
        digitalWrite(9, LOW);
        break;
      case 1000: //  at 1 second start over <<< Added to your sequence
        Counter = 0;
    }
  } else if (Mode == 2) {
    switch (Counter) {
      case 0:
      case 1:
        digitalWrite(9, HIGH);
        break;
      case 40:// delay(40);
        digitalWrite(9, LOW);
        break;
      case 115: // 40 + 75 delay(75);
        digitalWrite(10, HIGH);
        digitalWrite(8, HIGH);
        break;
      case 135: // 40 + 75 + 20 delay(20);
        digitalWrite(10, LOW);
        digitalWrite(8, LOW);
      case 1000: //  at 1 second start over <<< Added to your sequence
        Counter = 0;
    }
  } else Counter = 0;
}

Snake____1: Hi there,

I'm trying to construct two functions with delay lines, unfortunately this will stop everything. I have cut out everything but the actual lines that need modification.

I know about the millis() function, but how do i override the if(digitalRead(x) == LOW) function while waiting for the millis?

le code:

void setup() {
pinMode(4, INPUT);
digitalWrite(5, HIGH);
pinMode(5, INPUT);
digitalWrite(5, HIGH);
pinMode(8, OUTPUT);
digitalWrite(8, LOW);
pinMode(9, OUTPUT);
digitalWrite(9, LOW);
pinMode(10, OUTPUT);
digitalWrite(10, LOW);
pinMode(11, OUTPUT);
digitalWrite(11, LOW);
}

void loop() { if (digitalRead(5) == LOW) { digitalWrite(8, HIGH); delay(40); digitalWrite(8, LOW); delay(75); digitalWrite(10, HIGH); digitalWrite(9, HIGH); delay(20); digitalWrite(10, LOW); digitalWrite(9, LOW);}

if (digitalRead(4) == LOW) { digitalWrite(9, HIGH); delay(40); digitalWrite(9, LOW); delay(75); digitalWrite(10, HIGH); digitalWrite(8, HIGH); delay(20); digitalWrite(10, LOW); digitalWrite(8, LOW);} }

After trying to solve this I came to realize that what you have is "turn on / keep on / turn off" sequences. Pretty trivial to do without using delay - time driven state machine AKA BWD. You have a sample code posted here. The real issue is the requirement / code you have deleted. So what is the task when these "on/off" sequences are going on ? The preset code does nothing but runs inside loop() when there are no valid inputs to these "delay sequences". Jim

PS Maybe you want something like this ? if input x in low do { blink without delay } while input x is high else do something else

zhomeslice:

WOW! You really know this, this is going to be fun to fit in to my project. Thank You!

julyjim:

This is going to be code for a manual transmission with clutch control.

Complete code is attached, or as complete as it is now… “message was over 9000 characters”

Still missing RPM comparator and clutch control…

up_dn_shift.ino (11.6 KB)