Bird
Raised Fist0
Arduinoprogramming~20 mins

Non-blocking code architecture in Arduino - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Non-blocking Code Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this non-blocking LED blink code?

Consider this Arduino sketch that blinks an LED without using delay(). What will be printed to the Serial Monitor?

Arduino
const int ledPin = 13;
unsigned long previousMillis = 0;
const long interval = 1000;

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    digitalWrite(ledPin, !digitalRead(ledPin));
    Serial.println("LED toggled");
  }
}
ALED toggled printed every second
BLED toggled printed continuously without delay
CNo output printed because Serial.begin is missing
DLED toggled printed once and then stops
Attempts:
2 left
💡 Hint

Think about how millis() and the time check control when the message prints.

🧠 Conceptual
intermediate
1:30remaining
Why is using delay() not recommended in non-blocking code?

Which of the following best explains why delay() is avoided in non-blocking Arduino code?

A<code>delay()</code> uses too much memory
B<code>delay()</code> only works with LEDs
C<code>delay()</code> causes the Arduino to reset
DBecause <code>delay()</code> stops all code execution, preventing other tasks from running
Attempts:
2 left
💡 Hint

Think about what happens to the program when delay() is called.

🔧 Debug
advanced
2:30remaining
Identify the bug in this non-blocking button press code

This code is supposed to toggle an LED each time a button is pressed without blocking. What is the bug that prevents it from working correctly?

Arduino
const int buttonPin = 2;
const int ledPin = 13;
int ledState = LOW;

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  if (digitalRead(buttonPin) == HIGH) {
    ledState = !ledState;
    digitalWrite(ledPin, ledState);
    delay(50);
  }
}
ALED pin is not set as OUTPUT
BButton pin is not set as INPUT_PULLUP
CUsing <code>delay(50)</code> blocks code and causes multiple toggles on a single press
DMissing <code>Serial.begin()</code> in setup
Attempts:
2 left
💡 Hint

Think about what happens when the button is pressed and the code uses delay().

📝 Syntax
advanced
2:30remaining
Which option correctly implements a non-blocking timer using millis()?

Choose the code snippet that correctly toggles an LED every 500 milliseconds without blocking.

A
unsigned long lastTime = 0;
void loop() {
  if (millis() - lastTime &gt; 500) {
    lastTime = lastTime + 500;
    digitalWrite(13, !digitalRead(13));
  }
}
B
unsigned long lastTime = 0;
void loop() {
  if (millis() - lastTime &gt;= 500) {
    lastTime += 500;
    digitalWrite(13, !digitalRead(13));
  }
}
C
unsigned long lastTime = 0;
void loop() {
  if (millis() - lastTime &gt;= 500) {
    lastTime = 0;
    digitalWrite(13, !digitalRead(13));
  }
}
D
unsigned long lastTime = 0;
void loop() {
  if (millis() - lastTime &gt;= 500) {
    lastTime = millis();
    digitalWrite(13, !digitalRead(13));
  }
}
Attempts:
2 left
💡 Hint

Consider how to update lastTime to keep consistent timing without drift.

🚀 Application
expert
3:00remaining
How many times will the LED toggle in 5 seconds with this code?

Given this non-blocking Arduino code, how many times will the LED toggle in 5 seconds?

Arduino
const int ledPin = 13;
unsigned long previousMillis = 0;
const long interval = 700;

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis += interval;
    digitalWrite(ledPin, !digitalRead(ledPin));
  }
}
A7 times
B5 times
C6 times
D8 times
Attempts:
2 left
💡 Hint

Divide the total time by the interval and consider how the code updates previousMillis.

Practice

(1/5)
1. What is the main advantage of using non-blocking code in Arduino programming?
easy
A. It uses less memory than blocking code.
B. It makes the code run slower but more stable.
C. It allows the Arduino to perform multiple tasks without waiting.
D. It automatically fixes hardware errors.

Solution

  1. Step 1: Understand blocking vs non-blocking

    Blocking code stops the program until a task finishes, while non-blocking code lets the program keep running other tasks.
  2. Step 2: Identify the benefit of non-blocking

    Non-blocking code allows multitasking and keeps the Arduino responsive.
  3. Final Answer:

    It allows the Arduino to perform multiple tasks without waiting. -> Option C
  4. Quick Check:

    Non-blocking = multitasking [OK]
