element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Arduino Tutorials
  • Products
  • Arduino
  • Arduino Tutorials
  • More
  • Cancel
Arduino Tutorials
Blog A non blocking delay
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Arduino Tutorials to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Workshopshed
  • Date Created: 5 Jun 2014 8:45 PM Date Created
  • Views 9344 views
  • Likes 4 likes
  • Comments 15 comments
  • delay
  • code
  • c++
  • arduino
Related
Recommended

A non blocking delay

Workshopshed
Workshopshed
5 Jun 2014

The "hello world" of the Arduino is the blink sketch. This demonstrates that your board is working by blinking an LED, typically the on-board LED attached to pin13 but it has a problem.

The code uses the "delay" function which waits the desired number of milliseconds before continuing with the next line of the code.

 

int led = 13;

void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);     
}

void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
  //Code here runs once every 2 seconds
}

 

The problem with the delay function is that nothing else happens whilst the delay is running. This is not only wasteful of the limited processing power of the microcontroller but it also makes any other routines you are using potentially unresponsive. There are several approaches to this problem such as using interrupts. The approach I selected to use a class which implement the non blocking delay.

This delay is implemented with a variable and two function, the first sets the delay and the second checks if the delay has finished.

 

Here's how it is used:

#include "Delay.h"

int led = 13;
int ledstate = HIGH;
NonBlockDelay d;

void setup() {                
  pinMode(led, OUTPUT);  
}

// the loop routine runs over and over again forever:
void loop() {
  if (d.Timeout()) {
    digitalWrite(led, ledstate);
    ledstate = ledstate == LOW ? HIGH : LOW; //toggle state
    d.Delay(1000);
  } 
  //Code here runs frequently
}

 

Delay.h

#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
class NonBlockDelay {
    unsigned long iTimeout;
  public:
    void Delay (unsigned long);
    bool Timeout (void);
    unsigned long Time(void);
};

 

Delay.cpp

#include "Delay.h"
void NonBlockDelay::Delay (unsigned long t)
{
  iTimeout = millis() + t;
  return;
};
bool NonBlockDelay::Timeout (void)
{
  return (iTimeout < millis());
}
unsigned long NonBlockDelay::Time(void)
 {
   return iTimeout;
 }

 

My reason for wrapping the delay in a class is so that I can use it for twice for each of the steppers in my clock project and so my loop will end up as a series of non blocking calls.

 

void loop() {
     CheckInput();
     ReadClock();
     CalcHandPositions();
     SetStepperPositions();
     StepMotors();
}

  • Sign in to reply

Top Comments

  • jadew
    jadew over 11 years ago in reply to Workshopshed +1
    Hey Andy, Yes, you can put those 3 lines inside a header file and include it wherever you need it. I know why you went for the class, it's the natural way to go when you're coming from higher level environments…
Parents
  • celem
    celem over 9 years ago

    I altered Andy Clark's solution to better suit my needs. While I kept the Timeout member, I am not using it. I modified Delay() so that it stands alone and only executes the code after the timer expires. Here is what I am using. Note, all three files are concatenated together for this comment.

     

    /**
     * nonblockdelay2.ino
     * 
     * example "blink" program
     *
     */
    
    
    #include "Delay.h"
    
    
    int led = 13;
    int ledstate = HIGH;
    static NonBlockDelay d;
    
    
    void setup()
    {                
      pinMode(led, OUTPUT);
    }
    
    
    // the loop routine runs over and over again forever:
    void loop()
    {
      if(d.Delay(1000))
      {
        ledstate = (ledstate == LOW ? HIGH : LOW); //toggle state
        digitalWrite(led, ledstate);
      }
      //Code here runs frequently
    }
    
    
    //---------------------
    /**
     * Delay.cpp
     *
     */
    
    #include "Delay.h"
    
    
    // Set iTimeout to current millis plus milliseconds to wait for
    /**
     * Called with milliseconds to delay.
     * Return true if timer expired
     * 
     */
    bool NonBlockDelay::Delay (unsigned long t)
    {
      if(TimingActive)
      {
        if((millis() >iTimeout)){
          TimingActive = 0;
          return(1);
        }
        return(0);
      }
      iTimeout = millis() + t;
      TimingActive = 1;
      return(0);
    };
    
    
    
    
    // returns true if timer expired
    bool NonBlockDelay::Timeout (void)
    {
      if(TimingActive){
        if((millis() >iTimeout)){
          TimingActive = 0;
          iTimeout = 0;
          return(1);
        }
      }
      return(false);
    }
    
    
    // Returns the current timeout value in milliseconds
    unsigned long NonBlockDelay::Time(void)
     {
       return iTimeout;
     }
    
    
    //------------------------------
    /**
     * Delay.h
     *
     */
    
    #if defined(ARDUINO) && ARDUINO >= 100
    #include <Arduino.h>
    #else
    #include <WProgram.h>
    #endif
    class NonBlockDelay {
        unsigned long iTimeout;
        bool TimingActive = 0;
      public:
        bool Delay (unsigned long);
        bool Timeout (void);
        unsigned long Time(void);
    };
    //-------------------------

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Workshopshed
    Workshopshed over 9 years ago in reply to celem

    Hi Edward, nice idea, thanks for the comment.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • Workshopshed
    Workshopshed over 9 years ago in reply to celem

    Hi Edward, nice idea, thanks for the comment.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
No Data
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube