Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

Day 2 of 30 · about 32 minutes

Your first program: blink an LED

Today you build: The on-board LED blinking on your schedule

  • Read 7 min
  • Type, verify & upload 8 min
  • Wire an LED on the breadboard 6 min
  • Try it: heartbeat 8 min
  • Check yourself 3 min

Community draft — report a mistake

Yesterday you uploaded someone else’s Blink to prove the toolchain works. Today you write it yourself, understand every line, and wire your first LED.

What you need

  • Arduino Uno or Nano and its USB data cable (set up on day 1)
  • A breadboard, one LED (any colour), one 220 Ω resistor (red-red-brown) and two jumper wires — for the second half

Every Arduino program has two parts

  • setup() runs once, each time the board powers up or resets. You configure pins here.
  • loop() runs again and again, forever, as fast as it can. When it reaches the closing }, it starts over at the top.

There is no “end” to an Arduino program. That’s normal for a microcontroller: it does its one job until the power goes.

The code, line by line

Today’s code is at the bottom of this page.

  • // Blink the on-board LED… — a comment. Everything after // is for humans; the compiler ignores it.
  • Serial.begin(9600); — opens the USB serial link at 9600 bits per second, so the board can send you text.
  • pinMode(LED_BUILTIN, OUTPUT); — makes the LED’s pin an output. LED_BUILTIN is the Uno’s name for pin 13, where the L LED sits.
  • Serial.println(F("FlashReady: blink started")); — sends one line of text. F() keeps the text in flash memory instead of the Uno’s tiny RAM.
  • digitalWrite(LED_BUILTIN, HIGH); — puts 5 V on pin 13. The LED turns on.
  • delay(500); — waits 500 milliseconds (half a second). The board does nothing else meanwhile.
  • digitalWrite(LED_BUILTIN, LOW); — 0 V. LED off. Then another half-second wait, and loop() starts over.

Every statement ends with a semicolon, and C++ cares about capital letters: digitalwrite is a different (unknown) name from digitalWrite.

Type it, verify, upload

Copying works, but typing it once teaches your fingers the shape of a sketch.

  1. File → New Sketch. The IDE gives you empty setup() and loop() functions. Type the code into them.
  2. File → Save As… and name it my-blink. The IDE keeps each sketch in its own folder.
  3. Click Verify (the ✓). It only compiles, without uploading — the quickest way to catch typos. It should end with Sketch uses … bytes. A red error? Read the line it names, and the line above it.
  4. Click Upload (→). The L LED blinks once a second: half a second on, half off.
  5. Open Tools → Serial Monitor and set the speed to 9600 baud at its right-hand side. You see FlashReady: blink started.
  6. Press the board’s RESET button. The LED pauses, then the same line prints again.

Step 6 is setup() in action: it runs once per reset, while loop() never prints anything.

Prefer to try it first with no board? Open in Playground under the code runs it on an emulated Uno in your browser.

Wire an LED on the breadboard

The on-board LED is tiny. Time for a real one.

Breadboard basics: each short row of 5 holes is connected inside. The gap down the middle separates the left and right halves. The long lines along the edges (marked + and −) are power rails.

  1. Unplug the USB cable first. Wire with the power off, every time.
  2. Push the LED into the breadboard so its two legs are in different rows. The long leg is + (anode); the short leg, next to the flat edge of the rim, is − (cathode).
  3. Resistor from the long leg’s row to an empty row.
  4. Jumper from that empty row to Uno pin 13.
  5. Jumper from the short leg’s row to a Uno GND pin.

Check before power: trace the path with your finger: pin 13 → resistor → long leg → LED → short leg → GND. One path, no gaps, no row shared by two legs of the same part. Plug in. Your LED blinks together with L — no new upload needed, because it’s on the same pin.

Doesn’t light? Turn the LED around — backwards LEDs don’t light, but don’t break at these voltages either.

Try it: make a heartbeat

Change loop() so the LED goes ba-dum… ba-dum…: two short flashes close together, then a long pause. You need four digitalWrite/delay pairs. Hint: try on 100 ms, off 100 ms, on 100 ms, off 700 ms. Then tune the numbers until it looks right to you.

Common mistakes

  • 'digitalwrite' was not declared in this scope — wrong capital letters. Full fix.
  • expected ';' before… — a missing semicolon, usually at the end of the line above the one the error names. Full fix.
  • delay(0.5) doesn’t wait half a second. delay() takes whole milliseconds, so 0.5 becomes 0. Write delay(500).
  • Strange symbols in the Serial Monitor — its speed isn’t 9600. It must match Serial.begin(9600).
  • LED with no resistor. It may work for a while, but it draws too much current from the pin. Always use 220 Ω–1 kΩ.

On an ESP32 instead?

The same idea works on the ESP32 DevKit V1, whose blue LED is on GPIO 2 (and it has no LED_BUILTIN, as you saw on day 1). ESP32 sketches in this course use 115200 baud. The compile-checked version is on the ESP32 board page.

You’re done when…

  • Your own typed sketch verifies and uploads with no red errors.
  • The Serial Monitor shows FlashReady: blink started once after each RESET press.
  • Your breadboard LED blinks in step with the L LED.
  • Your heartbeat pattern runs, and you can explain which part runs once and which repeats.

Tomorrow the board stops only talking and starts listening: a button.

Today's code

Verified — core avr 1.8.8, 3 Nov 2026Compile-only
blink-uno.inoArduino C++Open in PlaygroundOpen in Playground
// Blink the on-board LED (pin 13) of an Arduino Uno R3 or Nano.
void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.println(F("FlashReady: blink started"));
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
}

↑↓ to move · Enter to open