Bird
Raised Fist0
Arduinoprogramming~20 mins

Timing-based state machines in Arduino - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Timing Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
Predict Output
intermediate
2:00remaining
Output of a simple timing-based LED blink state machine

Consider this Arduino code that uses a timing-based state machine to blink an LED connected to pin 13. What will be the output on the LED over 5 seconds?

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

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

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    ledState = (ledState == LOW) ? HIGH : LOW;
    digitalWrite(ledPin, ledState);
  }
}
AThe LED will turn ON and OFF every 1 second, blinking 5 times in 5 seconds.
BThe LED will stay ON continuously for 5 seconds.
CThe LED will stay OFF continuously for 5 seconds.
DThe LED will blink every 500 milliseconds, blinking 10 times in 5 seconds.
Attempts:
2 left
💡 Hint

Look at the interval variable and how it controls the timing of state changes.

🧠 Conceptual
intermediate
1:30remaining
Understanding state transitions in timing-based state machines

In a timing-based state machine on Arduino, what is the main purpose of storing the variable previousMillis?

ATo measure the total time since the Arduino started.
BTo store the current state of the machine.
CTo count how many times the loop() function has run.
DTo keep track of the last time the state changed, so the program can decide when to transition next.
Attempts:
2 left
💡 Hint

Think about how you know when to change states based on time.

🔧 Debug
advanced
2:30remaining
Identify the error causing the LED to never turn ON

Here is an Arduino code snippet intended to blink an LED every 2 seconds. However, the LED never turns ON. What is the cause?

Arduino
const int ledPin = 13;
unsigned long previousMillis = 0;
const long interval = 2000;
int ledState = LOW;

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

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
}
AThe interval variable is too large for blinking.
BThe condition uses assignment (=) instead of comparison (==) in 'if (ledState = LOW)'.
CThe pinMode is not set correctly in setup().
DThe digitalWrite function is called outside the timing check.
Attempts:
2 left
💡 Hint

Check the condition inside the if statement that tests ledState.

📝 Syntax
advanced
1:30remaining
Syntax error in timing-based state machine code

Which option contains the correct syntax to toggle an LED state variable ledState between HIGH and LOW using a ternary operator in Arduino C++?

AledState = (ledState == LOW) ? HIGH : LOW;
BledState == (ledState = LOW) ? HIGH : LOW;
CledState = (ledState = LOW) ? HIGH : LOW;
DledState = (ledState == LOW) ? LOW : HIGH;
Attempts:
2 left
💡 Hint

Remember the ternary operator format: condition ? value_if_true : value_if_false

🚀 Application
expert
2:00remaining
Calculate how many times a state machine toggles in a given time

An Arduino timing-based state machine toggles an output pin every 750 milliseconds. How many times will it toggle in 10 seconds?

A14 times
B12 times
C13 times
D15 times
Attempts:
2 left
💡 Hint

Divide total time by interval and consider if toggling happens at start or after interval.

Practice

(1/5)
1.

What is the main purpose of using millis() in a timing-based state machine on Arduino?

easy
A. To pause the program for a fixed time
B. To reset the Arduino board
C. To track elapsed time without stopping the program
D. To read analog sensor values

Solution

  1. Step 1: Understand what millis() does

    millis() returns the number of milliseconds since the Arduino started running. It keeps counting without stopping the program.
  2. Step 2: Connect millis() to timing-based state machines

    Using millis() lets the program check how much time passed and change states without pausing or blocking other tasks.
  3. Final Answer:

    To track elapsed time without stopping the program -> Option C
  4. Quick Check:

    millis() tracks time without delay [OK]
Hint: Remember: millis() never stops your code [OK]
Common Mistakes:
  • Thinking millis() pauses the program
  • Confusing millis() with delay()
  • Using millis() to reset Arduino
2.

Which of the following is the correct way to check if 1000 milliseconds have passed using millis()?

unsigned long previousMillis = 0;
unsigned long interval = 1000;

void loop() {
  unsigned long currentMillis = millis();
  // What condition checks if interval passed?
  if (__________) {
    // do something
    previousMillis = currentMillis;
  }
}
easy
A. previousMillis + currentMillis <= interval
B. previousMillis - currentMillis >= interval
C. currentMillis + previousMillis >= interval
D. currentMillis - previousMillis >= interval

