I'm currently working on project which takes the button as input and when we click the button starting from the first LED it shifts and after each 0.5 seconds LEDs follow each other. Interrupt function works perfectly, but the problem is that interrupt works when the loop is finished. I want to turn of the LEDs when I click the button. How to solve this issue?
int button;
void setup() {
DDRD = B11110000;
attachInterrupt(digitalPinToInterrupt(2), buttonPressed, RISING);
}
void loop() {
if(button) {
PORTD = B00010000;
delay(500);
PORTD = PORTD <<1;
delay(500);
PORTD = PORTD <<1;
delay(500);
PORTD = PORTD <<1;
delay(500);
}
else {
PORTD = B00000000;
}
}
void buttonPressed() {
if(button == 0) {
button = 1;
}else {
button = 0;
}
}
Instead of doing the whole loop you can rewrite the code to check the button state for each LED. This means that the LED will still always stay lit the full .5 second period.
int button;
void setup() {
DDRD = B11110000;
attachInterrupt(digitalPinToInterrupt(2), buttonPressed, RISING);
}
void loop() {
if(button) {
PORTD = PORTD <<1;
if (PORTD == 0) {
PORTD = B00010000;
}
delay(500);
} else {
PORTD = B00000000;
}
}
void buttonPressed() {
button = !button;
}
To make the LEDs dark immediately you should not use delay, but rather loop for up to .5 seconds and check the button state;
unsigned long timeout = millis() + 500;
while (button && millis() < timeout);
Or a bit more in context
void loop() {
if(button) {
next_light();
sleep(500);
} else {
PORTD = B00000000;
}
}
void next_light() {
PORTD = PORTD <<1;
if (PORTD == 0) {
PORTD = B00010000;
}
}
void sleep(unsigned long timeout) {
unsigned long end = millis() + timeout;
while (button && millis() < end);
}
void buttonPressed() {
button = !button;
}