On/Off with momentary switch

Let me start out by saying I am not a programmer and even after several class still fail to write my own code from scratch. What I have been able to do is rework someone else’s code to work and have been able to create a number of successful projects over the last year or so. With that said I’ve encountered a problem that I have been unable to find someone’s code I can work off of and get this to work.

The project is fairly simple -
Using a momentary button on A1, the 1st press will turn on an LED on pin 9 and create a 1.5 second timed pulse to an LED on pin 10.

Pressing the button a second time need’s to turn off the LED on pin 9 and create another 1.5 second pulse on pin 10.

These are the only 2 functions of the entire sketch and they can run in a loop using logic to determine the state or it can work in a two step program where it won’t advance to the next stage until the button is triggered again then start the loop over.

I’ve already come to the conclusion the circuit needs to be debounce’d to prevent accidental trigging from the momentary button. As a matter of fact I can use the debounce coding line for line to accomplish turning the LED on and off. What I have not be able to accomplish is creating the timed output that responds to the momentary switch.

The code I’m attaching is part of another persons sketch thats been hacked up and almost does what I need it to but for the life of me I can not get a second output pulse to work with out it keeping the LED on. I’m at the point though I think going back to the debounce code example and trying to add a timed output might be simpler.

PLEASE HELP ME

const byte buttonPin = A1;
const byte relayPins[] = {9, 10, 11, 12};
const byte NUMBER_OF_RELAYS = sizeof(relayPins);
byte state = 0;
unsigned long startWait = 50;
unsigned long period;
unsigned long currentTime;
byte currentButtonState;
byte previousButtonState;





void setup()
{
  Serial.begin(115200);
  for (int p = 0; p < NUMBER_OF_RELAYS; p++)
  {
    pinMode(relayPins[p], OUTPUT);
  }
  allOff();
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop()
{
  switch (state)
  {
    case 0:  //wait for button press
      currentButtonState = digitalRead(buttonPin);
      if (currentButtonState != previousButtonState && currentButtonState == LOW)
      {
        digitalWrite(relayPins[0], LOW);
        startWait = millis();
        period = 1000;
        state = 1;
      }
      previousButtonState = currentButtonState;
      break;

       

    case 1: //leds 1, 2 & 3 on wait 1000
      currentTime = millis();
      if (currentTime - startWait >= period)
      {
        digitalWrite(relayPins[1], HIGH);
        previousButtonState = LOW;
        state = 2;
      }
      break;

    case 2: //leds 1 & 3 on no wait
      currentTime = millis();
      if (currentTime - startWait >= period)
      {
        digitalWrite(relayPins[3], LOW);
        startWait = currentTime;
        period = 1580;
        state = 3;
      }
      break;

    case 3:  //leds 1, 3 & 4 on wait 1500
      currentTime = millis();
      if (currentTime - startWait >= period)
      {
        digitalWrite(relayPins[3], HIGH);
        previousButtonState = LOW;
        state = 4;
      }
      break;

    case 4:  //leds 1 & 3 no wait
      currentTime = millis();
      if (currentTime - startWait >= period)
      {
        digitalWrite(relayPins[1], LOW);
        startWait = currentTime;
        previousButtonState = HIGH; //bbb
        state = 5;
      }
      break;


case 5:  //wait for button press
      currentButtonState = digitalRead(buttonPin);
      if (currentButtonState != previousButtonState && currentButtonState == HIGH)
      
      
      {
        allOff();
        state = 0;
if (currentTime - startWait >= period)
 startWait = currentTime;
        digitalWrite(relayPins[3], LOW);
       period = 1000;
       digitalWrite(relayPins[3], HIGH);
      }

      
      previousButtonState = currentButtonState;
      break;
  }
}

void allOff()
{
  for (int p = 0; p < NUMBER_OF_RELAYS; p++)
  {
    digitalWrite(relayPins[p], HIGH);
    
  }
}

Ok you already have a state machine. Do you understand how that works? Can you modify it so that it does what you want for just pin 9? You just need the first "relay" and the all-off state. Delete the others.

Then you need another state machine for the LED on pin 10. This one is much simpler. It just has 2 states: on and off. It also needs a timer. When it is on, look at the timer to see if it is time to go off. To turn it on, the primary state machine can change it back to the on state and reset the timer to the current value of millis().

I do not really grasp how the "state" machine thing would work. The code example I have posted has been whittled down from like 8 or 9 of the "cases" it started with. The reason it works to give me the 1st pulse is it's trying to turn on a set of pins in a preset order, as I cut down the original code it started to do what I need. I've tried to remove some of the other "cases" that aren't actually being used but it ended up messing with the timing and right now the time's close enough that it works.

I have spent a great deal of time trying various things in "case 5" before the "AllOff" line and have been able to get a second output pulse the way I need but then the LED would stay on even if I declared the AllOff line father down in the code.

As for a timer my 1.5 second pulse doesn't have to be precise or even exactly the same every time, perhaps thats why it seems to work for me because I don't think I'm using a timer in the code right now. As a matter of fact the pulse doesn't even need to be the same every time, any thing from like 1-2.5 seconds would probably still work for what I'm doing. I'm sure that the pulse I'm getting right now that works shouldn't be working as a pulse but the delay function seems to be doing it because changing the time's on that alters the way it works. Again..... I'm sure I'm grossly misusing a coding error.

I'm sure this can be done with a lot less coding that I have right now, I've done far more complex things with less coding using other's sketches but with this..... I'm just lost.

To give a better idea of what this is actually for.When the button is pressed it turns on a light that stays on once triggered and the pulse'd output triggers a relay that grounds an output in my car's computer for about ~1.5 seconds. The car's computer will stay in this alternative mode until it get's another ~1.5 second pulse then it goes back into it's normal mode of operation and turns the light off. I have done this before by creating a latching relay(out of several other relays and diodes) and using a time delay relay but it creates a mess of wires, isn't cost effective and is rather hard to hide in the dash.

I've been told there are two types of people.... those that do hardware and those that do software. I can wire and trouble shoot just about any thing you could imagine and even if it was built using a single color of wire, I can design and build my hardware with no diagram or schematic by doing it all in my head but when it comes to writing a program or under standing much more then a "If Then" statement I draw a blank.

This actually does most of what I need, adding a timed or some type of pulsed delay on any other output pin would get it done. When I push the button the light comes on and stays on, when I push it again the light goes out. If I could add a pulse every time the button was pressed regardless of the LED state it would work.

// set pin numbers:
const int buttonPin = 2;    // the number of the pushbutton pin
const int ledPin = 13;      // the number of the LED pin

int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);

  // set initial LED state
  digitalWrite(ledPin, ledState);
}

