How to execute continuous code based off of momentary switches?

I'm trying to write a code where the Arduino constantly monitors the analog inputs of three different momentary switches and based on which one is pressed, execute an action indefinitely until a different momentary button is pressed. So far I can only get the code to execute if I hold one of the momentary switches down, but once I release the switch, the action stops.

How do I get the code to read when a momentary switch is pressed, and then execute a command indefinitely or until a different switch is pressed? Here is the code I'm working with now.

Entertainment_Center_LED_Code.ino (767 Bytes)

Well, I thought attaching the file would populate the code in the actual post, but here is the copied code:


int brightness = 0;
int fadeAmount = 15;

void setup() {
// put your setup code here, to run once:
}

void loop() {
// put your main code here, to run repeatedly:
int button1NewState = analogRead (A0);
int button2NewState = analogRead (A1);
int button1OldState = 0;
int button2OldState = 0;

if (button1NewState > button1OldState)
{
button1NewState = 1;

if (button1NewState == 1 && button1OldState == 0)
{
led1Fade();
button1OldState = button1NewState;
}
}
}

void led1Fade()
{
delay (10);
analogWrite (3, brightness);
brightness = brightness + fadeAmount;
if (brightness == 0 || brightness == 255)
{
fadeAmount = -fadeAmount;
}
delay (50);
}

Change A0 & A1 to be use them as digital pins (14 & 15 if you want). Momentary buttons are only going to return HIGH & LOW.

once I release the switch, the action stops.

That is how the program is currently written. You will need to change the fundamental program logic to do something else. Did you not write this program?

You will need to use a button debouncing technique to make sure that you have only one transition. There are Arduino libraries available for that purpose.

One approach would be to use something like the "Delays are boring" example here:

Essentially, you break the "action" into small steps and do one step each time through the loop. In your case that could be decreasing the LED brightness by a small amount if the condition for that action is met (the button is held down).

Keeping track of time to do each thing can become tedious though. You might find this helpful as well:

The code is available in github as well:
https://github.com/Megunolink/MLP/blob/master/ArduinoTimer.h
https://github.com/Megunolink/MLP/blob/master/ArduinoTimer.cpp

jremington:
That is how the program is currently written. You will need to change the fundamental program logic to do something else. Did you not write this program?

You will need to use a button debouncing technique to make sure that you have only one transition. There are Arduino libraries available for that purpose.

