Learning Goals 5 min
By the end of this lesson you will be able to:
- Open a two-way connection between the Arduino and your laptop with
Serial.begin(9600)insidesetup(). - Send messages back to the laptop with
Serial.println()andSerial.print(), and read them in the IDE's Serial Monitor. - Tell the difference between
print(no newline) andprintln(newline), and use them together to build neat output lines like"Press count: 3".
Warm-Up 10 min
Cluster C taught you how to listen to the world — buttons, debouncing, state changes. Cluster D goes the other way: the Arduino starts talking back to you. Until today, the only "output" you've had has been LEDs and the buzzer. From this lesson on, the Arduino can send words, numbers and live values straight to a window on your laptop screen.
Quick-fire puzzle
So far, when something goes wrong with your sketch, you have to guess what the Arduino is doing. Imagine each of these bugs — and ask yourself which would be easier to diagnose if the Arduino could say what it was doing in plain English.
- You wrote a burglar alarm but it never fires — the LED stays green forever no matter what you do.
- Your reaction-timer always shows the same score, 0 ms, even though you swear you were slow.
- Your buzzer plays the wrong note — you wanted middle C but it plays an octave too high.
Reveal the answer
- If the Arduino printed
button reads HIGHon every loop, you'd know it never saw a press — wiring fault, not code. If it printedbutton reads LOWbut the alarm still didn't fire, you'd know it's the code logic. - If the Arduino printed the start-time and end-time it measured, you'd see if it's reading
0for both (logic bug) or two very-close numbers (timing bug). - If the Arduino printed
tone freq = 1046when you asked for middle C (262), you'd see immediately that you typed the wrong number.
This is the superpower today's lesson unlocks: printing. Once your sketch can talk, debugging stops being guesswork.
New Concept — sending text up the USB cable 15 min
The big idea — the USB cable is a two-way street
You've been using the USB cable since lesson 1, but only for two things: power (5 V down the cable to run the Arduino) and uploading sketches (the compiled program flows down the cable into the chip's memory). Today you discover the third thing it can do: carry text messages back up the cable from the running Arduino to a window on your laptop.
That window is the Serial Monitor, built into the Arduino IDE. Open it (Tools → Serial Monitor, or the magnifying-glass icon at the top-right of the IDE) and you get a scrolling box that shows every message the Arduino sends. The keyboard at the top of that box even lets you send messages back down — but that's L01-26's job. Today is just about the Arduino → laptop direction.
The three lines you need to memorise
The serial system has exactly three pieces. Learn these three lines and you can debug almost anything.
Serial.begin(9600); // in setup() — opens the connection
Serial.println("Hello!"); // sends "Hello!" + newline
Serial.print("x = "); // sends "x = " with NO newlineLine 1 — Serial.begin(9600)
The number 9600 is the baud rate — how many bits per second the two ends agree to send. Both ends must use the same number or you'll see garbled characters. 9600 is the long-standing default for hobby Arduino work; it's slow by modern standards but reliable.
This line goes in setup() and runs once only. After it runs, the rest of your sketch can send messages whenever it likes. Forgetting this line is the most common Serial bug in the world — the Monitor opens, nothing appears, and the student stares at it for ten minutes. If your output is blank, check setup() first.
Line 2 — Serial.println(...)
The ln at the end stands for "line" — it sends whatever you give it, then a newline character, so the next message starts on a fresh line. This is what you want 90 % of the time. You can print:
- A string in double quotes:
Serial.println("Press count"); - A number:
Serial.println(42); - A variable:
Serial.println(presses);
Line 3 — Serial.print(...)
Same as println but without the newline. The next message stays on the same line. Use this when you want to build one tidy line out of several pieces — label + value + units — like "Press count: 3" instead of three messages on three separate lines.
Combine them like this:
Serial.print("Press count: "); // no newline
Serial.print(presses); // no newline
Serial.println(); // just the newlineThat produces one clean line per press: Press count: 1, Press count: 2, … Rule of thumb: every line you want to see in the Monitor ends with exactly one println.
Why it matters
Printing is the single most useful debugging tool in all of programming, on every language and every platform — Python developers call it "print debugging", JavaScript developers call it "console logging", but it's the same idea. You sprinkle println calls at suspicious places in your sketch, watch the Monitor, and the message that doesn't appear (or appears with a value you weren't expecting) tells you exactly where the bug lives. Every Cluster D lesson builds on this.
Worked Example — Hello, world! 20 min
Today's worked example is the most famous program in computing history — the one every programmer writes first in every new language: a sketch that says hello. No breadboard, no extra components, no wiring change from yesterday. Just the USB cable.
Step 1 — The "Hello, world!" sketch
Open a new sketch (File → New) and type this in:
// Hello world — Arduino's first words
void setup() {
Serial.begin(9600);
Serial.println("Hello, world!");
}
void loop() {
// nothing — setup runs once and we're done
}Notice that the message goes in setup(), not loop() — we only want to greet the user once. Put it in loop() and you'd flood the Monitor with thousands of "Hello, world!" lines per second.
Step 2 — Upload, then open the Serial Monitor
- Plug in the USB. Click the Upload button (→ arrow, top-left). Wait for "Done uploading."
- Open the Serial Monitor: click the magnifying-glass icon at the top-right of the IDE, or use Tools → Serial Monitor (shortcut Ctrl+Shift+M on Windows, Cmd+Shift+M on Mac).
- At the bottom-right of the Monitor window, set the baud rate dropdown to 9600 baud.
- You should see
Hello, world!appear in the Monitor. If you don't, press the small reset button on the Arduino — the sketch will run again.
Serial.begin().Step 3 — Make it count
One message is the smallest possible test. Now move the printing into loop() and count up forever, one number per second. This is the classic "is the chip even alive?" sanity check.
// Counter — prints 0, 1, 2, 3, … every second
int count = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print("Count: ");
Serial.println(count);
count = count + 1;
delay(1000);
}Open the Monitor. Lines should appear once a second:
Count: 0
Count: 1
Count: 2
Count: 3
…Two new ideas in one sketch:
- One line, two pieces.
Serial.print("Count: ")writes the label without ending the line;Serial.println(count)writes the number and then ends the line. Together, one tidy line per pass. - Variables print fine. Pass any variable to
printorprintlnand it prints its current value. This is what makes printing useful for debugging — you can watch a variable change over time.
Trace it on paper
For each line of the counter sketch's loop(), write down what exactly appears in the Monitor on the first three passes.
| Pass | count value | What appears in Monitor |
|---|---|---|
| 1 | 0 | ____ |
| 2 | ____ | ____ |
| 3 | ____ | ____ |
If you can fill this in without uploading, you've understood print vs println. If not, re-read the New Concept — the difference between them is the trickiest idea in this lesson.
Try It Yourself — make the Arduino talk 20 min
Goal: Print your name, then your age, then your favourite colour — each on its own line, once at startup. No loop() body needed.
Plan: three Serial.println() calls in setup(), after Serial.begin(9600).
void setup() {
Serial.begin(9600);
Serial.println("____"); // your name
Serial.println(0); // your age, as a number
Serial.println("____"); // your favourite colour
}
void loop() { }Questions:
- Why is the age the only one without quotes? ____ (Hint: text vs number.)
- What happens in the Monitor if you change
printlntoprinton all three lines? Try it and describe the result. ____
Goal: Print one neat line per second showing how many seconds the sketch has been running, like Up for 7 seconds.
Plan: keep a count variable like in the worked example, but build the line with three pieces — a label, the number, and a unit-string ending in a full stop. Use two prints and one println.
int seconds = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print("Up for ");
Serial.print(seconds);
Serial.println(" seconds.");
seconds = seconds + 1;
delay(1000);
}Questions:
- You have three calls per line, but only one
println. What rule does that match? ____ (Hint: the recap from the New Concept.) - Remove the space inside
" seconds."so it reads"seconds.". What does the Monitor show now? Why? ____ - Change the delay to 100 ms. The number now jumps by 1 ten times a second, but the label still says "seconds". How would you fix the wording so it stays truthful? ____
Goal: Use printing to watch a real-world value live. Keep your burglar alarm (or just the two buttons) wired up from L01-23. Print one line per loop pass that shows the current value of both buttons, like A=1 B=0, with a 100 ms delay between prints.
This is the exact pattern professional embedded engineers use to debug input wiring — instead of guessing whether the button is reading correctly, you watch the value change as you press it.
const int A_PIN = 7;
const int B_PIN = 6;
void setup() {
Serial.begin(9600);
pinMode(A_PIN, INPUT_PULLUP);
pinMode(B_PIN, INPUT_PULLUP);
}
void loop() {
Serial.print("A=");
Serial.print(digitalRead(A_PIN));
Serial.print(" B=");
Serial.println(digitalRead(B_PIN));
delay(100);
}Questions:
- The value is
1when the button is NOT pressed and0when it IS pressed. Why? ____ (Hint:INPUT_PULLUPfrom L01-17.) - Unplug one of the button's GND wires while the sketch is running and watch the Monitor. What value does the disconnected button now show, and does it stay steady or jitter? ____
- If you remove the
delay(100), the Monitor scrolls so fast it's unreadable. Roughly how many lines per second would the loop produce without the delay? ____ (Hint: an Uno's loop runs about a hundred thousand times per second when it has very little work to do.)
Mini-Challenge — the press counter 10 min
"How many times have I pressed this button?"
Wire just one button on D7 with INPUT_PULLUP (the L01-17 circuit). Each time you press and release the button, the Arduino must print one line to the Monitor:
Press count: 1
Press count: 2
Press count: 3Between presses, the Arduino prints nothing at all — the Monitor stays still until you press.
Your task:
- Keep a mutable global
int presses = 0;. - Use the L01-19 state-change detection pattern: store
lastButtonand only act on the moment the button goes from HIGH (released) to LOW (pressed). - On each fresh press, do three things:
presses = presses + 1;, thenSerial.print("Press count: ");, thenSerial.println(presses);. - End the loop with a small
delay(20)as a cheap debounce.
It works if:
- The Monitor is silent until you press a button.
- Each press adds exactly one new line (not five lines from the contact bouncing).
- Holding the button down does not add more lines — only the press edge counts, not the held-down state.
Reveal one valid sketch
// Press counter — prints one line per press
const int BUTTON_PIN = 7;
int presses = 0;
int lastButton = HIGH;
void setup() {
Serial.begin(9600);
pinMode(BUTTON_PIN, INPUT_PULLUP);
Serial.println("Ready — press the button.");
}
void loop() {
int nowButton = digitalRead(BUTTON_PIN);
if (lastButton == HIGH && nowButton == LOW) {
presses = presses + 1;
Serial.print("Press count: ");
Serial.println(presses);
}
lastButton = nowButton;
delay(20);
}Two Cluster C ideas combine with one Cluster D idea: state-change detection (L01-19) decides when to print, INPUT_PULLUP (L01-17) reads the button cleanly, and the two new Serial calls do the actual talking. Almost every interactive sketch you write from now on will follow this shape: detect an event, then print what happened.
Recap 5 min
The USB cable is a two-way street: power and uploads come down, text messages go up. Three calls unlock it: Serial.begin(9600) in setup() opens the connection; Serial.println() sends text followed by a newline; Serial.print() sends text without one, letting you build a tidy line out of label + value + unit. The Serial Monitor in the IDE displays everything that arrives — match its baud rate dropdown to the number you passed to begin, and you'll see your Arduino talk back for the first time.
- Serial Monitor
- The window in the Arduino IDE (magnifying-glass icon, top-right) that shows messages sent by the running sketch. Open with Ctrl+Shift+M (or Cmd+Shift+M on Mac).
- Baud rate
- The number of bits per second the two ends of a serial link agree to send. Both sides must use the same value.
9600is the long-standing default for hobby Arduino work. Serial.begin(n)- Opens the serial connection at
nbaud. Goes insetup(), runs once. Forgetting this line is the most common cause of an empty Monitor. Serial.println(x)- Sends
x(text, number or variable) up the USB cable, followed by a newline so the next message appears on a fresh line. Thelnstands for "line". Serial.print(x)- Same as
printlnbut with no newline at the end. Use to build one neat output line from several pieces; close the line with a finalprintln. - Print debugging
- The universal technique of sprinkling
printlncalls through suspicious code to watch what really happens. Programmers in every language do this; it's almost always the fastest way to find a bug.
Homework 5 min
The temperature-of-the-room joke. Make the Arduino print a different "temperature reading" every two seconds — but make it up. The sketch should:
- Open serial at 9600 baud in
setup(). - In
loop(), print one line of the form"Room temp: ___ °C". - Use a mutable global
int fakeTemp = 20;. Every loop pass, change it: add 1 if it's below 25, subtract 1 if it's at 25 or above. (Use anif/elsefrom L01-20.) - Delay 2000 ms between prints.
The Monitor should slowly cycle 20, 21, 22, 23, 24, 25, 24, 23, … — your "thermometer" climbing then falling. We'll connect a real sensor in Cluster E; today's job is just to get comfortable with the printing pattern.
Also: a design reflection on paper.
- Pick any sketch you wrote in Cluster C (the burglar alarm, reaction timer, two-button combiner, etc.). Name three moments inside that sketch where adding a
Serial.printlnwould have made debugging faster, and write what each one would have printed. ____ - Why must
Serial.begin(9600)go insetup()and notloop()? Answer in your own words. ____ - The lesson called
9600a "baud rate". Look up whatbaudoriginally meant (whose name it comes from) and write one sentence. ____
Bring back next class:
- The saved
.inofile (call itfake-thermometer). - A phone photo of the Serial Monitor showing at least one full up-and-down cycle (20 → 25 → 20).
- Your three "where I'd have printed" notes + the two short written answers, in your notebook.
Heads up for next class: L01-25 "Debugging With Prints" turns today's three lines into a complete debugging workflow — finding bugs in other people's sketches by adding println at the right places. Bring today's .ino file; we'll deliberately break it together and fix it using only the Monitor.