void loop() {
 
  int reading = digitalRead(buttonPin);
  
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
 
        if (reading != buttonState) {
      buttonState = reading;
     
      if (buttonState == HIGH) {
        ledState = !ledState;
      }
    }
  }
  digitalWrite(ledPin, ledState);
   lastButtonState = reading;
}

Ok, if you are having trouble with if-else then that's a big program to have to work with. But we can break it down and work with it.

So you do understand what if-else does, right? (you may notice in C code that there is no "then")

In an Arduino program it is used a little differently to how the normal programming textbooks teach it. The main difference is the loop() function. This always runs. It runs thousands of times per second. But the Arduino never gets bored asking "Are we there yet?" thousands of times per second.

So you don't really detect that a button has been pushed. You just look at the button 'now'. Sometimes it is being held down, sometimes it isn't. But you get either of these pieces of information repeated thousands of times. So you cannot simply do an action when you detect that the button is being held. You have to remember what it was last time you looked. If it was UP last time and now it is DOWN then you should start the action.

That is why your code has previousButtonState all over it.

Our posts crossed. The new code looks much easier to work with. No switch-case, for example.

So add a new boolean isOn to remember if the second pin is outputting HIGH. Also add another unsigned long startTime .

Each time the main output changes, set that isOn variable to true, turn on the pin and set startTime=millis();

Then add a new if(isOn && millis()-startTime>interval) which will turn the LED off and set isOn=false;

This code is tested and working 100%. I know this isn't the way you were suggesting to go about this but my... call it programmers block that draws a blank trying to figure out what to write and where to insert the code that was suggested. I have commented all the lines for what it does although I'm not sure it's doing it the way it should be. Is this code structured correctly?

I have read a number of posts in the past about the Delay command not being ideal because it stops the loop from running. In this case it's working as my timed delay. Will there be any averse affect using it this way long term or any type of hiccup I might encounter? My concern here is with it being reliable since this is going into my vehicle. Other then the extra lines of commented out code is there any thing else that should be cleaned up or removed?