Yes, I did write it, and the debouncing is taking place in the "led1Fade()" function (At least that's what I was trying to do).

Additionally, I realize that's how the code is currently written. My question is how do I change the current code to execute the "led1Fade()" function indefinitely or until another button is pressed.

Ultimately what I'm tying to do is program different sequences of LED light displays based on which momentary button is pressed.

For example, if button one is pressed, I want the LED to do a repeating fade pattern until another button is pressed. When button two is pressed, I want the LED to blink rapidly until a different button is pressed.

Paul_Martinsen:
One approach would be to use something like the "Delays are boring" example here:
5 Tips for Arduino Programs | Articles | MegunoLink

Essentially, you break the "action" into small steps and do one step each time through the loop. In your case that could be decreasing the LED brightness by a small amount if the condition for that action is met (the button is held down).

Keeping track of time to do each thing can become tedious though. You might find this helpful as well:
Arduino Timer | Articles | MegunoLink

The code is available in github as well:
https://github.com/Megunolink/MLP/blob/master/ArduinoTimer.h
https://github.com/Megunolink/MLP/blob/master/ArduinoTimer.cpp

I apologize, I think I may not have been clear in what I was trying to accomplish. I'm trying to avoid having to hold down the button. I only want to momentarily press the button, and as a result of the momentary button press I want a certain action to occur indefinitely or until a different button is momentarily pressed.

CrossRoads:
Change A0 & A1 to be use them as digital pins (14 & 15 if you want). Momentary buttons are only going to return HIGH & LOW.

I tried your suggestion, and it's still not quite working. Now the LED just stays on.

Here's what I got:

int brightness = 0;
int fadeAmount = 15;

void setup() {

pinMode (6, INPUT);
pinMode (4, INPUT);

}

void loop() {

int button1 = digitalRead (4);
int button2 = digitalRead (6);

if (button1 == HIGH)
{
delay (10);
analogWrite (3, brightness);
brightness = brightness + fadeAmount;
if (brightness == 0 || brightness == 255)
{
fadeAmount = -fadeAmount;
}
delay (50);
}
}

How are pins 4 and 5 wired?
You're not using the built-in pull ups.

MERRITTJW1:
I apologize, I think I may not have been clear in what I was trying to accomplish. I'm trying to avoid having to hold down the button. I only want to momentarily press the button, and as a result of the momentary button press I want a certain action to occur indefinitely or until a different button is momentarily pressed.

No problem. Same principle applies. You just want to have another variable that detects when the button is hit and triggers your action.

So something like

bool DoAction1 = false;
loop()
{
if (digitalRead(4))
{
DoAction = true;
}

if (DoAction1)
{
// Do a little bit of the action
// if the action is finished, set DoAction1 = false;
}
}

You can duplicate the pattern for the additional switches. But those delays will add up and produce uneven fading I think. At that point the millis approach I suggested would be useful.

You might need debouncing on your button as has been suggested. But because activation is triggering something that runs for a few tens of milliseconds by the look of it, maybe not. I'd try without first.

If you're using boolean, where do you define what "DoAction1" is?

If you say: "boolean led1Fade = false;"

and then later say: "led1Fade = true;" then what happens? Where do I define what "led1Fade" is so that it calls upon that action to be true?

I'm pretty sure I have a severe misunderstanding of what the boolean commands are and how to use them. The "tutorial" and reference page on this site do not really help at all.

"boolean" is a variable type. The variable can be either true or false (1 or 0 basically).

if (boolean_variable) {
do_something;
}

just checks whether boolean_variable is true or false.

I'm not understanding how to implement boolean into my code, but here's the most recent revision and it still isn't working. I'm trying to tell the code to run the code after the "if" statement once the button has been pressed, but it still only runs the code while I have the button held down. As soon as I let go of the button, it stops where ever the code was at that moment in time. For example, when I hold down the button, the LED will fade fully on and then fade fully off, but when I release the button, it "pauses" the fade and the LED remains at the same brightness it was at when I released the button. How do I get the code to continuously execute regardless if the button is still pressed or not? I appreciate everyones advice so far, but I'm still pretty new to arduino and some of what you guys are suggesting is still unfamiliar to me.

Can someone please break it down in simple terms what I'm doing wrong and explain what it is I need to be doing and why I need to be doing it? (i.e. if I need to execute command "x," please define what "x" means so I can put it into context of what I'm trying to do). Like I said, so far there's been suggestions, but I still don't quite understand what those suggestions mean and why I'm supposed to use them.

It would be east to use a SPST switch to do this, but for the project I'm designing, I'd like to use a momentary switch.

int brightness = 0;
int fadeAmount = 15;

void setup() {

pinMode (6, INPUT);
pinMode (4, INPUT);

}

void loop() {

int button1Current = digitalRead (4);
int button2Current = digitalRead (6);
int button1Old = 0;
int button2Old = 0;

if (button1Current != button1Old)
{
delay (100);
analogWrite (3, brightness);
brightness = brightness + fadeAmount;
if (brightness == 0 || brightness == 255)
{
fadeAmount = -fadeAmount;
button1Current = 1;
}
delay (50);
}
}

MERRITTJW1:
I'm trying to write a code where the Arduino constantly monitors the analog inputs of three different momentary switches and based on which one is pressed, execute an action indefinitely until a different momentary button is pressed. So far I can only get the code to execute if I hold one of the momentary switches down, but once I release the switch, the action stops.

How do I get the code to read when a momentary switch is pressed, and then execute a command indefinitely or until a different switch is pressed? Here is the code I'm working with now.

here is a variable that I use to keep track of which function I am supposed to be doing;

void loop() {
if button A is pressed
make a note of the fact that I need to do me some A;

if button B is pressed
make a note of the fact that I need to do me some B;

if button C is pressed
make a note of the fact that I need to do me some C;

if I'm supposed to be doing some A
do some A;
else if I'm supposed to be doing some B
do some B;
else if I'm supposed to be doing some C
do some C;
else
; // WTF? Do nothing, I suppose.

}