New way to avoid DELAY function

in this code, is it possible to remove delay() and just add a counter from 1 to 1000 to achieve the delay without losing the multitasking advantage ??

// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}

(deleted)

Multitasking, no.
As mentioned use BWD.
Read Robin2’s discussion.

//Simple BWD BlinkWithoutDelay examples
//
//Timer variables used
unsigned long currentMillis;
unsigned long pin13Millis;
unsigned long pin12Millis;
unsigned long SwitchMillis;
 
//if these are not changed in the sketch, they can be const
unsigned long debounceMillis = 50UL;  //50ms
unsigned long ledOnTime      = 500UL; //500ms seconds
 
byte lastSwitchState = HIGH;
byte buttonState     = HIGH;
 
//enable/disable flags
boolean flag13 = true;
boolean flag12 = false;
 
const byte Switch = 2; //pushed = LOW
 
//**********************************************************************
 
void setup()
{
  Serial.begin(9600);
 
  digitalWrite(13,LOW);
  pinMode(13, OUTPUT);
  
  digitalWrite(12,LOW);
  pinMode(12, OUTPUT);
 
  pinMode(Switch, INPUT_PULLUP); //pushed = LOW
 
} //  >>>>>>>>>>>>>> E N D  O F  s e t u p ( ) <<<<<<<<<<<<<<<<<
 