My last question would be do I NEED to use a pull-down resistor on pin A2. I have it bread boarded and have tried it with and without the resistor and it seems to work fine both way simply putting Pin A2 to the 5V ref. On the same topic the original code I drew this from used a digital pin rather then an Analog pin, in this case is there an advantage to using digital input pin from a reliability or longevity standpoint?

As a side note here, I wanted the timed pulse to occur prior to turning the LED on to simulate a more realistic turn on. I also kept the LED on until after the 2nd output pulse is given to give a more fluent and modern type shutdown.

// set pin numbers:
const int buttonPin = A2;    // the number of the pushbutton pin
const int LedPin = 13;      // the number of the LED pin
const int RelayPin = 12;    //pulsed output pin to relay

int ledState = LOW;         // the current state of the output pin to OFF - If HIGH turns on LED when power on
int buttonState;             // the current reading from the input pin
int lastButtonState = HIGH;   // the previous reading from the input pin - This was low, changed when ledState was changed to HIGH

unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 100;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT);//Input Trigger
  pinMode(LedPin, OUTPUT);// LED output
  pinMode(RelayPin, OUTPUT);// Pulsed Output

  // set initial LED state
  digitalWrite(LedPin, ledState);
}

void loop() {
   int reading = digitalRead(buttonPin);
  
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
         if (reading != buttonState) {
      buttonState = reading;
       if (buttonState == HIGH) {
        ledState = !ledState;
      }
    }
  }
  //digitalWrite(LedPin, ledState); Removed to hold off LED On until after intial pulse
   
  if (buttonState == HIGH) {
   
    digitalWrite(RelayPin, HIGH);//Turn on RelayPin
        delay(1000); //Timed Delay before turning RelayPin off - Time is NOT actual time it's longer
    digitalWrite(LedPin, HIGH);//Delays LED turn on until after Relay pulse 
  } 
  else {
    digitalWrite(LedPin, ledState);// Turns LED off on next press
    digitalWrite(RelayPin, LOW);//Turns off Relay Pin after timed delay
      }


   // These were tired and removed in favor of the above lines
   // digitalWrite(RelayPin, ledState);   // turn the LED on (HIGH is the voltage level)
    //delay(1000);                       // wait for a second
   //digitalWrite(RelayPin, LOW);    // turn the LED off by making the voltage LOW

lastButtonState = reading;
   
}

Yes, you need a pull-down or pull-up resistor. If you just connect 5V then pressing the button will draw the entire 5V rail down to zero and turn off the Arduino. You know you can use pinMode(buttonPin, INPUT_PULLUP) and then you don't need an external resistor?

If you're asking that question then perhaps you don't know how buttons work? They just touch two pieces of wire together. When they're not touching, the Arduino input is called "floating" which means that it can be any voltage at all. It might drift off to zero or it might pick up some electrical interference and drift towards 5V. A pullup resistor will ensure that it is only ever 5V when the button isn't pressed.

We call them "analog pins" but they are really the same as any other pin, just with an additional function. Like we don't call pin 13 the SCK pin even though it has the additional function of being the hardware SCK pin and you can even use that name to refer to it in Arduino code.

Delay takes all the 16 million instructions that the Arduino can execute in just one second and puts them all in the trash. It can't do anything during a delay. It can't detect that a button was pushed or released. It can't detect that a motor has reached the end of its track and needs to stop. It can't accept new serial input data from a GPS. Yes, you can use a delay but it's usually not the right choice for anything more complex than a flashing light.

PeteS160:
I've been told there are two types of people.... those that do hardware and those that do software.

There are actually four types. Those that do software, those that do hardware, those that do both, and those that do neither. :slight_smile:

My last question was worded poorly. I should have clarified it better. Does using the internal pull up/down resistor have any draw backs VS using an external pull up/down resistor?

As for the "Delay" function I know it stops the loop from running but in this type of program do you think it would cause any type of issues? I did find an example of a timed On/Off using

//Global Variables
const byte BUTTON=2; // our button pin
const byte LED=13; // LED (built-in on Uno)
 
unsigned long buttonPushedMillis; // when button was released
unsigned long ledTurnedOnAt; // when led was turned on
unsigned long turnOnDelay = 2500; // wait to turn on LED
unsigned long turnOffDelay = 5000; // turn off LED after this time
bool ledReady = false; // flag for when button is let go
bool ledState = false; // for LED is on or not.
 
