Bird
Raised Fist0
Arduinoprogramming~10 mins

Timing-based state machines in Arduino - Interactive Code Practice

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
Practice - 5 Tasks
Answer the questions below
1fill in blank
easy

Complete the code to get the current time in milliseconds.

Arduino
unsigned long currentTime = [1]();
Drag options to blanks, or click blank then click option'
Atime
Bmillis
Cmicros
Ddelay
Attempts:
3 left
💡 Hint
Common Mistakes
Using delay() instead of millis()
Using micros() which returns microseconds, not milliseconds
2fill in blank
medium

Complete the code to check if 1000 milliseconds have passed since lastTime.

Arduino
if (currentTime - lastTime [1] 1000) {
Drag options to blanks, or click blank then click option'
A==
B<
C>=
D<=
Attempts:
3 left
💡 Hint
Common Mistakes
Using < instead of >=
Using == which is too strict
3fill in blank
hard

Fix the error in the state machine update condition.

Arduino
if (state == [1] && currentTime - lastTime >= interval) {
Drag options to blanks, or click blank then click option'
A1
Btrue
CHIGH
DON
Attempts:
3 left
💡 Hint
Common Mistakes
Using true instead of a numeric state
Using HIGH which is for pin states
4fill in blank
hard

Fill both blanks to update the state and reset the timer.

Arduino
state = [1];
lastTime = [2];
Drag options to blanks, or click blank then click option'
A2
Bmillis()
C1
Ddelay(1000)
Attempts:
3 left
💡 Hint
Common Mistakes
Using delay() instead of millis() for lastTime
Setting state to 1 instead of 2
5fill in blank
hard

Fill all three blanks to create a timing-based state machine that toggles an LED every second.

Arduino
unsigned long [1] = 0;
int [2] = 0;
const unsigned long [3] = 1000;
Drag options to blanks, or click blank then click option'
AlastToggle
Bstate
Cinterval
DledPin
Attempts:
3 left
💡 Hint
Common Mistakes
Using ledPin for timing variables
Mixing variable names for state and time

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