1. Objective
The goal of this lab is to design and implement a system controlled by a Finite State Machine (FSM). You will control an LED's behavior using a single push-button. This lab will reinforce your understanding of state transitions and how to implement them in Arduino C++.
2. Prerequisites
- Basic understanding of digital input and output on the Arduino Uno.
- Experience with wiring a simple circuit with an LED and a push-button on a breadboard.
- Familiarity with the Arduino IDE (uploading code, serial monitor).
- Introduction to the concept of State Machines (States, Events, Transitions).
3. Materials
- 1 x Arduino Uno R3
- 1 x Breadboard
- 1 x LED (any color)
- 1 x Push-button
- 1 x 220Ω Resistor (for the LED)
- 1 x 10kΩ Resistor (for the push-button)
- Jumper Wires
4. Problem Description
You will design a system that cycles through four different modes of operation for an LED every time a push-button is pressed. The system should behave as follows:
- State 1: OFF - The LED is off. This is the initial state.
- State 2: SOLID ON - The LED is constantly on.
- State 3: SLOW BLINK - The LED blinks slowly (On for 500ms, Off for 500ms).
- State 4: FAST BLINK - The LED blinks quickly (On for 150ms, Off for 150ms).
A single press of the push-button should transition the system from its current state to the next one in the sequence (1 -> 2 -> 3 -> 4 -> 1...).
For the blinking states, you must not use the
delay() function. Using delay() would make your program unresponsive and unable to detect button presses while it is "delaying". Instead, you should use the millis() function to keep track of time without pausing the program.
5. Procedure
Part 1: State Machine Design (On Paper)
Before you write any code or connect any wires, you must design your state machine.
- Identify the States: List all the possible states of your system based on the problem description.
- Identify the Event: What is the single event that causes the system to change from one state to another?
- Sketch the State Diagram: Draw a state diagram. Each state should be a circle, and the transitions between states should be arrows. Label the arrows with the event that causes them. Your diagram should look something like this, but you need to fill in the details:
You will need to submit a picture of your final state diagram.
Part 2: Hardware Setup
Construct the circuit on your breadboard according to the diagram below. We will use Pin 8 for the LED and Pin 2 for the button.
- LED: Connect the long leg (anode) of the LED to the 220Ω resistor. Connect the other end of the resistor to Arduino Pin 8. Connect the short leg (cathode) of the LED to GND.
- Push-button: Connect one leg of the button to Arduino Pin 2. Connect the same leg to the 10kΩ resistor, and connect the other end of that resistor to GND (this is a pull-down resistor). Connect the other leg of the button to 5V.
Your wiring should look conceptually like this:
// Arduino Pin Connections // [Pin 8] --- [220Ω Resistor] --- [LED Anode (+)] // [LED Cathode (-)] --- [GND] // [5V] --- [Button Leg 1] // [Pin 2] --- [Button Leg 1] --- [10kΩ Resistor] --- [GND] // (Button Leg 2 is connected to Leg 1 internally)
Part 3: Software Implementation
Open the Arduino IDE and use the following skeleton code. Your task is to fill in the missing logic inside the loop() function.
The skeleton already defines the states using an enum, which is a good practice for making your code readable.
// Lab 2 - State Machine Control
// Student Name: [Your Name Here]
// Pin Definitions
#define LED_PIN 8
#define BUTTON_PIN 2
// State definitions for our State Machine
enum State {
S_OFF,
S_SOLID,
S_BLINK_SLOW,
S_BLINK_FAST
};
// Global variables
State currentState = S_OFF; // Initial state
int currentLedState = LOW; // To track the LED's on/off status for blinking
// Variables for button debouncing
long lastDebounceTime = 0;
long debounceDelay = 50; // 50 ms
// Variables for non-blocking blinking
unsigned long previousMillis = 0;
int blinkInterval = 500; // Default interval
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT);
digitalWrite(LED_PIN, LOW); // Start with LED off
}
void loop() {
// --- 1. Read the button state and handle debouncing ---
int buttonState = digitalRead(BUTTON_PIN);
// Check if the button is pressed and enough time has passed since the last press
if (buttonState == HIGH && (millis() - lastDebounceTime) > debounceDelay) {
// --- 2. State Transition Logic ---
// This is where you change from one state to the next.
// Use a switch statement or if-else chain on 'currentState'.
// Example: if (currentState == S_OFF) { currentState = S_SOLID; } ...
// YOUR STATE TRANSITION CODE GOES HERE
//
// After transitioning, print the new state to the Serial Monitor for debugging
Serial.print("New State: ");
Serial.println(currentState);
// Update the debounce timer
lastDebounceTime = millis();
}
// --- 3. State Action Logic ---
// This is where you define what happens IN each state.
// Use a switch statement on 'currentState'.
switch (currentState) {
case S_OFF:
// What should the LED do in the OFF state?
// YOUR CODE HERE
break;
case S_SOLID:
// What should the LED do in the SOLID ON state?
// YOUR CODE HERE
break;
case S_BLINK_SLOW:
// Set the correct blink interval
blinkInterval = 500;
// Use the handleBlinking() function below
handleBlinking();
break;
case S_BLINK_FAST:
// Set the correct blink interval
blinkInterval = 150;
// Use the handleBlinking() function below
handleBlinking();
break;
}
}
// Helper function to handle non-blocking blinking
void handleBlinking() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= blinkInterval) {
previousMillis = currentMillis; // Save the last time you blinked the LED
// If the LED is off, turn it on and vice-versa
if (currentLedState == LOW) {
currentLedState = HIGH;
} else {
currentLedState = LOW;
}
digitalWrite(LED_PIN, currentLedState);
}
}
6. Submission Requirements
You need to submit a single ZIP file containing the following:
- State Diagram (`.jpg` or `.pdf`): A clear photo or scan of your hand-drawn state machine diagram from Part 1.
- Arduino Code (`.ino` file): Your final, working Arduino code. Make sure to add your name at the top.
- Video Demonstration (`.mp4`): A short video (less than 1 minute) showing your circuit working. You must clearly demonstrate:
- The system starting in the OFF state.
- Pressing the button to cycle through all four states (OFF -> SOLID -> SLOW BLINK -> FAST BLINK).
- The cycle repeating by going from FAST BLINK back to OFF.