# State Machines for Embedded Logic — Arduino & Embedded C

Source: https://www.geekswithgeeks.com/en/arduino-embedded-c/state-machines

> Clear behaviour without tangled flags.

## States, events and transitions

As projects grow, nested `if`s and boolean flags become unmanageable. A **finite state machine** names each mode the device can be in (IDLE, HEATING, ALARM), the **events** that matter (button press, timeout, sensor threshold) and the **transitions** between states. In C/C++ use an `enum` for states and a `switch` in `loop()`; each case does its non-blocking work and decides whether to change state. Record when the state was entered with `millis()` to implement timeouts. State machines combine naturally with non-blocking timing and interrupt flags, and they are easy to draw, review and test.

## From sketch to dependable device

Real devices combine clear structure, careful networking and systematic debugging.

![Four ideas: state machines, IoT with ESP32, debugging and testing, a final checklist.](assets/figures/arduino-embedded-c/section-8-map.svg) — Figure 8.1 — Design, connect, debug and review stages of a project.

## A traffic light with a pedestrian button

Arduino C++; pins are examples for an Uno R3 with LEDs through 330 Ω resistors.

```cpp
enum class Light : uint8_t { Green, Yellow, Red };

const uint8_t RED = 10, YELLOW = 11, GREEN = 12, BUTTON = 2;
Light state = Light::Green;
unsigned long enteredAt = 0;
bool requested = false;

void enter(Light s) {
  state = s;
  enteredAt = millis();
  digitalWrite(GREEN,  s == Light::Green);
  digitalWrite(YELLOW, s == Light::Yellow);
  digitalWrite(RED,    s == Light::Red);
}

void setup() {
  pinMode(RED, OUTPUT); pinMode(YELLOW, OUTPUT); pinMode(GREEN, OUTPUT);
  pinMode(BUTTON, INPUT_PULLUP);
  enter(Light::Green);
}

void loop() {
  if (digitalRead(BUTTON) == LOW) requested = true;
  unsigned long inState = millis() - enteredAt;

  switch (state) {
    case Light::Green:
      if (requested && inState >= 5000) enter(Light::Yellow);
      break;
    case Light::Yellow:
      if (inState >= 2000) enter(Light::Red);
      break;
    case Light::Red:
      if (inState >= 6000) { requested = false; enter(Light::Green); }
      break;
  }
}
```

## A board game

A state machine is like a board game: you are always on exactly one square, and the rules say which squares you can move to next and what makes you move.

**Quiz:** What is the main benefit of a state machine in embedded code?

- [ ] It replaces all interrupts
- [ ] It removes the need for any timing
- [ ] It makes the code run in parallel on several cores
- [x] Behaviour is organised into explicit states and transitions that are easy to reason about

*Answer:* Behaviour is organised into explicit states and transitions that are easy to reason about. Explicit states replace tangled flags and nested conditions.
