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Ω.
pinMode(switch_pin, INPUT_PULLUP);
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]);
}
}