HOW TO INSERT OVER RIDE SWITCH ON MY PROGRAM

I have made one program with the help of forum.brief explanation of my project is that i have three led and it will turn on by one by one ,led will turn on 10 sec and get off immediately LED2 will get ON for 10 Sec and get OFF same as third led also.

Here is my program.its working satisfactory.

int led = 13;
int led2 = 12;
int led3 = 11;
int timer = 1000;
// the setup routine runs once when you press reset:
void setup()
{
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop()
{
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  timeDelay();//delay(timer);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  digitalWrite(led2, HIGH);
  timeDelay();//delay(timer);
  digitalWrite(led2, LOW);
  digitalWrite(led3, HIGH);
  timeDelay();//delay(timer);
  digitalWrite(led3, LOW);
}

void timeDelay()
{
  unsigned long presentMillis = millis();//read present time of Arduino Timer
  while(millis()- presentMillis <= 10000)  //checking if 10000 ms has elapsed
  {
    ; //do nothing
  }
}

Now i want to introduce one Push button as a over ride switch.That means if push button press and release the current immediately current led will get OFF( led not wait 10 sec.) and turn ON the next led2 ,if again operate the switch led2 will get off immediately and jump to next led3.

please advice how changes are to be made in the program for achieving this.

Looks to me like your timeDelay() function is just like delay(), in spite of being millis()-based internally. It just uses millis() to do nothing....

That means your button's press is going to be blocked, just as if you used delay(). To get a button to work, or at least to be decently responsive, you need to re-jig the code using millis() properly.

That means if push button press and release the current immediately current led will get OFF( led not wait 10 sec.)

You were forewarned in your other thread that your timeDelay() function was leading you up the garden path to a dead end

Read Using millis() for timing. A beginners guide, Several things at the same time and look at the BlinkWithoutDelay example in the IDE.

meltDown:
That means your button's press is going to be blocked, just as if you used delay(). To get a button to work, or at least to be decently responsive, you need to re-jig the code using millis() properly.

thank you for your reply,please give me the threads to make the program.

sreekanthmp:
please give me the threads to make the program.

No idea what that means....


UKHelibob's reply #2 in your other thread was a proper millis()-based solution. It's not clear from subsequent discussion if it was perfect, but it certainly is the kind of thing you would have pursued, if AKRF and GolamMostafa hadn't painted you into the corner.

I think you should start from there.

sreekanthmp:
thank you for your reply,please give me the threads to make the program.

See reply #2

meltDown:
Looks to me like your timeDelay() function is just like delay(), in spite of being millis()-based internally. It just uses millis() to do nothing....

That means your button's press is going to be blocked, just as if you used delay(). To get a button to work, or at least to be decently responsive, you need to re-jig the code using millis() properly.

Excuse me... eh, isn't this really easy to do just now. Ok, we'll need to make sure the button is properly released as well, but simply adding some code instead of 'do nothing' and an extra condition would suffice.

void timeDelay()
{
  bool buttonpressed=false;
  unsigned long presentMillis = millis();//read present time of Arduino Timer
  while ((millis()- presentMillis <= 10000) && (!buttonpress)) //checking if 10000 ms has elapsed
  {
    if (!digitalRead(BUTTON_PIN) buttonpressed=true; // assuming active LOW
  }
  while (buttonpressed) {
     delay(100); // for debounce
     if (digitalRead(BUTTON_PIN) buttonpressed=false; // wait for the release
  }
}

assuming active LOW for the button. Since the time delay is already there as a separate function. Of course you could move the debounce to the beginning of the function and make buttonpressed static but as a general idea i don't see what the problem is. (OTHER THAN: "DO NOT USE CAPITALS IN THE TOPIC NAME")

Ok that's fair enough.... good thinking BatMan

The sketch below does what the code in the opening post here does, but with a "real" implementation of millis() and blink without delay() thinking.

It uses the bwod logic, but instead of blinking one led, it increments the ledNumber and uses that as the case in a switch... case. The millis()-based timing and the switch...case are handled in functions to keep things nice and tidy.

(It would benefit from arrays I guess, but in the interests of not hitting the OP with too much at once, that can be another day.)

OP, see if you can follow this thinking and try figure out where and how to implement your button to jump ahead to the next led. (I have already written that solution but will only reveal it if you ask.... hint #1, becasue the code is delay()-less you can pretty much read the button where you like; hint #2, look at the state change detect example to see how to read a button.)

//   https://forum.arduino.cc/index.php?topic=630113
//  7 august 2019

// this mark2 using millis() properly
// DOES NOT implement the skip button... that will be mark3

byte led1 = 11;
byte led2 = 12;
byte led3 = 13;
int interval = 1000;
unsigned long previousMillisLed;
byte ledNumber;

void setup()
{
  Serial.begin(9600);
  Serial.println(".... 630133 mk2 proper bwod  ....");
  Serial.print("Compiler: ");
  Serial.print(__VERSION__);
  Serial.print(", Arduino IDE: ");
  Serial.println(ARDUINO);
  Serial.print("Created: ");
  Serial.print(__TIME__);
  Serial.print(", ");
  Serial.println(__DATE__);
  Serial.println(__FILE__);

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);

  Serial.println("setup() complete");

} //setup

// the loop routine runs over and over again forever:
void loop()
{
  doMillisStuff();
  handleTheStates();
}//loop

void doMillisStuff()
{
  if (millis() - previousMillisLed >= interval)
  {
    previousMillisLed = millis();
    ledNumber++;
    if (ledNumber == 4) ledNumber = 1;
    Serial.println(ledNumber);
  }
}//millis stuff

void handleTheStates()
{
  switch (ledNumber)
  {
    case 1:
      digitalWrite(led1, HIGH);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      break;

    case 2:
      digitalWrite(led1, LOW);
      digitalWrite(led2, HIGH);
      digitalWrite(led3, LOW);
      break;

    case 3:
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, HIGH);
      break;
  }//switch
}//states
  Serial.println(".... 630133 mk2 proper bwod  ....")

Are you sure ?

UKHeliBob:

  Serial.println(".... 630133 mk2 proper bwod  ....")

Are you sure ?

I was :wink: but I actually meant "proper millis"

This code is actually better and simper than the sketch in #8.

I changed my mind about the switch...case, and here use an array to turn all the leds off every time the interval expires, and immediately turn the correct one on:

//   https://forum.arduino.cc/index.php?topic=630113
//  7 august 2019

// this mark2a using millis() properly
// this one uses an array instead of switch...case
byte ledPins[] = {11, 12, 13}; //index from 0 to 2 for 3 leds
byte howManyLEDs = 3;
int interval = 1000;
unsigned long previousMillisLed;
byte ledNumber = -1;

void setup()
{
  Serial.begin(9600);
  Serial.println(".... 630113 mk2a proper millis()  with array");
  Serial.print("Compiler: ");
  Serial.print(__VERSION__);
  Serial.print(", Arduino IDE: ");
  Serial.println(ARDUINO);
  Serial.print("Created: ");
  Serial.print(__TIME__);
  Serial.print(", ");
  Serial.println(__DATE__);
  Serial.println(__FILE__);

  for (int i = 0; i < howManyLEDs; i++)
  {
    pinMode(ledPins[i], OUTPUT);
  }

  Serial.println("setup() complete");

} //setup

// the loop routine runs over and over again forever:
void loop()
{
  doMillisStuff();
  lightTheLeds();
}//loop

void doMillisStuff()
{
  if (millis() - previousMillisLed >= interval)
  {
    previousMillisLed = millis();
    ledNumber++;
    if (ledNumber == 3) ledNumber = 0;
    Serial.println(ledNumber);
  }
}//millis stuff

void lightTheLeds()
{
  //turn them all off
  for (int i = 0; i < howManyLEDs; i++)
  {
    digitalWrite(ledPins[i], LOW);
  }

  //and immediately turn on the right one
  digitalWrite(ledPins[ledNumber], HIGH);


}//lightTheLeds

meltDown:
I was :wink: but I actually meant "proper millis"

Actually I was referring to the number, which I took to be a reference to the number of this topic, except that it isn't the correct number

meltDown:
Ok that's fair enough.... good thinking BatMan

Thanx, i'm not Batman though... I like those other sketches, always good to see someone actually taking the time to explain something.

UKHeliBob:
Actually I was referring to the number, which I took to be a reference to the number of this topic, except that it isn't the correct number

oh yeah.... 630113 not 133

meltDown:
)

OP, see if you can follow this thinking and try figure out where and how to implement your button to jump ahead to the next led. (I have already written that solution but will only reveal it if you ask.... hint #1, becasue the code is delay()-less you can pretty much read the button where you like; hint #2, look at the state change detect example to see how to read a button.)

Sir,
its working but what are the changes i have to make while inserting push button as a over ride switch.please help me.

sreekanthmp:
.please help me.

Does that mean you want a solution? I gave you 2 hints... Have you tried to adapt the code I already gave?

Deva_Rishi:
Excuse me... eh, isn't this really easy to do just now. Ok, we'll need to make sure the button is properly released as well, but simply adding some code instead of 'do nothing' and an extra condition would suffice.

void timeDelay()

{
 bool buttonpressed=false;
 unsigned long presentMillis = millis();//read present time of Arduino Timer
 while ((millis()- presentMillis <= 10000) && (!buttonpress)) //checking if 10000 ms has elapsed
 {
   if (!digitalRead(BUTTON_PIN) buttonpressed=true; // assuming active LOW
 }
 while (buttonpressed) {
    delay(100); // for debounce
    if (digitalRead(BUTTON_PIN) buttonpressed=false; // wait for the release
 }
}

its not working!

here is my code

int BUTTON_PIN = 8;
int led = 2;
int led2 = 6;
int led3 = 7;
int timer = 1000;
// the setup routine runs once when you press reset:
void setup()
{
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop()
{
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  timeDelay();//delay(timer);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  digitalWrite(led2, HIGH);
  timeDelay();//delay(timer);
  digitalWrite(led2, LOW);
  digitalWrite(led3, HIGH);
  timeDelay();//delay(timer);
  digitalWrite(led3, LOW);
}
 void timeDelay()
{
  bool buttonpressed=false;
  unsigned long presentMillis = millis();//read present time of Arduino Timer
  while ((millis()- presentMillis <= 10000) && (!buttonpressed)) //checking if 10000 ms has elapsed
  {
    if (!digitalRead(BUTTON_PIN)) buttonpressed=true; // assuming active LOW
  }
  while (buttonpressed) {
     delay(100); // for debounce
     if (digitalRead(BUTTON_PIN)) buttonpressed=false; // wait for the release
  }
}

please point out if i made any mistake

If that last post was aimed at me, no I won't help with that timeDelay code since I think it's nonsense in spite of Deva_Rishi's patch. The underlying principle is flawed.

And short of giving you the full working code, I can't see how to help you with the code I gave untill you show what you tried to get the button working.

sreekanthmp:
its not working!
please point out if i made any mistake

ah, you forgot to addpinMode(BUTTON_PIN, INPUT__PULLUP);
tbh i didn't tell you to, but since you hadn't told me how you were going to wire-up the button, i wasn't going to completely tell you how to do that, OK so connected to BUTTON_PIN and grounding out when pressed. the code should work. btw

its not working!

is insufficient information. ok, maybe it is close enough but only in this case.