How can I control things without using delay?

I have always hated that you couldn't do other things while you used the delay(); function. However, I want to blink a LED or do whatever while using serial, but how does this work? How do I do this without using the delay function?

• isn't there a separate Arduino area? Find it strange to see Programming-related stuff in Electrical Engineering area (apart from the question involving a LED that is) – George Birbilis Feb 6 '16 at 9:51
• @GeorgeBirbilis This question is almost three years old, long before there was an Arduino stackexchange. – pipe Feb 6 '16 at 15:18
• @pipe thing is I came here from the same question at Arduino stackexchange and there was a comment there that it had been copied here too or something like that – George Birbilis Feb 8 '16 at 18:24

Interrupts are a common way to get things done while something else is going on. In the example below, the LED is blinking without using delay(). Whenever Timer1 fires, the interrupt service routine (ISR) isrBlinker() is called. It switches the LED on/off.

To show that other things can simultaneously happen, loop() repeatedly writes foo/bar to the serial port independent of the LED blinking.

#include "TimerOne.h"

int led = 13;

{
static bool on = false;
digitalWrite( led, on ? HIGH : LOW );
on = !on;
}

void setup() {
Serial.begin(9600);
Serial.flush();
Serial.println("Serial initialized");

pinMode(led, OUTPUT);

Timer1.initialize(1000000);
}

void loop() {
Serial.println("foo");
delay(1000);
Serial.println("bar");
delay(1000);
}


This is a very simple demo. ISRs can be much more complex and can be triggered by timers and external events (pins). Many of the common libraries are implemented using ISRs.

Here is an example on Arduino:

const int ledPin =  13;      // the number of the LED pin

int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}

void loop()
{
// here is where you'd put code that needs to be running all the time.
unsigned long currentMillis = millis();

if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;

// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;

// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}


This records when it will need to change and waits until it is that time.

Of course, this function (millis();) will reset after about 50 days when it becomes too large to store, but if you don't keep it on for more than about 40 days, you should be good. You could prevent this by finding out how large this value can be and do a if statement for when it nears the top to stop for a minute or so. You would have trouble adding to the milliseconds when it gets that high, but I don't know how to solve that, but this will work for a small project.