Hint: Non-blocking means no waiting, so tasks run together [OK]
Common Mistakes:
  • Thinking non-blocking slows code down
  • Confusing memory use with blocking behavior
  • Believing non-blocking fixes hardware issues
2. Which of the following is the correct way to check elapsed time without blocking in Arduino?
easy
A. delay(1000);
B. if (millis() - previousMillis >= interval) { /* do task */ }
C. while(millis() < 1000) { /* wait */ }
D. delayMicroseconds(1000);

Solution

  1. Step 1: Identify blocking vs non-blocking code

    delay() and while loops that wait block the program, stopping other tasks.
  2. Step 2: Recognize millis() usage

    Using millis() to check elapsed time allows the program to continue running other code.
  3. Final Answer:

    if (millis() - previousMillis >= interval) { /* do task */ } -> Option B
  4. Quick Check:

    millis() check = non-blocking [OK]
Hint: Use millis() difference, not delay(), to avoid blocking [OK]
Common Mistakes:
  • Using delay() which blocks the program
  • Using while loops that wait for time
  • Confusing delayMicroseconds with non-blocking
3. What will be the output of this Arduino code snippet?
unsigned long previousMillis = 0;
const long interval = 1000;
void loop() {
  if (millis() - previousMillis >= interval) {
    previousMillis = millis();
    Serial.println("Tick");
  }
}
medium
A. Prints "Tick" every second repeatedly.
B. Prints "Tick" continuously without delay.
C. Prints "Tick" once and stops.
D. Does not print anything due to syntax error.

Solution

  1. Step 1: Analyze the millis() timing check

    The code checks if 1000 milliseconds (1 second) have passed since last print.
  2. Step 2: Understand the loop behavior

    When 1 second passes, it updates previousMillis and prints "Tick" again, repeating forever.
  3. Final Answer:

    Prints "Tick" every second repeatedly. -> Option A
  4. Quick Check:

    millis() timer triggers print every 1 second [OK]
Hint: millis() timer resets each print for repeated ticks [OK]
Common Mistakes:
  • Thinking it prints only once
  • Assuming continuous printing without delay
  • Believing there is a syntax error
4. Identify the problem in this non-blocking Arduino code and how to fix it:
unsigned long previousMillis = 0;
const long interval = 1000;
void loop() {
  if (millis() > previousMillis + interval) {
    Serial.println("Hello");
  }
}
medium
A. It never updates previousMillis, causing continuous prints.
B. The comparison operator should be '<' instead of '>'.
C. The interval variable must be unsigned long, not long.
D. Serial.println() cannot be used inside loop.

Solution

  1. Step 1: Check the timing logic

    The code checks if millis() is greater than previousMillis + interval but never updates previousMillis.
  2. Step 2: Understand the effect

    Without updating previousMillis, the condition stays true, so "Hello" prints continuously without delay.
  3. Final Answer:

    It never updates previousMillis, causing continuous prints. -> Option A
  4. Quick Check:

    Missing previousMillis update = continuous print [OK]
Hint: Always update previousMillis after action to avoid repeats [OK]
Common Mistakes:
  • Forgetting to update previousMillis
  • Changing comparison operator incorrectly
  • Thinking Serial.println() is invalid in loop
5. You want to blink an LED every 500ms and read a sensor every 200ms without blocking. Which code structure best achieves this?
hard
A. Use while loops to wait 500ms and 200ms before each task.
B. Use delay(500) for LED blink and delay(200) for sensor reading in sequence.
C. Use a single millis() timer for both tasks with combined interval 700ms.
D. Use two millis() timers, one for LED and one for sensor, each updating separately.

Solution

  1. Step 1: Understand multitasking with millis()

    Each task needs its own timer to run independently without blocking.
  2. Step 2: Evaluate options

    Use two millis() timers, one for LED and one for sensor, each updating separately. This uses two separate millis() timers, allowing LED and sensor to run at different intervals smoothly.
  3. Final Answer:

    Use two millis() timers, one for LED and one for sensor, each updating separately. -> Option D
  4. Quick Check:

    Separate timers = true multitasking [OK]
Hint: Use separate millis() timers for each task to avoid blocking [OK]
Common Mistakes:
  • Using delay() which blocks all tasks
  • Combining intervals causing missed timings
  • Using while loops that block execution
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard