/*
* 74HC595 LED Chase Effect - FSM Style
*
* Wiring Connections:
* ┌─────────────────┬──────────┬─────────────────────────┐
* │ 74HC595 │ Pin │ Arduino Connection │
* ├─────────────────┼──────────┼─────────────────────────┤
* │ DS (Data) │ 14 │ D8 │
* │ SHCP (Clock) │ 11 │ D12 │
* │ STCP (Latch) │ 12 │ D11 │
* │ MR (Reset) │ 10 │ 5V │
* │ OE (Enable) │ 13 │ GND │
* │ VCC │ 16 │ 5V │
* │ GND │ 8 │ GND │
* └─────────────────┴──────────┴─────────────────────────┘
*
* LED Connections: Q0~Q7 -> 560Ω -> LED -> GND
*/
const int PIN_DATA = 8;
const int PIN_CLOCK = 12;
const int PIN_LATCH = 11;
const unsigned long INTERVAL_TIME = 500;
const int TOTAL_LEDS = 8;
enum class State
{
LED_ON,
LED_OFF
};
State current_state = State::LED_OFF;
unsigned long previous_millis = 0;
int current_led = 0;
void setup()
{
initialize_hardware();
initialize_state();
}
void loop()
{
if (is_time_to_transition())
{
update_time_stamp();
process_current_state();
}
}
void initialize_hardware()
{
pinMode(PIN_DATA, OUTPUT);
pinMode(PIN_CLOCK, OUTPUT);
pinMode(PIN_LATCH, OUTPUT);
}
void initialize_state()
{
current_state = State::LED_OFF;
current_led = 0;
turn_off_all_leds();
}
bool is_time_to_transition()
{
unsigned long current_millis = millis();
return (current_millis - previous_millis >= INTERVAL_TIME);
}
void update_time_stamp()
{
previous_millis = millis();
}
void process_current_state()
{
switch (current_state)
{
case State::LED_ON:
handle_led_on_state();
break;
case State::LED_OFF:
handle_led_off_state();
break;
}
}
void handle_led_on_state()
{
turn_off_all_leds();
transition_to_led_off_state();
move_to_next_led();
}
void handle_led_off_state()
{
turn_on_current_led();
transition_to_led_on_state();
}
void transition_to_led_on_state()
{
current_state = State::LED_ON;
}
void transition_to_led_off_state()
{
current_state = State::LED_OFF;
}
void turn_on_current_led()
{
byte pattern = 1 << current_led;
update_shift_register(pattern);
}
void turn_off_all_leds()
{
update_shift_register(0x00);
}
void move_to_next_led()
{
current_led++;
if (current_led >= TOTAL_LEDS)
{
current_led = 0;
}
}
void update_shift_register(byte pattern)
{
digitalWrite(PIN_LATCH, LOW);
shiftOut(PIN_DATA, PIN_CLOCK, MSBFIRST, pattern);
digitalWrite(PIN_LATCH, HIGH);
}