Combine "Getting Started with Arduino" Programs

For an LED circuit, I would like code that will allow an LED to stay on at a continuous/persistent brightness, but when a pushbutton is pressed, to switch from persistent brightness mode, to "fade in and out like an apple computer" mode. For my first attempt at this, I took the on/off code from "Getting Started with Arduino" (pg 49) quoted below as "CODE A", and in lieu of "digitalWrite(LED, LOW);" following the "} else {" command, I added the "fade in like an apple computer code" ("Getting Started with Arduino" pg 57). The original "fade in and out like an apple computer" code is written below as "CODE B", and the resultant code after having combined "CODE A" with "CODE B" is written below as "CODE C".

My issue: "CODE C" running via Arduino Uno starts by fading the LED in and out like an apple computer. When I press the pushbutton, nothing happens when the LED is in the midst of its fade and does not switch to persistent brightness mode. However, at the VERY moment the fade of the LED reaches its lowest point, and if at that exact moment I press the pushbutton, then BAM, the LED switches to persistence mode. The problem: it is VERY difficult to hit the pushbutton, right at the very moment the LED is at the dead-center bottom of its fade-out. I've tried changing some "==" to "<" or ">", but without success. Any help would be greatly appreciated, and I apologize if there's a forehead-slap solution as this is my first attempt writing an unique code. Thank you in advance.

CODE A

// Example 03C: Turn on LED when the button is pressed and keep it on after is is released.
// including simple debouncing
//Now with another new and improved formula!!!

const int LED = 13;      // the pin for the LED
const int BUTTON = 7;   // the input pin where the pushbutton is connected

int val = 0;          // val will be used to store the state of the input pin

int old_val = 0;     // this variable stores the previous value of "val"

int state = 0;        // 0 = LED off while 1 = LED on

void setup()  {
  pinMode (LED, OUTPUT);     // tell Arduino LED is an output
  pinMode (BUTTON, INPUT);   //and BUTTON is an input
}


void loop()  {
  val = digitalRead(BUTTON);  //read input value and store it
  
  //check if there was a transition
  if ((val == HIGH) && (old_val == LOW)) {
    state = 1 - state;
    delay(10);
  }
  
  old_val = val;   // val is now old, let's store it
  
  if (state == 1) {
    digitalWrite(LED, HIGH);   // turn LED ON
  } else {
    digitalWrite(LED, LOW);
  }
}

CODE B

//Example 04: Fade an LED in and out like on a sleeping Apple computer

const int LED = 9;  // the pin for the LED
int i = 0;         // we'll use this to count up and down

void setup() {
  pinMode(LED, OUTPUT);  //tell Ardiuno LED is an output
}

void loop() {
  
  for (i=0; i < 255; i++) {  // loop from 0 to 254 (fade in)
  analogWrite(LED, i);        //set the LED brightness
  delay(10);     //Wait 10ms because analogWrite is instantaneous and we would not see a change
  }
  
  for (i = 255; i > 0; i--) { // loop from 255 to 1 (fade out)
  
  analogWrite(LED, i);  // set the LED brightness
  delay(10);             // wait 10 ms
  }
  
}

CODE C: Resultant code from combining A and B

// When button is pressed toggle between continuous brightness
// and fading in and out like an apple computer.  

const int LED = 9;      // the pin for the LED
const int BUTTON = 7;   // the input pin where the pushbutton is connected

int i = 0;              // we'll use this to count up and down

int val = 0;          // val will be used to store the state of the input pin

int old_val = 0;     // this variable stores the previous value of "val"

int state = 0;        // 0 = LED off while 1 = LED on

void setup()  {
  pinMode (LED, OUTPUT);     // tell Arduino LED is an output
  pinMode (BUTTON, INPUT);   //and BUTTON is an input
}


void loop()  {
  val = digitalRead(BUTTON);  //read input value and store it
  
  //check if there was a transition
  if ((val == HIGH) && (old_val == LOW)) {
    state = 1 - state;
    delay(10);
  }
  
  old_val = val;   // val is now old, let's store it
  
  if (state == 1) {
    digitalWrite(LED, HIGH);   // turn LED ON
  } else {
     for (i=0; i < 255; i++) {  // loop from 0 to 254 (fade in)
  analogWrite(LED, i);        //set the LED brightness
  delay(10);     //Wait 10ms because analogWrite is instantaneous and we would not see a change
  }
  
  for (i = 255; i > 0; i--) { // loop from 255 to 1 (fade out)
  
  analogWrite(LED, i);  // set the LED brightness
  delay(10);             // wait 10 ms
  }
  }
}

You're not checking the button while you're running the fade, so as you observe, it's hard to catch the exact moment to press the button. I suspect you can hold the button down during the fade and it will switch at the end, but you still have to get your finger off quickly so it doesn't read it again and return to fade mode.

You can check for the button being pressed during your fade loops and break out of them. Probably better though is to remove the for loops. If you're in fade mode, just change i by 1 each time round loop. You'll need some logic to switch between increment and decrement when you get to 0 or 255. Then, you'll be checking the button frequently. Button response may still be a little bit flaky though because of your delays. At that point you'll need to adapt your D variant to an E that's based on the method shown in blink without delay.

Thank you very much for the response. I was with you until your last sentence, "At that point you'll need to adapt your D variant to an E that's based on the method shown in blink without delay." Not a clue what a D variant or an E in fact is, and I am unaware of a code that enables a blink without a delay: that seems counterintuitive to me.

Let me ask you this, please. On many kits coming from, for example, Evil Mad Science, there is usually a button which enables the circuit to switch from one mode, to another. So if I have two perfect codes, one which lights an LED yet enables me to alter brightness by holding down the button, and another code which fades an LED in and out, is there not a simple command I can utilize to link the two separate codes in a way that would enable me to push the button (or push and hold for a certain length of time) and toggle between codes/LED functions???

Take the Octolively Kit: Octolively Kit There are 8 distinct separate codes manifested as modes which can be changed by holding down a pushbutton. Perhaps I can use a similar technique as they to bring together the two codes I'd like represented?

Thank you very much again for the response. Appreciated.

I was with you until your last sentence, "At that point you'll need to adapt your D variant to an E that's based on the method shown in blink without delay." Not a clue what a D variant or an E in fact is, and I am unaware of a code that enables a blink without a delay: that seems counterintuitive to me.

You've labeled your initial three pieces of code A, B & C. I was suggesting a first change to the C version and called it D, another change to be E. Blink without delay is an example sketch that comes with the IDE. It uses the millis function to manage the blinking of an LED without having to use the delay function. Delay is a problem if you want to do other things in your sketch because it causes the Arduino to sit in a tight loop doing nothing until time is up. Similarly, your fade loops concentrate on fading the LED but ignore the switch. The arduino is single threaded, so here is no magic bullet to take two pieces of code and co-mingle their functions - you have to adapt them to work together.

Awesome. I'm going to check out that code and attempt the consecutive variants as you suggest. Thanks!

Something that may or may not be a solution has occurred to me. If I purchased a three position switch, could I then set up the switch to be in the off position, the on position, and the fade position, 1,2,3? Not sure if switches work this way, but if so, then I wouldn't have to write any code. I could have the switch just open and close the circuit for off/on, and then the third position for the switch would enable the microcontroller programmed with the fade.

Possible? Thank you in advance!!