Skip to content

Embedded Systems

Arduino setup() and loop() explained

Every Arduino sketch has two functions. setup() runs once, when the board powers up or resets: it gets things ready, like setting pin modes and starting the serial port. loop() runs next, then again and again, for as long as the board has power: it's where the sketch reads inputs and drives outputs.

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);   // L, on pin 13
  Serial.begin(9600);             // start the serial monitor
  Serial.println("Ready");        // said once
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(100);                     // on for 100 ms
  digitalWrite(LED_BUILTIN, LOW);
  delay(900);                     // off for 900 ms
}

That sketch says Ready once, then flashes L once a second, forever.

What happens behind them

Arduino writes the rest of the program for you. Stripped down, it's this:

int main() {
  init();          // set up the chip's timers
  setup();         // your code, once
  for (;;) {
    loop();        // your code, forever
  }
}

So loop() isn't magic: it's an ordinary function called inside a loop that never ends.

Live experiment

Meet the board

The board starts unplugged and asleep. Tap the USB socket to plug it in, and the starter program blinks L. Then tap round the board to find its six parts: the USB socket, the microcontroller, L, the digital pins, the analog pins and 5V and GND.

Try it yourself: free lesson

“Meet the board” is lesson 1 of 6 in Blink Bay, Embedded Systems World 1. Free with an account. It’s open as soon as you sign up.

What goes where

In setup(): anything that only needs doing once. pinMode(), Serial.begin(), a welcome message, starting a sensor.

In loop(): anything that should keep happening. Reading buttons and sensors, deciding what to do, writing to LEDs and motors. Read a sensor only in setup() and you get one reading, at power-on, and never another.

Above setup(): variables that must remember something between passes, like a count or the time of the last blink. A variable declared inside loop() is made fresh on every pass, so it can't keep a running total.

The syntax rules

  • Each statement ends with a semicolon, ;
  • A block of statements sits between { and }
  • // starts a comment, a note the board ignores
  • A function call passes its arguments in brackets: delay(100)

The compiler is strict: Delay and delay are different names, and a missing ; stops the upload with a message naming the line.

Once the sketch is uploaded, the board runs it by itself, even with the computer unplugged, starting from setup() every time it powers up.

Free lesson

Now build it yourself

Each lesson comes in three short parts: see the idea, try it on a live board, then build it yourself, with quick checks as you go.

Try it yourself: free lesson

“Meet the board” is lesson 1 of 6 in Blink Bay, Embedded Systems World 1. Free with an account. It’s open as soon as you sign up.

Or start from the very first lesson, no account needed

Practice questions

Three quick questions from the lessons. Pick an answer to check it.

  1. Question 1 of 3Which part of a program runs again and again?
    Show the answer

    Answer: loop(). setup() runs once when the board starts. loop() runs next, then again and again, for as long as the board has power.

    • Why not “The pins”? The pins are the board's connections, not part of the program. loop() is the code that repeats.
    • Why not “Upload”? Upload copies the program onto the board once. It isn't part of the program that runs.
    • Why not “setup()”? setup() runs only once, when the board starts or resets. loop() is the part that repeats.
  2. Question 2 of 3Which part of this line does the board ignore? delay(900); // wait
    Show the answer

    Answer: // wait. Everything after // on a line is a comment, a note for people. The board skips it.

    • Why not “(900);”? (900); gives delay its argument and ends the statement. Without it the line wouldn't even compile.
    • Why not “delay”? delay is the function the line calls, so the board runs it and waits.
  3. Question 3 of 3The count lives above setup() because…
    Show the answer

    Answer: it must keep its value from one pass of loop() to the next. A variable made inside loop() is thrown away at the end of every pass. Above setup(), it lives for as long as the board runs.

    • Why not “it makes the program faster”? Where a variable lives doesn't change the speed. It changes how long its value lasts.
    • Why not “loop() can't hold numbers”? loop() can hold numbers, but a variable made inside it is made fresh on every pass and starts again.
    • Why not “setup() needs it first”? setup() doesn't use the count at all. It sits above setup() so it survives from one pass of loop() to the next.
Keep practising: free lesson

“Meet the board” is lesson 1 of 6 in Blink Bay, Embedded Systems World 1. Free with an account. It’s open as soon as you sign up.

Questions people ask

Can an Arduino sketch run without loop()?

No: both setup() and loop() must exist, or it won't compile. They can be empty, though. A program that does everything once can put it all in setup() and leave loop() empty, and the board then idles in loop() forever.

When does setup() run again?

Whenever the board restarts: at power-on, when you press its reset button, and after every upload. On an Uno, opening the serial monitor usually resets the board too, so setup() runs again.

How fast does loop() repeat?

As fast as its code allows. An empty loop() comes round hundreds of thousands of times a second on a 16 MHz Uno, and each digitalRead or digitalWrite adds a few microseconds. A delay() inside it sets the pace instead.

Every topic