Hi all,
I'm trying to write the code to program the following functions for a building 7 LED sequence but I want to add one push button with start/stop function.
the sequence would run as follows:
Push button press to start the sequence -> first led switches on -> second led switches on, first light remains lit -> third led switches on, previous 2 stay lit ->fourth led switches on, previous 3 stay lit -> [..] -> 7th led switches on, previous 6 leds stay lit -> all leds remain on until push button pressed again then all leds switch off.
I have written the following code allowing for button bounce etc but when I run it as a demo the button starts the sequence but doesn't turn it all off when pressed again. I am guessing I am missing a crucial bit of code OR I have put my code lines in the wrong place? is anyone able to help!
It looks like your code works upon button RELEASE, not button PRESS. The following code should function the same way. Try this slightly modified but untested version with plenty of comments:
#define LED_PIN1 2
#define LED_PIN2 3
#define LED_PIN3 4
#define LED_PIN4 5
#define LED_PIN5 6
#define LED_PIN6 7
#define LED_PIN7 8
#define BUTTON_PIN 9
// Store previous button state to detect changes
byte lastButtonState;
// Store whether or not the LED sequence should be ON or OFF
byte ledState = LOW;
// Button debounce timing
unsigned long lastTimeButtonStateChanged = millis();
unsigned long debounceDuration = 50; // debounce time in milliseconds
void setup() {
// Configure all LED pins as outputs
pinMode(LED_PIN1, OUTPUT);
pinMode(LED_PIN2, OUTPUT);
pinMode(LED_PIN3, OUTPUT);
pinMode(LED_PIN4, OUTPUT);
pinMode(LED_PIN5, OUTPUT);
pinMode(LED_PIN6, OUTPUT);
pinMode(LED_PIN7, OUTPUT);
// Configure the button pin as an input
// IMPORTANT- The assumption is that a pull down resistor is being used
pinMode(BUTTON_PIN, INPUT);
// Read the initial button state at startup
lastButtonState = digitalRead(BUTTON_PIN);
}
void loop() {
// Check debounce timing
if (millis() - lastTimeButtonStateChanged >= debounceDuration) {
// Read current state button
byte buttonState = digitalRead(BUTTON_PIN);
// If button state changed since the last check...
if (buttonState != lastButtonState) {
// Record the time of this change (later used for debounce timing)
lastTimeButtonStateChanged = millis();
// Update stored button state
lastButtonState = buttonState;
// Only act when the button is RELEASED (LOW)
// This should ensure only one trigger per button cycle
if (buttonState == LOW) {
// Toggle the LED state variable
if (ledState == HIGH) {
ledState = LOW; // If LEDs were ON, turn them OFF
} else {
ledState = HIGH; // If LEDs were OFF, start the sequence
}
// If LEDs are supposed to be ON
if (ledState == HIGH) {
// Turn on LEDs one at a time with a delay
//IMPORTANT--You have 7 seconds of delay that prevents anything else from happening
digitalWrite(LED_PIN1, HIGH);
delay(1000);
digitalWrite(LED_PIN2, HIGH);
delay(1000);
digitalWrite(LED_PIN3, HIGH);
delay(1000);
digitalWrite(LED_PIN4, HIGH);
delay(1000);
digitalWrite(LED_PIN5, HIGH);
delay(1000);
digitalWrite(LED_PIN6, HIGH);
delay(1000);
digitalWrite(LED_PIN7, HIGH);
delay(1000);
}
// If LEDs are supposed to be OFF
else {
digitalWrite(LED_PIN1, LOW);
digitalWrite(LED_PIN2, LOW);
digitalWrite(LED_PIN3, LOW);
digitalWrite(LED_PIN4, LOW);
digitalWrite(LED_PIN5, LOW);
digitalWrite(LED_PIN6, LOW);
digitalWrite(LED_PIN7, LOW);
}
}
}
}
}
You could probably light your LEDs in a for loop. It would be a little tidier. Also, if nothing NEVER needs to happen while the LEDs are being lit, the delays are fine. If you ever want to expand the code to where something else might need to happen while they are being lit, time them using the millis().
At no time does the original code turn the LEDs off.
The main goal is to change from a state of "cycling LEDs" to "NOT cycling LEDs" which is initiated by a button press. This sketch uses a "turn all LEDs off" function in both "cycle LEDs" and "NOT cycle LEDs" to simplify the code.
#define BUTTON_PIN 9
int ledPin[] = {2, 3, 4, 5, 6, 7, 8};
int numLeds = sizeof(ledPin) / sizeof(ledPin[0]);
bool cyclestate = LOW, buttonState, lastButtonState;
unsigned long timer, timeout = 50; // milliseconds
int i, j;
void setup() {
for (byte i = 0; i < numLeds; i++) {
pinMode(ledPin[i], OUTPUT);
}
pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop() {
byte buttonState = digitalRead(BUTTON_PIN);
delay(10); // cheap button debounce
if (buttonState == LOW && lastButtonState == HIGH) // LOW = button PRESSED
cyclestate = !cyclestate; // ... change LED cycle state
if (cyclestate == HIGH)
ledCycle(); // cycle the LEDs
if (cyclestate == LOW)
ledOff(); // turn LEDs off
lastButtonState = buttonState; // store last button state
}
void ledCycle() {
if (millis() - timer > timeout) { // cycle timeout exceeded...
timer = millis(); // ... reset cycle timer
if (i == numLeds) // count number of LEDs
i = 0; // reset count
ledOff(); // turn all LEDs OFF
digitalWrite(ledPin[i], HIGH); // turn this LED ON
i++; // next LED
}
}
void ledOff() {
for (byte i = 0; i < numLeds; i++) // count all LEDs...
digitalWrite(ledPin[i], LOW); // ... turn OFF
}