void setup() {
 pinMode(BUTTON, INPUT_PULLUP);
 pinMode(LED, OUTPUT);
 digitalWrite(LED, LOW);
}
 
void loop() {
 // get the time at the start of this loop()
 unsigned long currentMillis = millis(); 
 
 // check the button
 if (digitalRead(BUTTON) == LOW) {
  // update the time when button was pushed
  buttonPushedMillis = currentMillis;
  ledReady = true;
 }
  
 // make sure this code isn't checked until after button has been let go
 if (ledReady) {
   //this is typical millis code here:
   if ((unsigned long)(currentMillis - buttonPushedMillis) >= turnOnDelay) {
     // okay, enough time has passed since the button was let go.
     digitalWrite(LED, HIGH);
     // setup our next "state"
     ledState = true;
     // save when the LED turned on
     ledTurnedOnAt = currentMillis;
     // wait for next button press
     ledReady = false;
   }
 }
  
 // see if we are watching for the time to turn off LED
 if (ledState) {
   // okay, led on, check for now long
   if ((unsigned long)(currentMillis - ledTurnedOnAt) >= turnOffDelay) {
     ledState = false;
     digitalWrite(LED, LOW);
   }
 }
}

I have tried to adapt this into my program but I haven't had any luck. The source it's from isn't debounced and the author said it didn't need to be, I'm not sure how to go about modifying it since it's not debounced and it's written in a way I can't find examples I under stand or how I would try and add an LED that is toggled on/off.

As for my current code that's working using the delay function the only issues I have found with it that I'm not happy with is if you press and hold the momentary button it will start the pulsed output but hold both Output pin's active with out proceeding in the loop until the button is released. I noticed this when i was trying to adapt the code I posted above since it doesn't start the loop until the button is released. I'm not really sure if it would be easier to adapt the above code into my current code or to try and rework the above code to also include a toggled On/Off led since it does away with the delay function and addresses the holding of the button.

Your help thus far has been invaluable despite not implementing the specific changes you suggested. I have made more progress on this since I started this thread then I have in the last couple of months tinkering with this from time to time.

aarg:
There are actually four types. Those that do software, those that do hardware, those that do both, and those that do neither. :slight_smile:

Then you should also include those that have brilliant idea's but lack the skill to create it them self. Trying to find a programmer to "code something" isn't like finding someone to fix a sink on the weekend, replace the brakes on your car or even get a couple of guys together and re-roof a house over the weekend. I'm sure there are a lot more people like myself that would be glad to pay someone to write a program or fix the coding in something they've already created. I have have well over 20 hours invested into this program, I'd imagine someone that programs C for a living could have done it in what....maybe 20-30 minutes?

Always use to format your code to make it easier to read.

The controller has pull-up resistors, not pull-down.

There are times when you might need external pull-up/pull-down resistors that are smaller in value to increase signal drive add/or help reduce noise from interfering with the input signals. This is usually for longer wire runs.

Generally it is not recommended to use delay() in a sketch.

//Global Variables
const byte BUTTON = 2;                   // our button pin 2
const byte LED    = 13;                  // LED (built-in on Uno)

const unsigned long turnOnDelay  = 2500; // wait to turn on LED
const unsigned long turnOffDelay = 5000; // turn off LED after this time

unsigned long buttonPushedMillis;        // when button was released
unsigned long ledTurnedOnAt;             // when led was turned on

bool ledReady = false;                   // flag for when button is let go
bool ledState = false;                   // for LED is on or not.

void setup()
{
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);

}//END of        s e t u p ( )