void loop()
{
  //save the current time
  currentMillis = millis();
 
  //*************************************
  //Heartbeat LED
  //Toggle LED on and off. Helps show if there is blocking code
  if (flag13 == true && currentMillis - pin13Millis >= ledOnTime)
  {
    pin13Millis = millis();            //re-initialize Timer
    digitalWrite(13,!digitalRead(13)); //toggle LED condition
  }
 
  //*************************************
  if (flag12 == true && currentMillis - pin12Millis >= 5*1000UL)
  {
    //Turn off pin 12
    digitalWrite(12,LOW); //Turn off LED
    flag12 = false;       //disable timing
  }
 
  //*************************************
  //is it time to check the switches?
  if (currentMillis - SwitchMillis >= debounceMillis)
  {
    //code here runs every debounceMillis ms
    SwitchMillis = millis(); //re-initilize Timer
    //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;   
 
  //check if this switch has changed state
  thisState = digitalRead(Switch);
  if (thisState != lastSwitchState)
  { 
    //update the switch state
    lastSwitchState = thisState; 
 
    //this switch position has changed so do some stuff
    //"LOW condition code"
    //has switch gone from HIGH to LOW?
    if(thisState == LOW)                         
    {
      //Do some LOW switch stuff here 
      flag12 = true;          //allow timing
      digitalWrite(12, HIGH); //turn on LED
      pin12Millis = millis(); //initialize Timer
    }
 
  } //END of Switch code
 
  //***************************************** 
  // similar code for other switches goes here
  //***************************************** 
 
} //END of checkSwitches()
 
//**********************************************************************
 
//======================================================================
//                      E N D  O F  C O D E
//======================================================================

.

#define NUM_ENTRIES(ARRAY)  (sizeof(ARRAY) / sizeof(ARRAY[0]))

const uint8_t           pinLED      = 13;   // on-board LED

const uint8_t           pinLED_1    = 33;   // user specified
const uint8_t           pinLED_2    = 32;   // user specified
const uint8_t           pinLED_3    = 31;   // user specified
const uint8_t           pinLED_4    = 30;   // user specified
const uint8_t           pinLED_5    = 29;   // user specified

const uint8_t           LED_OFF     = LOW;
const uint8_t           LED_ON      = HIGH;

const unsigned long     HALF_SECOND =  500UL;
const unsigned long     ONE_SECOND  = 1000UL;

const uint8_t           pinsLEDS[]  = { pinLED_1, pinLED_2, pinLED_3, pinLED_4, pinLED_5 };


class timerT
{
    const unsigned long     m_tmsPeriod;
    unsigned long           m_tmsPrevious;
    bool                    m_isTriggered;

public:

    // INSTANCE CONSTRUCTOR, USING INITIALISATION LIST
    timerT(unsigned long const tms) : m_tmsPeriod(tms), m_isTriggered(false)
    {
        m_tmsPrevious = millis();
    }

    void reset()
    {
        m_isTriggered   = false;
        m_tmsPrevious  += m_tmsPeriod;
    }

    bool is_expired()
    {
        if ( ! m_isTriggered )
        {
            m_isTriggered = ((millis() - m_tmsPrevious) >= m_tmsPeriod);
        }

        return m_isTriggered;
    }
};

void setup()
{
    pinMode(pinLED, OUTPUT);
    digitalWrite(pinLED, LED_ON);

    for ( size_t i = NUM_ENTRIES(pinsLEDS); i--; )
    {
        pinMode(pinsLEDS[i], OUTPUT);
    }
}

void loop()
{
    // ... BLINK SINGLE LED ...
    static timerT   timerLED(ONE_SECOND);

    if ( timerLED.is_expired() )
    {
        digitalWrite(pinLED, !digitalRead(pinLED));

        timerLED.reset();
    }
    

    // ... SEQUENCE OVER AN ARRAY OF LEDS ...

    const unsigned long tmsBLINK    = HALF_SECOND / NUM_ENTRIES(pinsLEDS)
    static timerT       timerLEDS   = timerT(tmsBLINK);
    static size_t       iLED        = NUM_ENTRIES(pinsLEDS) - 1;

    if ( timerLEDS.is_expired() )
    {
        iLED = ((iLED + 1) % NUM_ENTRIES(pinsLEDS));

        for ( size_t i = NUM_ENTRIES(pinsLEDS); i--; )
        {
            digitalWrite(pinsLEDS[i], ((iLED == i) ? LED_ON : LED_OFF));
        }

        timerLEDS.reset();
    }
}

in this code,

is it possible to remove delay()
YES

and just add a counter from 1 to 1000
NO - you need different count values for same time delay

to achieve the delay
YES

without losing the multitasking advantage ??

NO , you cannot lose what you did not have in first place

Are we having fun yet?

Jim

Use timer library :wink:

You Will simply call t.pulse(pin,time,start value);

Have a look: http://playground.arduino.cc/Code/Timer

guys you are taking my quesion literally..i meant in case you have other tasks together with blink in the same code..things like servo s moving & sound card playing clips..can we replace Delay with a count function to e Delay does not disrupt other tasks,

guys you are taking my quesion literally.

Do you imagine the compiler won't do that?

in this code, is it possible to remove delay() and just add a counter from 1 to 1000 to achieve the delay without losing the multitasking advantage ??

It sounds like you are thinking of breaking down the 1 second delay() into 1000 1 millisecond delay()s. Don’t do that. Use the value of millis() each time through loop() to determine whether 1 second has elapsed. This is the famous Blink Without Delay technique.

Goldenshuttle:
in this code, is it possible to remove delay() and just add a counter from 1 to 1000 to achieve the delay without losing the multitasking advantage ??

No

While it was common practice about 40 years ago (when Fortran was the leading compiler language and BASIC was the leading interpreter language) to use empty counting loops as a busy-waiting-delay in programs, it will not even work in optimizing compilers like AVR GCC nowadays.

The compiler will see that the variable is never "ever used" in whatever way and completely

  • optimize out the counting variable
  • and even optimize out the empty loop code from the program before uploading to the board.

Empty counting loops are good for nothing, not even for a bad replacement of delay().

BTW: Even the slowest AVR Atmega will count up by much more than 1000 in one second while nothing else is due to be done in the program.

Cooperative multitasking and effective programs are not a matter of using "delay()" or any other busy-waiting function in the code, it's a matter of arranging a suitable and effective programming logic.

jurs:
...
The compiler will see that the variable is never "ever used" in whatever way and completely

  • optimize out the counting variable
  • and even optimize out the empty loop code from the program before uploading to the board.
    ...

Maybe we're using different compiler then...

for ( uint16_t volatile d=0xffff; d>0; d-- )
  ;

Empty counting loops are good for nothing, not even for a bad replacement of delay().

?

The below empty loop forms the basis for practically every Arduino (µC ?) program:

for (;;)
  loop();

All in fun...

Empty counting loops.

volatile is a direction to the compiler NOT to optimise-away the variable references.

(Not really at all funny)

JimEli:
Maybe we're using different compiler then...

Maybe.
But surely the "volatile" declaration of counting variable d will prevent optimizing out the d variable from the compiled code..

JimEli:
The below empty loop forms the basis for practically every Arduino (µC ?) program:

for (;;)

loop();




All in fun...

That loop is NOT empty, it's calling loop(). Now you confuse endless loops with empty loops :wink: