Selectable led sequence with push button to run program only one

Dear All

i am not much familar with programimg the program trying to make is to run only once by pushing button very similar to musical Door bell

here the program keep's running continues

Thanks in Advance

int switchPin = 2; // switch is connected to pin 2
int led1Pin = 6;
int led2pin = 7;
int led3Pin = 8;
int led4pin = 9;
int led5Pin = 10;
int led6pin = 11;
int led7Pin = 12;
int led8pin = 13;
int val; // variable for reading the pin status
int val2; // variable for reading the delayed status
int buttonState; // variable to hold the button state
int Mode = 0; // What mode is the light in?

void setup() {
  pinMode(switchPin, INPUT);    // Set the switch pin as input
  pinMode(led1Pin, OUTPUT);
  pinMode(led2pin, OUTPUT);
  pinMode(led3Pin, OUTPUT);
  pinMode(led4pin, OUTPUT);
  pinMode(led5Pin, OUTPUT);
  pinMode(led6pin, OUTPUT);
  pinMode(led7Pin, OUTPUT);
  pinMode(led8pin, OUTPUT);

  buttonState = digitalRead(switchPin);   // read the initial state
}

void loop(){
  val = digitalRead(switchPin);      // read input value and store it in val
  delay(10);                         // 10 milliseconds is a good amount of time
  val2 = digitalRead(switchPin);     // read the input again to check for bounces
  if (val == val2) {                 // make sure we got 2 consistant readings!
    if (val != buttonState) {          // the button state has changed!
      if (val == LOW) {                // check if the button is pressed
        if (Mode == 0) {          
          Mode = 1;               
        } else {
            if (Mode == 1) {        
            Mode = 2;           
        } else {
            if (Mode == 2) {      
            Mode = 3;           
        } else {
            if (Mode == 3) { 
            Mode = 0;          
              }
        }
       }
      }
     }
    }
    buttonState = val;                 // save the new state in our variable
  }

  // Now do whatever the lightMode indicates
  if (Mode == 0) { // all-off
    digitalWrite(led1Pin, LOW);
    digitalWrite(led2pin, LOW);
    digitalWrite(led1Pin, LOW);
    digitalWrite(led2pin, LOW);
    digitalWrite(led1Pin, LOW);
    digitalWrite(led2pin, LOW);
    digitalWrite(led1Pin, LOW);
    digitalWrite(led2pin, LOW);
  }

  if (Mode == 1) { 
    digitalWrite(led1Pin, HIGH);
    delay(500);
    digitalWrite(led2pin, LOW);
    delay(500);
    digitalWrite(led3Pin, HIGH);
    delay(500);
    digitalWrite(led4pin, LOW);
    delay(500);
    digitalWrite(led5Pin, HIGH);
    delay(500);
    digitalWrite(led6pin, LOW);
    delay(500);
    digitalWrite(led7Pin, HIGH);
    delay(500);
    digitalWrite(led8pin, LOW);
    delay(500);
    digitalWrite(led1Pin, LOW);
    delay(500);
    digitalWrite(led2pin, HIGH);
    delay(500);
    digitalWrite(led3Pin, LOW);
    delay(500);
    digitalWrite(led4pin, HIGH);
    delay(500);
    digitalWrite(led5Pin, LOW);
    delay(500);
    digitalWrite(led6pin, HIGH);
    delay(500);
    digitalWrite(led7Pin, LOW);
    delay(500);
    digitalWrite(led8pin, HIGH);
    delay(500);
  }

  if (Mode == 2) { 
    digitalWrite(led1Pin, HIGH);
    delay(500);
    digitalWrite(led2pin, HIGH);
    delay(500);
    digitalWrite(led3Pin, HIGH);
    delay(500);
    digitalWrite(led4pin, HIGH);
    delay(500);
    digitalWrite(led5Pin, HIGH);
    delay(500);
    digitalWrite(led6pin, HIGH);
    delay(500);
    digitalWrite(led7Pin, HIGH);
    delay(500);
    digitalWrite(led8pin, HIGH);
    
   
  }
  if (Mode == 3)  { 
    digitalWrite(led1Pin, HIGH);
    delay(500);
    digitalWrite(led2pin, HIGH);
    delay(500);
    digitalWrite(led3Pin, HIGH);
    delay(500);
    digitalWrite(led4pin, HIGH);
    delay(500);
    digitalWrite(led5Pin, HIGH);
    delay(500);
    digitalWrite(led6pin, HIGH);
    delay(500);
    digitalWrite(led7Pin, HIGH);
    delay(500);
    digitalWrite(led8pin, HIGH);
    delay(500);
    digitalWrite(led1Pin, LOW);
    delay(500);
    digitalWrite(led2pin, LOW);
    delay(500);
    digitalWrite(led3Pin, LOW);
    delay(500);
    digitalWrite(led4pin, LOW);
    delay(500);
    digitalWrite(led5Pin, LOW);
    delay(500);
    digitalWrite(led6pin, LOW);
    delay(500);
    digitalWrite(led7Pin, LOW);
    delay(500);
    digitalWrite(led8pin, LOW);
  }    
}

Why did you start a topic in the Uncategorised category of the forum when its description is

:warning: DO NOT CREATE TOPICS IN THIS CATEGORY :warning:

Your topic has been moved to the Programming category

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the < CODE/ > icon above the compose window) to make it easier to read and copy for examination

2 Likes
  • How is your switch wired ?

  • You do know delay( ) pauses your code for the delay amount of time ?

  • Have you ever used a Flag to enable/disable a process ?

Use code tags when attaching you sketch.

1 Like

look this over

void loop()
{
    byte val = digitalRead(switchPin);
    if (buttonState != val)  {
        buttonState = val;
        delay (20);     // debounce
        if (LOW == val) {
            if (3 < ++Mode)
                Mode = 0;
        }
    }

    // Now do whatever the lightMode indicates
    if (Mode == 0) { // all-off

1 Like
if (LOW == val)

I understand why you wrote the test that way, but to my mind it makes the logic of the code more difficult to understand than

if (val == LOW)

We are, after all, testing the value of val and in English the object of the comparison would normally be on the left of the comparison, ie "Is the value LOW ?" (English) rather than "is LOW the value ?" (Yoda)

Each to his/her own, but I know what I think makes more sense

1 Like

apparently it's called yoda-notation. see Logic question about a climate control function with temperature and humidity - #20 by DaveX

1 Like

I my mind I read the in-fix operators directly into my own c pidgin english as "if val equals LOW" or "if LOW equals val", and don't try to translate the code into english as either a pre-fix "is val low" or "is low val".

Is Yoda postfix/RPN?

1 Like

wouldn't it be LOW val == or val LOW == in RPN?

1 Like

Re postfix yoda, I was hearing LOW, val, is or val, LOW, is

1 Like

i see (hp25 x<=y and x=0

1 Like

your sequence will run as long as you press the button again (and change the mode).

However. I would make an Array to define which pins are on/off, and for how long and just jump through that array.

something like this:

/*
   Select between several LED sequences
   https://forum.arduino.cc/t/selectable-led-sequence-with-push-button-to-run-program-only-one/1126244/5
   2023-05-13 by noiasca
   sketch in forum
*/

const uint8_t switchPin = 2;                      // switch is connected to pin 2
const uint8_t pin[] {6, 7, 8, 9, 10, 11, 12, 13}; // the used output pins
const bool runOnce = true;                        // run only once by pushing
const bool on = HIGH;                             // set to LOW if output(relay) is LOW active
const bool off = LOW;                             // set to HIGH if output(relay) is LOW active
int buttonState;                                  // variable to hold the button state
int mode = 0;                                     // What mode is the light in?

struct Step {                // each step consists of:
  uint16_t out;              //   a bitmask
  uint32_t interval;         //   how long to be displayed
};

// now we create an array of steps, several steps are one sequence
// just define for each step, which output schould be on/which one should be off and the interval
Step sequenceA[] {
  {0b00000001, 1000},
  {0b00000101, 1000},
  {0b00010101, 1000},
  {0b01010101, 1000},
  {0b01010100, 500},
  {0b01010110, 500},
  {0b01010010, 500},
  {0b01011010, 500},
  {0b01001010, 500},
  {0b01101010, 500},
  {0b00101010, 500},
  {0b10101010, 500},
  {0b00000000, 500},
};

Step sequenceC[] {
  {0b00000001, 500},
  {0b00000011, 500},
  {0b00000111, 500},
  {0b00001111, 500},
  {0b00011111, 500},
  {0b00111111, 500},
  {0b01111111, 500},
  {0b11111111, 500},
  {0b11111110, 500},
  {0b11111100, 500},
  {0b11111000, 500},
  {0b11110000, 500},
  {0b11100000, 500},
  {0b11000000, 500},
  {0b10000000, 500},
  {0b00000000, 500},
};

byte actual = 0;  // step within a sequence
// this takes care of the time management of the sequence and runs the steps
// it needs a pointer to a sequence (=an array of steps), and the number of steps
void runSequence(Step * step, size_t noOfSteps) {
  static uint32_t previousMillis = 0;
  uint32_t currentMillis = millis();
  if (currentMillis - previousMillis > step[actual].interval) {
    previousMillis = currentMillis;
    if (actual >= noOfSteps && runOnce) return;
    Serial.print(F(" mode=")); Serial.print(mode);       // just for debug printing ...
    Serial.print(F(" actual=")); Serial.print(actual);
    Serial.print(F("\t0b"));
    for (int i = sizeof(pin) - 1; i >= 0 ; --i) {
      if (step[actual].out & (1 << i)) {
        digitalWrite(pin[i], on);
        Serial.print('1');
      }
      else {
        digitalWrite(pin[i], off);
        Serial.print('0');
      }
    }
    Serial.println();
    actual++;  // for the next run
    if (actual >= noOfSteps && !runOnce) actual = 0;  // rollover if sequence should  loop infinite
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(switchPin, INPUT);              // Set the switch pin as input
  for (auto &i : pin) pinMode(i, OUTPUT); // set all led pins to outputs
  buttonState = digitalRead(switchPin);   // read the initial state
}

void allPins(int val) {
  for (auto &i : pin) digitalWrite(i, val); // switch all pins
}

void loop() {
  int val = digitalRead(switchPin);
  if (buttonState != val)  {
    buttonState = val;
    delay (20);     // debounce
    if (val == LOW) {
      if (3 < ++mode) {
        mode = 0;
        allPins(off);
      }
      actual = 0;
      Serial.println(mode);
      if (mode == 2) allPins(on);
    }
  }
  // in some modes we must call runSequence
  if (mode == 1) runSequence(sequenceA,  sizeof(sequenceA) / sizeof(sequenceA[0]));
  else if (mode == 3) runSequence(sequenceC,  sizeof(sequenceC) / sizeof(sequenceC[0]));
}

The sketch remains very responsive (= can react on new button presses) as the only delay is used for debouncing the button. The rest is non blocking code.

1 Like

Dear Noiasca

Thank You very much for Array code it worked as i was looking for

here made some changes

void loop() {
  int val = digitalRead(switchPin);
  if (buttonState != val)  {
    buttonState = val;
    delay (20);     // debounce
    if (val == LOW) {
      if (3 < ++mode) {
        mode = 0;
        allPins(off); **code 1**
      }
      actual = 0;
      Serial.println(mode);
      if (mode == 2) allPins(on); **code 2**
    }

As button push after Sequence C Code 1 was making all led off so i removed
And button push after Sequence A Code 2 was making all led On so i removed

Here is the code also added some more sequence please make changes you feel is not correct

/*
   Select between several LED sequences
   https://forum.arduino.cc/t/selectable-led-sequence-with-push-button-to-run-program-only-one/1126244/5
   2023-05-13 by noiasca
   sketch in forum
*/

const uint8_t switchPin = 2;                      // switch is connected to pin 2
const uint8_t pin[] {6, 7, 8, 9, 10, 11, 12, 13}; // the used output pins
const bool runOnce = true;                        // run only once by pushing
const bool on = HIGH;                             // set to LOW if output(relay) is LOW active
const bool off = LOW;                             // set to HIGH if output(relay) is LOW active
int buttonState;                                  // variable to hold the button state
int mode = 0;                                     // What mode is the light in?

struct Step {                // each step consists of:
  uint16_t out;              //   a bitmask
  uint32_t interval;         //   how long to be displayed
};

// now we create an array of steps, several steps are one sequence
// just define for each step, which output schould be on/which one should be off and the interval
Step sequenceA[] {
  {0b00000001, 200},
  {0b00000101, 200},
  {0b00010101, 200},
  {0b01010101, 200},
  {0b01010100, 200},
  {0b01010110, 200},
  {0b01010010, 200},
  {0b01011010, 200},
  {0b01001010, 200},
  {0b01101010, 200},
  {0b00101010, 200},
  {0b10101010, 200},
  {0b00000000, 200},
};
Step sequenceB[] {
  {0b00000000, 200},
  {0b01010101, 200},
  {0b10101010, 200},
  {0b01010101, 200},
  {0b10101010, 200},
  {0b01010101, 200},
  {0b10101010, 200},
  {0b01010101, 200},
  {0b10101010, 200},
  {0b01010101, 200},
  {0b10101010, 200},
  {0b01010101, 200},
  {0b10101010, 200},
  {0b01010101, 200},
  {0b10101010, 200},
  {0b01010101, 200},
  {0b10101010, 200},
  {0b00000000, 200},
};
Step sequenceC[] {
  {0b00000001, 200},
  {0b00000011, 200},
  {0b00000111, 200},
  {0b00001111, 200},
  {0b00011111, 200},
  {0b00111111, 200},
  {0b01111111, 200},
  {0b11111111, 200},
  {0b11111110, 200},
  {0b11111100, 200},
  {0b11111000, 200},
  {0b11110000, 200},
  {0b11100000, 200},
  {0b11000000, 200},
  {0b10000000, 200},
  {0b00000000, 200},
};
Step sequenceD[] {
  {0b10000001, 200},
  {0b11000011, 200},
  {0b11100111, 200},
  {0b11111111, 200},
  {0b00000000, 200},
  {0b00011000, 200},
  {0b00111100, 200},
  {0b01111110, 200},
  {0b11111111, 200},
  {0b00000000, 200},
  {0b10000001, 200},
  {0b11000011, 200},
  {0b11100111, 200},
  {0b11111111, 200},
  {0b00000000, 200},
  {0b00011000, 200},
  {0b00111100, 200},
  {0b01111110, 200},
  {0b11111111, 200},
  {0b00000000, 200},
};
Step sequenceE[] {
  {0b10000000, 200},
  {0b11000000, 200},
  {0b01100000, 200},
  {0b00110000, 200},
  {0b00011000, 200},
  {0b00001100, 200},
  {0b00000110, 200},
  {0b00000011, 200},
  {0b00000001, 200},
  {0b00000000, 200},
  {0b00000001, 200},
  {0b00000011, 200},
  {0b00000110, 200},
  {0b00001100, 200},
  {0b00011000, 200},
  {0b00110000, 200},
  {0b01100000, 200},
  {0b11000000, 200},
  {0b10000000, 200},
  {0b00000000, 200},
  {0b10000000, 200},
  {0b11000000, 200},
  {0b01100000, 200},
  {0b00110000, 200},
  {0b00011000, 200},
  {0b00001100, 200},
  {0b00000110, 200},
  {0b00000011, 200},
  {0b00000001, 200},
  {0b00000000, 200},
  {0b00000001, 200},
  {0b00000011, 200},
  {0b00000110, 200},
  {0b00001100, 200},
  {0b00011000, 200},
  {0b00110000, 200},
  {0b01100000, 200},
  {0b11000000, 200},
  {0b10000000, 200},
  {0b00000000, 200},
};
byte actual = 0;  // step within a sequence
// this takes care of the time management of the sequence and runs the steps
// it needs a pointer to a sequence (=an array of steps), and the number of steps
void runSequence(Step * step, size_t noOfSteps) {
  static uint32_t previousMillis = 0;
  uint32_t currentMillis = millis();
  if (currentMillis - previousMillis > step[actual].interval) {
    previousMillis = currentMillis;
    if (actual >= noOfSteps && runOnce) return;
    Serial.print(F(" mode=")); Serial.print(mode);       // just for debug printing ...
    Serial.print(F(" actual=")); Serial.print(actual);
    Serial.print(F("\t0b"));
    for (int i = sizeof(pin) - 1; i >= 0 ; --i) {
      if (step[actual].out & (1 << i)) {
        digitalWrite(pin[i], on);
        Serial.print('1');
      }
      else {
        digitalWrite(pin[i], off);
        Serial.print('0');
      }
    }
    Serial.println();
    actual++;  // for the next run
    if (actual >= noOfSteps && !runOnce) actual = 0;  // rollover if sequence should  loop infinite
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(switchPin, INPUT);              // Set the switch pin as input
  for (auto &i : pin) pinMode(i, OUTPUT); // set all led pins to outputs
  buttonState = digitalRead(switchPin);   // read the initial state
}

void allPins(int val) {
  for (auto &i : pin) digitalWrite(i, val); // switch all pins
}

void loop() {
  int val = digitalRead(switchPin);
  if (buttonState != val)  {
    buttonState = val;
    delay (20);     // debounce
    if (val == LOW) {
      if (5 < ++mode) {
        mode = 1;  
      }
      actual = 0;
      Serial.println(mode);  
    }
  }
  // in some modes we must call runSequence
  if (mode == 1) runSequence(sequenceA,  sizeof(sequenceA) / sizeof(sequenceA[0]));
  if (mode == 2) runSequence(sequenceB,  sizeof(sequenceB) / sizeof(sequenceB[0]));
  if (mode == 3) runSequence(sequenceC,  sizeof(sequenceC) / sizeof(sequenceC[0]));
  if (mode == 4) runSequence(sequenceD,  sizeof(sequenceD) / sizeof(sequenceD[0]));
  if (mode == 5) runSequence(sequenceE,  sizeof(sequenceE) / sizeof(sequenceE[0]));
}

at present i am using simultor SimulIDE

This is the primary project and need to devolop hardware which will take time once done, the secondary project will be sequence file trasfer through wifi with mobile application.

Thanks Once again for taking time writing code.

Mahesh Peswani

nice.
You can mark one answer as solution.
You can say thank you to several helpers by pressing the heart under their post (also other have helped you!)

1 Like

Thanking You'll for organizing and instant replying and getting solution within 24hrs.

Best Regards

Mahesh Peswani

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.