void loop()
{
  // get the time at the start of this loop()
  unsigned long currentMillis = millis();

  // check the button
  if (digitalRead(BUTTON) == LOW)
  {
    // update the time when button was pushed
    buttonPushedMillis = currentMillis;
    ledReady = true;
  }

  // make sure this code isn't checked until after button has been let go
  if (ledReady == true)
  {
    //this is typical millis code here:
    if (currentMillis - buttonPushedMillis >= turnOnDelay)
    {
      // okay, enough time has passed since the button was let go.
      digitalWrite(LED, HIGH);
      // setup our next "state"
      ledState = true;
      // save when the LED turned on
      ledTurnedOnAt = currentMillis;
      // wait for next button press
      ledReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledState == true)
  {
    // okay, led on, check for now long
    if (currentMillis - ledTurnedOnAt >= turnOffDelay)
    {
      ledState = false;
      digitalWrite(LED, LOW);
    }
  }
}//END of           l o o p ( )

larryd:
Always use to format your code to make it easier to read.

The controller has pull-up resistors, not pull-down.

There are times when you might need external pull-up/pull-down resistors that are smaller in value to increase signal drive add/or help reduce noise from interfering with the input signals. This is usually for longer wire runs.

Generally it is not recommended to use delay() in a sketch.

//Global Variables

const byte BUTTON = 2;                   // our button pin 2
const byte LED    = 13;                  // LED (built-in on Uno)

const unsigned long turnOnDelay  = 2500; // wait to turn on LED
const unsigned long turnOffDelay = 5000; // turn off LED after this time

unsigned long buttonPushedMillis;        // when button was released
unsigned long ledTurnedOnAt;             // when led was turned on

bool ledReady = false;                   // flag for when button is let go
bool ledState = false;                   // for LED is on or not.

void setup()
{
 pinMode(BUTTON, INPUT_PULLUP);
 pinMode(LED, OUTPUT);
 digitalWrite(LED, LOW);

}//END of        s e t u p ( )

void loop()
{
 // get the time at the start of this loop()
 unsigned long currentMillis = millis();

// check the button
 if (digitalRead(BUTTON) == LOW)
 {
   // update the time when button was pushed
   buttonPushedMillis = currentMillis;
   ledReady = true;
 }

// make sure this code isn’t checked until after button has been let go
 if (ledReady == true)
 {
   //this is typical millis code here:
   if (currentMillis - buttonPushedMillis >= turnOnDelay)
   {
     // okay, enough time has passed since the button was let go.
     digitalWrite(LED, HIGH);
     // setup our next “state”
     ledState = true;
     // save when the LED turned on
     ledTurnedOnAt = currentMillis;
     // wait for next button press
     ledReady = false;
   }
 }

// see if we are watching for the time to turn off LED
 if (ledState == true)
 {
   // okay, led on, check for now long
   if (currentMillis - ledTurnedOnAt >= turnOffDelay)
   {
     ledState = false;
     digitalWrite(LED, LOW);
   }
 }
}//END of           l o o p ( )

Looks a bit cleaner, still seems to work the same but I’ll take your word it’s correct.

Now what do I need to add to the program to have another LED say Pin12 toggle On and Off with each press but keep the same characteristic that it won’t change states until the BUTTON is released?

I know I need to declare “const byte ledPin=12;” and I will likely need a place to store the state in " int LedState = LOW; "

In Void setup I’ll need to declare the output “pinMode(ledPin, OUTPUT);” and I need to set the state" digitalWrite(ledPin, ledState);"

Where in the Void Loop would I add my If BUTTON statement with the digitalWrite HIGH and LOW commands?

All the LED on pin 12 needs to do is come on AFTER Pin 13 has finished it’s timed On - Off cycle. Once Pin 13 has gone off Pin 12 should now be On and stay On until the next time the button is pressed & released. On the next button press& release Pin 13 comes back on for it’s timed delay and goes back off. Pin 12 should also turn OFF at the same time Pin 13 turns off. I have gotten it to work this way using the delay command and debounce but it’s not on button release.

I feel like I’m close to getting this working correctly but I’ve been at this point several times before and ended up scraping what I have and trying something else. I just want this to work :frowning:

All the LED on pin 12 needs to do is come on AFTER Pin 13 has finished it's timed On - Off cycle. Once Pin 13 has gone off Pin 12 should now be On and stay On until the next time the button is pressed & released. On the next button press& release Pin 13 comes back on for it's timed delay and goes back off. Pin 12 should also turn OFF at the same time Pin 13 turns off.

Explain how the additions work.

//Global Variables
const byte BUTTON    = 2;                // our button pin 2
const byte LED       = 13;               // LED (built-in on Uno)
const byte toggleLED = 12;               // Toggle LED

const unsigned long turnOnDelay  = 2500; // wait to turn on LED
const unsigned long turnOffDelay = 5000; // turn off LED after this time

unsigned long buttonPushedMillis;        // when button was released
unsigned long ledTurnedOnAt;             // when led was turned on

bool ledReady = false;                   // flag for when button is let go
bool ledState = false;                   // for LED is on or not.

void setup()
{
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
  pinMode(toggleLED, OUTPUT);
  digitalWrite(toggleLED, LOW);

}//END of        s e t u p ( )

void loop()
{
  // get the time at the start of this loop()
  unsigned long currentMillis = millis();

  // check the button
  if (digitalRead(BUTTON) == LOW)
  {
    // update the time when button was pushed
    buttonPushedMillis = currentMillis;
    ledReady = true;
  }

  // make sure this code isn't checked until after button has been let go
  if (ledReady == true)
  {
    //this is typical millis code here:
    if (currentMillis - buttonPushedMillis >= turnOnDelay)
    {
      // okay, enough time has passed since the button was let go.
      digitalWrite(LED, HIGH);
      // setup our next "state"
      ledState = true;
      // save when the LED turned on
      ledTurnedOnAt = currentMillis;
      // wait for next button press
      ledReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledState == true)
  {
    // okay, led on, check for now long
    if (currentMillis - ledTurnedOnAt >= turnOffDelay)
    {
      ledState = false;
      digitalWrite(LED, LOW);

      //toggle pin 12
      digitalWrite(toggleLED, !digitalRead(toggleLED));
    }
  }
}//END of           l o o p ( )

I feel like I'm close to getting this working correctly but I've been at this point several times before and ended up scraping what I have and trying something else.

That work style is part of the problem. MorganS told you exactly what to do in reply #5 with the code you had at that time. Rather than trying to execute what he suggested (and coming back with specific questions about that path if you had problems)you changed the code and the requirements for when things should turn off.

Your are not making it easy for people to assist you. If you could get the code in #3 to work with the suggestions of #5 would that be what you want?

LarryD, THANKYOU SO MUCH. I have lost far too many hours of sleep over this. Your code is easy to read and it wasn't overly complex. I'm actually amazed how simple it was to make the 2nd LED stay on, I was figuring it'd take at least a couple lines of code in the VoidLoop and you made it work with just one line.

This code performs the operation exactly how I need it to work. I spent some time trying to find any exploits or issues I could potentially encounter once it's in my truck and have found one. If I activate pin 2 and start the sequence but activate pin 2 again before the sequence has competed it hickup's a bit. Just to see if some type of delay would help I added "delay(2000);" after the digitalWrite( toggleLed) line and it improves the issues but doesn't totally prevent glitching it mid sequence if the button is toggled repeatedly. Should this be corrected with debouce? The way I under stand it debounce prevents reading the button for X amount of time. In the example it's to prevent it from flickering but in my case I need to stop the button from being read while the sequence runs though and I think I can see how what I'm trying to fix now in essence is the same thing as button flicker.

Again THANKYOU SO MUCH !!!!!

larryd:
Explain how the additions work.

//Global Variables

const byte BUTTON    = 2;                // our button pin 2
const byte LED      = 13;              // LED (built-in on Uno)
const byte toggleLED = 12;              // Toggle LED

const unsigned long turnOnDelay  = 2500; // wait to turn on LED
const unsigned long turnOffDelay = 5000; // turn off LED after this time

unsigned long buttonPushedMillis;        // when button was released
unsigned long ledTurnedOnAt;            // when led was turned on

bool ledReady = false;                  // flag for when button is let go
bool ledState = false;                  // for LED is on or not.

void setup()
{
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
  pinMode(toggleLED, OUTPUT);
  digitalWrite(toggleLED, LOW);

}//END of        s e t u p ( )

void loop()
{
  // get the time at the start of this loop()
  unsigned long currentMillis = millis();

// check the button
  if (digitalRead(BUTTON) == LOW)
  {
    // update the time when button was pushed
    buttonPushedMillis = currentMillis;
    ledReady = true;
  }

// make sure this code isn't checked until after button has been let go
  if (ledReady == true)
  {
    //this is typical millis code here:
    if (currentMillis - buttonPushedMillis >= turnOnDelay)
    {
      // okay, enough time has passed since the button was let go.
      digitalWrite(LED, HIGH);
      // setup our next "state"
      ledState = true;
      // save when the LED turned on
      ledTurnedOnAt = currentMillis;
      // wait for next button press
      ledReady = false;
    }
  }

// see if we are watching for the time to turn off LED
  if (ledState == true)
  {
    // okay, led on, check for now long
    if (currentMillis - ledTurnedOnAt >= turnOffDelay)
    {
      ledState = false;
      digitalWrite(LED, LOW);

//toggle pin 12
      digitalWrite(toggleLED, !digitalRead(toggleLED));
    }
  }
}//END of          l o o p ( )

And this is why, if I ruled the world, students submitting programming assignments would be stood in front of a whiteboard and required to explain how their program works before getting credit for it.

This is what I have done to try and correct the button from being triggered while the led timed cycle is running and to make the button less sensitive to short repeated presses. I’m not entirely sure what the LastDebounceTime and DebounceDelay do or how they interact with it only that they do seem to change it’s behavior. I have tried various numbers in each and while I can tell subtle differences in how it responds to the button press/release timing I’m not sure what they SHOULD be doing or if they are working correctly. I’m thinking my code is likely formatted or structured improperly… that or I don’t really under stand how debounce works. I have noted the lines I added and the one line i altered in the code LarryD posted.

//Global Variables
const byte BUTTON = A2; // our button pin 2
const byte LED = 13; // LED (built-in on Uno)
const byte toggleLED = 12; // Toggle LED

const unsigned long turnOnDelay = 100; // wait to turn on LED
const unsigned long turnOffDelay = 1000; // turn off LED after this time

// ADDED BELOW CODE

int buttonState; //
int lastButtonState = LOW; // Something needs to be looked at, when power on Arduino cycle starts and LED’s come on
unsigned long lastDebounceTime = 5000; // Not really sure what this is doing but seemed best around this
unsigned long debounceDelay = 500; // at 250 seems best but still has some glitching if switched toggled quickly
//ADD ABOVE LINES

unsigned long buttonPushedMillis; // when button was released
unsigned long ledTurnedOnAt; // when led was turned on

bool ledReady = false; // flag for when button is let go
bool ledState = false; // for LED is on or not.

void setup()
{
pinMode(BUTTON, INPUT_PULLUP);
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW);
pinMode(toggleLED, OUTPUT);
digitalWrite(toggleLED, LOW);

}//END of s e t u p ( )

void loop()
{
// get the time at the start of this loop()
unsigned long currentMillis = millis();

//ADD BELOW LINES FOR DEBOUNCE
// read the state of the switch into a local variable:
int reading = digitalRead(BUTTON);

// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you’ve waited
// long enough since the last press to ignore any noise:

// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}

if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it’s been there for longer
// than the debounce delay, so take it as the actual current state:

// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
}
}

//ADDED ABOVE LINES FOR DEBOUNCE

// check the button
if (buttonState == LOW)//Changed from digitalRead when added debounce coding to make work
{
// update the time when button was pushed
buttonPushedMillis = currentMillis;
ledReady = true;
}

// make sure this code isn’t checked until after button has been let go
if (ledReady == true)
{
//this is typical millis code here:
if (currentMillis - buttonPushedMillis >= turnOnDelay)
{
// okay, enough time has passed since the button was let go.
digitalWrite(LED, HIGH);
// setup our next “state”
ledState = true;
// save when the LED turned on
ledTurnedOnAt = currentMillis;
// wait for next button press
ledReady = false;
}
}

// see if we are watching for the time to turn off LED
if (ledState == true)
{
// okay, led on, check for now long
if (currentMillis - ledTurnedOnAt >= turnOffDelay)
{
ledState = false;
digitalWrite(LED, LOW);

//toggle pin 12
digitalWrite(toggleLED, !digitalRead(toggleLED));
//delay(2000); Used for testing
}
}
lastButtonState = reading; // Added for debounce
}//END of l o o p ( )

If you want to disable something, create a flag then use the flag to enable or disable code execution.
For the version posted in post #13, switchReadingFlag is now used to enable and disable reading of the switch.

//Global Variables
const byte BUTTON    = 2;                // our button pin 2
const byte LED       = 13;               // LED (built-in on Uno)
const byte toggleLED = 12;               // Toggle LED

const unsigned long turnOnDelay  = 2500; // wait to turn on LED
const unsigned long turnOffDelay = 5000; // turn off LED after this time

unsigned long buttonPushedMillis;        // when button was released
unsigned long ledTurnedOnAt;             // when led was turned on

bool ledReady = false;                   // flag for when button is let go
bool ledState = false;                   // for LED is on or not.
bool switchReadingFlag = true;           // when false, switch reading is disabled

void setup()
{
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
  pinMode(toggleLED, OUTPUT);
  digitalWrite(toggleLED, LOW);

}//END of        s e t u p ( )

void loop()
{
  // get the time at the start of this loop()
  unsigned long currentMillis = millis();

  // check the button
  if (switchReadingFlag == true && digitalRead(BUTTON) == LOW)
  {
    // update the time when button was pushed
    buttonPushedMillis = currentMillis;
    ledReady = true;

    //disable the reading of the switch as we are now timing
    switchReadingFlag = false;
  }

  // make sure this code isn't checked until after button has been let go
  if (ledReady == true)
  {
    //this is typical millis code here:
    if (currentMillis - buttonPushedMillis >= turnOnDelay)
    {
      // okay, enough time has passed since the button was let go.
      digitalWrite(LED, HIGH);
      // setup our next "state"
      ledState = true;
      // save when the LED turned on
      ledTurnedOnAt = currentMillis;
      // wait for next button press
      ledReady = false;
    }
  }

  // see if we are watching for the time to turn off LED
  if (ledState == true)
  {
    // okay, led on, check for now long
    if (currentMillis - ledTurnedOnAt >= turnOffDelay)
    {
      ledState = false;
      digitalWrite(LED, LOW);

      //toggle pin 12
      digitalWrite(toggleLED, !digitalRead(toggleLED));
      
      //timing is now finished, enable switch reading
      switchReadingFlag = true;
    }
  }
}//END of           l o o p ( )

