sheen.bot logo

← Insights

Why delay() Breaks Classroom Arduino Projects (and How to Teach millis() to Kids)

Oct 8, 2026·Sheen Robotics
Why delay() Breaks Classroom Arduino Projects (and How to Teach millis() to Kids)

Using delay() puts the microcontroller to sleep, blinding sensors and locking motors. Here is how the stopwatch mental model teaches non-blocking timing to Senior Phase learners.

The delay() function breaks classroom Arduino projects because it halts the microcontroller completely. For the entire duration of the delay, the processor does nothing: it cannot read a bump sensor, cannot check an ultrasonic distance reading, and cannot respond to a stop button. If a wheeled robot is moving forward when it hits a two-second delay, it will drive blind into a wall for two full seconds before executing its next instruction.

To fix this with Grade 7 to 9 learners, you do not need to teach threading, hardware timer interrupts, or object-oriented state machines. You need a single, concrete mental model: checking a wristwatch instead of taking a nap.

The Anatomy of a Classroom Bug

In almost every introductory robotics scheme of work, Lesson 1 is the standard LED blink:

digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);

It works, it gives learners instant gratification, and it plants a conceptual landmine that detonates three weeks later. In Lesson 4, when learners are asked to build a pedestrian crossing (blink a light and detect a button press) or an obstacle-avoiding rover (spin motors and read distance), their code falls apart.

The learner writes a loop that checks the push-button, turns on a buzzer, and calls delay(1000). When they press the button, the board usually ignores them. Why? Because the processor was busy counting dead cycles inside the delay. The human finger pressed and released the switch during the 99% of the loop cycle where the chip was functionally asleep.

On an ATmega328P clocked at 16 MHz, calling delay(1000) wastes 16 million clock cycles executing empty assembly instructions. The robot is not multitasking; it is frozen.

The Wristwatch Mental Model

Before showing learners code, get them away from their screens for a five-minute demonstration. Ask a volunteer to perform a task: “Clap your hands every three seconds, but if I drop this pen, catch it before it hits the floor.”

First, have them simulate delay(): tell them that to time three seconds, they must close their eyes and count silently to three in their head. Drop the pen at second two. They will fail every time. Their sensors were shut down while they were timing.

Next, give them the non-blocking model: tell them to keep their eyes wide open, look at the classroom wall clock (or a digital wristwatch), and keep watching your hand. They check the time: if three seconds have ticked past since their last clap, they clap. If the pen drops, they react instantly.

This shifts the concept of timing from an action (“wait for two seconds”) to a comparison (“has enough time passed yet?”).

The Core Pattern: Three Questions

Once learners understand the clock on the wall, introduce millis(). Explain that millis() is simply an internal stopwatch that started running the exact millisecond the Arduino was plugged into power. It never stops, and it never pauses the code.

Every non-blocking event can be reduced to three plain-language questions inside the continuous loop:

  • What time is it right now? (Read the stopwatch: currentTime = millis())
  • When did I last do this action? (Look at the stored note: previousTime)
  • Has the required amount of time passed? (Do the subtraction: currentTime - previousTime >= interval)

If the answer to the third question is yes, perform the action and update the note: set previousTime = currentTime. If the answer is no, skip the action and move on immediately. Because the loop finishes in a fraction of a millisecond, the board is free to read ultrasonic sensors, check limit switches, and poll line-trackers thousands of times every second.

Teaching the Syntax Without Overwhelming Beginners

For Grade 7 and 8 learners, the C++ boilerplate around unsigned long often creates cognitive overload. In schools working within the gazetted Senior Phase Coding and Robotics curriculum, learners are typically operating in block-based environments or hybrid editors.

If you are teaching in blocks (such as Scratch-based Arduino environments), the translation is straightforward: introduce a “timer” block and a variable named last_time_checked. Avoid the “wait 1 second” block entirely once basic inputs are introduced.

If you are teaching text-based Arduino C++, do not dump the stock BlinkWithoutDelay example on their screens without scaffolding. The official Arduino example combines two separate concepts at once: non-blocking timing and state toggling (inverting an LED state variable). This is why kids get confused.

Separate the timing check from the logic. Use this sequence instead:

  1. Demonstrate the failure: Have them run an LED blink using delay() while trying to trigger an emergency stop button. Watch the frustration when the button fails to trigger.
  2. Introduce the timer variable: Show them how to print millis() to the Serial Monitor so they see the numbers climbing continuously. This demystifies the function—it is just an odometer for time.
  3. Write the timed wrapper: Provide a scaffolded template where the subtraction logic is isolated from the robot’s behaviour.
ApproachProcessor StateSensor ResponsivenessSuitability
delay(1000)Halted in busy-wait loopCompletely blind during delaySingle-task demos, Grade 4–6 intro
millis() comparisonFree-running at full clock speedInstant (sub-millisecond polling)Robotics, rovers, interactive systems

Making It Stick in Class Projects

When learners transition from rovers that drive blind to rovers that poll sensors continuously, their debugging experience changes. Instead of wondering why a bumper switch failed to stop a DC motor, they can trace execution cleanly.

If your school is structuring a multi-term progression from block-based logic into physical robotics, having structured teaching sequences and verified hardware layouts removes the guesswork. Our team at Sheen Robotics for Schools works with teachers to align these embedded systems concepts with classroom timetables, ensuring learners build reliable mental models before bad coding habits set in.

Once a learner understands that a computer should never sit with its eyes closed counting seconds, they have crossed the threshold from simply running scripts to writing responsive, real-world software.

#arduino#robotics education#coding#pedagogy#stem

More Insights