#include <Arduino.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/atomic.h>
#define LED_MASK 0x07
volatile uint8_t buttonEvent = 0;
uint8_t patternStep = 0;
unsigned long lastPressTime = 0;
// This is purely AI generated Code
// External interrupt INT0: Arduino D2
ISR(INT0_vect)
{
buttonEvent = 1;
}
void setup()
{
// D8, D9, D10 = PB0, PB1, PB2
DDRB |= LED_MASK;
PORTB &= ~LED_MASK;
// D2 / PD2 input with internal pull-up
DDRD &= ~(1 << DDD2);
PORTD |= (1 << PORTD2);
// Configure INT0 for falling-edge trigger
EICRA &= ~((1 << ISC00) | (1 << ISC01));
EICRA |= (1 << ISC01);
// Clear pending interrupt and enable INT0
EIFR = (1 << INTF0);
EIMSK |= (1 << INT0);
lastPressTime = millis() - 200;
// Enable global interrupts
sei();
}
void loop()
{
uint8_t event;
// Read and clear the event safely
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
event = buttonEvent;
buttonEvent = 0;
}
// Debounce outside the ISR
if (event && (millis() - lastPressTime >= 200))
{
lastPressTime = millis();
patternStep++;
if (patternStep > 4)
patternStep = 1;
}
uint8_t leds = 0;
switch (patternStep)
{
case 1: leds = 0b001; break;
case 2: leds = 0b010; break;
case 3: leds = 0b100; break;
case 4: leds = 0b111; break;
default: leds = 0; break;
}
// Update LED outputs using PORTB
PORTB = (PORTB & ~LED_MASK) | (leds & LED_MASK);
}