Do you understand how switchReadingFlag stops all switch reading while you are in the timing mode?

.

Code is not performing as it would be expected. It activates the led sequence on button press not release. If the button is held the led sequence runs in a loop. The reason I wanted activation of the led's on button release was to prevent it from looping if the button was held down.

Just looking over the code quick I don't see how the SwitchReadingFlag is tied into the function of the code not executing until button release. But i know nothing of how a Flag works and I only had a few minuites to read about it while I was eating my lunch. I will try and find more information on it tonight so that I can under stand what it should be doing and how it does it. Thanks again for taking the time to help me on this.

larryd:
If you want to disable something, create a flag then use the flag to enable or disable code execution.
For the version posted in post #13, switchReadingFlag is now used to enable and disable reading of the switch.

//Global Variables

const byte BUTTON    = 2;                // our button pin 2
const byte LED      = 13;              // LED (built-in on Uno)
const byte toggleLED = 12;              // Toggle LED

const unsigned long turnOnDelay  = 2500; // wait to turn on LED
const unsigned long turnOffDelay = 5000; // turn off LED after this time

unsigned long buttonPushedMillis;        // when button was released
unsigned long ledTurnedOnAt;            // when led was turned on

bool ledReady = false;                  // flag for when button is let go
bool ledState = false;                  // for LED is on or not.
bool switchReadingFlag = true;          // when false, switch reading is disabled

void setup()
{
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
  pinMode(toggleLED, OUTPUT);
  digitalWrite(toggleLED, LOW);

}//END of        s e t u p ( )

void loop()
{
  // get the time at the start of this loop()
  unsigned long currentMillis = millis();

// check the button
  if (switchReadingFlag == true && digitalRead(BUTTON) == LOW)
  {
    // update the time when button was pushed
    buttonPushedMillis = currentMillis;
    ledReady = true;

//disable the reading of the switch as we are now timing
    switchReadingFlag = false;
  }

// make sure this code isn't checked until after button has been let go
  if (ledReady == true)
  {
    //this is typical millis code here:
    if (currentMillis - buttonPushedMillis >= turnOnDelay)
    {
      // okay, enough time has passed since the button was let go.
      digitalWrite(LED, HIGH);
      // setup our next "state"
      ledState = true;
      // save when the LED turned on
      ledTurnedOnAt = currentMillis;
      // wait for next button press
      ledReady = false;
    }
  }

// see if we are watching for the time to turn off LED
  if (ledState == true)
  {
    // okay, led on, check for now long
    if (currentMillis - ledTurnedOnAt >= turnOffDelay)
    {
      ledState = false;
      digitalWrite(LED, LOW);

//toggle pin 12
      digitalWrite(toggleLED, !digitalRead(toggleLED));
     
      //timing is now finished, enable switch reading
      switchReadingFlag = true;
    }
  }
}//END of          l o o p ( )






Do you understand how switchReadingFlag stops all switch reading while you are in the timing mode?


.