Solution

  1. Step 1: Understand elapsed time calculation

    Elapsed time is current time minus previous time: currentMillis - previousMillis.
  2. Step 2: Check if elapsed time reached interval

    We compare if elapsed time is greater or equal to the interval: currentMillis - previousMillis >= interval.
  3. Final Answer:

    currentMillis - previousMillis >= interval -> Option D
  4. Quick Check:

    Elapsed time = current - previous [OK]
Hint: Subtract previous from current time to get elapsed [OK]
Common Mistakes:
  • Reversing subtraction order
  • Adding times instead of subtracting
  • Using <= instead of >=
3.

What will be the output of this Arduino code snippet that uses a timing-based state machine?

unsigned long previousMillis = 0;
const long interval = 2000;
int ledState = LOW;

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

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(13, ledState);
    Serial.println(ledState);
  }
}
medium
A. Prints alternating 0 and 1 every 2 seconds
B. Prints 1 continuously every 2 seconds
C. Prints 0 continuously every 2 seconds
D. No output because of syntax error

Solution

  1. Step 1: Understand the timing and state toggle

    Every 2000 ms, the code toggles ledState between LOW (0) and HIGH (1).
  2. Step 2: Check output printed

    Each toggle prints the current ledState (0 or 1) to Serial, alternating every 2 seconds.
  3. Final Answer:

    Prints alternating 0 and 1 every 2 seconds -> Option A
  4. Quick Check:

    State toggles and prints 0,1 alternately [OK]
Hint: Toggle state and print inside timed if-block [OK]
Common Mistakes:
  • Assuming constant output without toggle
  • Confusing HIGH/LOW with 1/0
  • Missing update of previousMillis
4.

Identify the bug in this timing-based state machine code and choose the fix.

unsigned long previousMillis = 0;
const long interval = 1000;
int ledState = LOW;

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

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    ledState = !ledState;
    digitalWrite(13, ledState);
  }
}
medium
A. Add previousMillis = currentMillis; inside the if-block
B. Change int ledState to bool ledState
C. Replace ! with ~ in toggle
D. Remove the if condition to toggle every loop

Solution

  1. Step 1: Check timing update logic

    The code never updates previousMillis, so the condition stays true forever after first pass.
  2. Step 2: Fix by updating previousMillis

    Adding previousMillis = currentMillis; inside the if-block resets the timer for the next interval.
  3. Final Answer:

    Add previousMillis = currentMillis; inside the if-block -> Option A
  4. Quick Check:

    Update previousMillis to reset timer [OK]
Hint: Always update previousMillis after interval check [OK]
Common Mistakes:
  • Forgetting to update previousMillis
  • Using bitwise NOT (~) instead of logical NOT (!)
  • Removing timing check causes fast toggling
5.

You want to create a state machine that cycles through three LED states: OFF, RED, GREEN. Each state lasts 3 seconds. Which code snippet correctly implements this using millis()?

unsigned long previousMillis = 0;
const long interval = 3000;
int state = 0;

void setup() {
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    state = (state + 1) % 3;
    switch(state) {
      case 0:
        digitalWrite(RED_PIN, LOW);
        digitalWrite(GREEN_PIN, LOW);
        break;
      case 1:
        digitalWrite(RED_PIN, HIGH);
        digitalWrite(GREEN_PIN, LOW);
        break;
      case 2:
        digitalWrite(RED_PIN, LOW);
        digitalWrite(GREEN_PIN, HIGH);
        break;
    }
  }
}
hard
A. Does not change states due to missing update
B. Correctly cycles OFF, RED, GREEN every 3 seconds
C. Cycles states every 1 second instead of 3
D. Cycles only RED and GREEN, skipping OFF

Solution

  1. Step 1: Check timing and state update

    The code uses millis() to check 3 seconds passed, then updates state cycling 0,1,2 with modulo 3.
  2. Step 2: Verify LED outputs per state

    State 0 turns both LEDs off, 1 turns RED on, 2 turns GREEN on. This matches the required cycle.
  3. Final Answer:

    Correctly cycles OFF, RED, GREEN every 3 seconds -> Option B
  4. Quick Check:

    State cycles with modulo and timing [OK]
Hint: Use modulo (%) to cycle states smoothly [OK]
Common Mistakes:
  • Forgetting to update previousMillis
  • Incorrect modulo causing wrong cycles
  • Not turning off LEDs in OFF state