Editorial Solution

First, we need to connect four LEDs to Arduino and we need a proper resistor for each LED to limit the current flowing through them to 10mA.

As we can see below, 1.8V is the voltage drop across LED so the resistor value is 320Ω. We can use a standard resistor near 320Ω which is 330Ω or 300Ω.   

 

 

  • We need to use a push button switch to change the LED blinking pattern. While interfacing the switch, we need to carefully connect it, so that it will provide GPIO levels i.e. LOW and HIGH.
  • To ensure proper HIGH and LOW voltage levels, we need to use a pull-up or pull-down configuration.
  • However, Arduino UNO GPIO has an internal PULLUP Resistor, which can be used for the Switch interface.
  • To enable the internal pull-up resistor, configure the GPIO pin as follows:

 pinMode(switch_pin, INPUT_PULLUP);

Circuit Diagram 

Code

const int led_pins[] = { 2, 3, 4, 5 };            // LEDs connected to pins
const int switch_pin = 12;                        // Pin for the switch

// Arrays related to LED Patterns
const int pattern_lengths[] = { 2, 2, 4, 2, 2 };  
const int patterns[][4][4] = {  
    { { 1, 1, 1, 1 }, { 0, 0, 0, 0 } },                                      // Pattern 0
    { { 1, 0, 1, 0 }, { 0, 1, 0, 1 } },                                      // Pattern 1
    { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } },      // Pattern 2
    { { 1, 1, 0, 0 }, { 0, 0, 1, 1 } },                                      // Pattern 3
    { { 1, 0, 0, 1 }, { 0, 1, 1, 0 } }                                       // Pattern 4
};

unsigned int flag_check = 1;          // Controls the execution of the current pattern
int pattern_index = 0;                // Current pattern index
unsigned long debounce_delay = 50;    // Debounce delay in milliseconds
int last_button_state = 1;            // Previous button state (1: not pressed, 0: pressed)
int current_button_state = 1;         // Current button state
unsigned long last_debounce_time = 0; // Timestamp of the last button state change

void setup() {
   
    for (int i = 0; i < 4; i++) {
        pinMode(led_pins[i], OUTPUT);
    }

    pinMode(switch_pin, INPUT_PULLUP);    
}

void loop() {
    // Execute the selected pattern
    while (flag_check) {
        // Iterate through each step of the current pattern
        for (int j = 0; j < pattern_lengths[pattern_index]; j++) {
            set_leds(patterns[pattern_index][j]);                     // Set LEDs for the current step
            flag_check = delay_with_button_check(500);                // Wait with button check
            if (!flag_check) break;                                   // Exit if the button is pressed
        }
        if (!flag_check) break;                                       // Exit the pattern loop if the button is pressed
    }
    flag_check = 1;                                                   // Reset flag after pattern completion
}


 // Checks if the button is pressed and debounced.
 
bool is_debounced_press(int button_pin) {
    int reading = digitalRead(button_pin); 

    // If the button state has changed, reset the debounce timer
    if (reading != last_button_state) {
        last_debounce_time = millis();
    }
    last_button_state = reading; 
    // If the button state is stable for more than 50 msec the debounce delay, update the state.
    if ((millis() - last_debounce_time) > debounce_delay) {
        if (reading != current_button_state) {
            current_button_state = reading;
            
            // Return true if the button is pressed (LOW state)
            if (current_button_state == 0) {
                return true;  // valid press detected
            }
        }
    }
    return false;                // No valid press detected
}


// Implements a delay while checking for button press. 
 
bool delay_with_button_check(long delay_duration) {
    long delay_start_time = millis(); // Record the start time of the delay
    while ((millis() - delay_start_time) < delay_duration) {
        if (is_debounced_press(switch_pin)) {
            pattern_index = (pattern_index + 1) % 5; // Cycle to the next pattern
            return false;                            // Exit delay early
        }
    }
    return true; // Continue executing the pattern
}

// Set the states of the LEDs
void set_leds(const int states[]) {
  for (int i = 0; i < 4; i++) {
    digitalWrite(led_pins[i], states[i]);
  }
}

Understanding code

  • Pattern Execution: Start with pattern0, and poll the switch for presses.
  • Switch Press Detection: Press changes to the next pattern and no press continues the current pattern.
  • Looping: After the last pattern, loop back to pattern0.
  • Polling: Continuously poll to ensure presses are detected.
  • Debounce: is_debounced_press(); prevents false presses.
  • Delay: delay_with_button_check(); Waits, checks for press, changes pattern if pressed, otherwise continues the delay.

OUTPUT

  • LED and switch interfacing with Arduino UNO

 


Output Video
 

Submit Your Solution