programming 2 leds to flicker on, pulse continually, then fade off

I'm learning to code but have been hitting a lot of walls trying to do this due to being a complete novice. I've got 2 leds connected to a button switch and have them set to simply turn on and off with a press of the button. What I really want to do is have them flicker on, then run a continual more subtle flicker, and second button press have it fade to off instead of immediate off. Then repeat on next button press. Flicker on, fade off, etc. I haven't been able to insert the functions in a way that actually makes this happen. Am I going about this entirely the wrong way?

int button = 4;              // switch is connected to pin 4
int led1 = 5;                // Green LED pin 5
int led2 = 6;                 // Green LED pin 6

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 buttonPresses = 0;          // how many times the button has been pressed
int lightMode = 0;              // What mode is the light in?

// button switch here
int state = LOW;      // the current state of the output pin
int reading;           // the current reading from the input pin
int previous = HIGH;    // the previous reading from the input pin
long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers

// base flicker here
int pulseMin = 1; // Minimum number of pulses in each set
int pulseMax = 3; // Maximum number of pulses in each set
int brightMin = 106; // Baseline LED brightness. Cannot exceed 128.
int minDelay = 2500; // Minimum delay between pulse sets (ms)
int maxDelay = 7000; // Maximum delay between pulse sets (ms)

// fade out here
int fade1 = 2;

void setup() {                

  randomSeed (analogRead (3)); // Randomise
  pinMode(button, INPUT); // Sets button to be an input
  pinMode(led1, OUTPUT); // Sets LED Pin to be an output 
  pinMode(led2, OUTPUT);

}

void loop()
{

  // For on and off button
  reading = digitalRead(button);

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (reading == LOW && previous == HIGH && millis() - time > debounce) {
    if (state == LOW){
      state = HIGH;
      powerUp();
    }else{
      state = LOW;
      fadeOff();
    }  

    time = millis();    
  }

  if(state = HIGH){
    baseFlicker();
  }

  previous = reading;
}


// Function for power-on flicker
void powerUp() {

  analogWrite(led1, 50);
  analogWrite(led2, 50);
  delay(50);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  delay(20);
  analogWrite(led1, 80);
  analogWrite(led2, 80);
  delay(70);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  delay(40);
  analogWrite(led1, 120);
  analogWrite(led2, 120);
  delay(90);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  delay(60);
  analogWrite(led1, 140);
  analogWrite(led2, 140);
  delay(110);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  delay(00);

}  

// Function to make LED flicker continually while on
void baseFlicker() {

  // For loop sets the number of pulses and repeats these pulses

  for (int x = random(pulseMin, pulseMax); x > 0; x-- ) { 

    int bright = 224 - random(96); // Sets a random maximum brightness level for this pulse

    // For loop raises the brightness of the LED from minimum to maximum value

    for (int y = brightMin; y < bright ; y++) {

      analogWrite(led1, y);
      analogWrite(led2, y);
      delay(3);

    }

    // For loop lowers the brightness of the LED from maximum to minimum value

    for (int y = bright; y > brightMin; y--) {

      analogWrite(led1, y);
      analogWrite(led2, y);
      delay(3);

    }

    delay(10); // Adds a delay between pulses to make them more visible

  }

  analogWrite(led1, brightMin);
  analogWrite(led2, brightMin);
  delay(random(minDelay,maxDelay)); // Adds a delay between pulse sets

}

// Function to fade to off
void fadeOff () {

  static int lastBright1 = 0;                 // set the lastbright variable

  if (state < HIGH) {                         // check if LED is on 
    analogWrite(led1, LOW);                 // turn the led off
    analogWrite(led2, LOW);                 // turn the led off
    if (lastBright1 > 0)                      // check to see if the last brightness is more than 0 
        lastBright1 = lastBright1 * fade1;  // Dim the light til it reaches 0

    analogWrite(led1, lastBright1);       // write the brightness to the led
    analogWrite(led2, lastBright1);       // write the brightness to the led

  }
}

Thanks in advance for any help/advice.

I believe dimming of leds on the arduino is usually done using PWM, so have a look at that.

But, as it is, your fadeoff() function will only be called once on the transition. You need it to either be called continually in the loop, or for it to have its own loop until the fade is complete.

arduinodlb:
I believe dimming of leds on the arduino is usually done using PWM, so have a look at that.

But, as it is, your fadeoff() function will only be called once on the transition. You need it to either be called continually in the loop, or for it to have its own loop until the fade is complete.

I've managed to successfully fade leds w/ PWM on a loop, but the fadeOff() doesn't actually work at all the way I have it here. Pushing the button to turn it off doesn't do anything. No fade off, its not turning off at all. When I run the sketch it just does the baseFlicker() only. I'm unclear on how to call the functions properly, I've been studying functions tutorials but I haven't figured out what I'm doing wrong? It's obviously a lot more involved than a basic on/off switch but I'm just really stuck.

I'm aiming for a start-up and shutdown "behavior" from the lights, triggered by pressing the button.

Post your code as it is at the moment.

The code hasn't changed from the first post, I am really that stuck :frowning:

What about the version that successfully fades using PWM in a loop? Can you give us that version as well?

In the meantime, one way of getting the fadeoff to work, at least to demonstrate the problem, would be something like (untested):

void fadeOff () {

    int lastBright1 = 255;

   while (lastBright1 > 0)
   {
    analogWrite(led1, lastBright1);       // write the brightness to the led
    analogWrite(led2, lastBright1);       // write the brightness to the led
    lastBright1 = lastBright1 / 2;
    delay(50);
  }
    analogWrite(led1, 0); // make sure it's completely off
    analogWrite(led2, 0)
}

arduinodlb:
What about the version that successfully fades using PWM in a loop? Can you give us that version as well?

It's just a sketch that I was using to learn about PWM fading, not for this project, it doesn't have an on/off triggered by button or anything. Here it is though.

int value, value2 ;
int ledpin = 5;                           // light connected to digital pin 5
int ledpin2 = 6;                           // light connected to digital pin 6
long time=0;

int switchPin = 2;              // switch is connected to pin 2
int val;                        // variable for reading the pin status
int buttonState;                // variable to hold the button state
int buttonPresses = 0;          // how many times the button has been pressed

int brightMin = 116; // Baseline LED brightness. Cannot exceed 128.

int periode = 8000;
int displace = 10;

void setup() 
{ 
  pinMode(switchPin, INPUT);    // Set the switch pin as input

  Serial.begin(9600);           // Set up serial communication at 9600bps
  buttonState = digitalRead(switchPin);   // read the initial state

} 

void loop() 
{ 
  
   val = digitalRead(switchPin);      // read input value and store it in val

  if (val != buttonState) {          // the button state has changed!
    if (val == LOW) {                // check if the button is pressed
      buttonPresses++;               // increment the buttonPresses variable
      Serial.print("Button has been pressed ");
      Serial.print(buttonPresses);
      Serial.println(" times");
    }
  }

  buttonState = val;                 // save the new state in our variable
  
  time = millis();
  value = 128+127*cos(2*PI/periode*time);
  value2 = 128+127*cos(2*PI/periode*(displace-time));
  analogWrite(ledpin, value);           // sets the value (range from 0 to 255) 
  analogWrite(ledpin2, value);           // sets the value (range from 0 to 255) 
}

Thank you for your help! I still am unclear on the correct way to insert these functions within the main loop of the sketch? The button doesn't do anything. I understand the code for a simple on/off, but can't figure out where to go from there.

Rather than just give you code, I think it's useful for you to make sure you understand how to make this work.

So, to that end, let's take this one problem at a time, so that you can write your own code ultimately.

Let's start with this problem:

The button doesn't do anything. I understand the code for a simple on/off, but can't figure out where to go from there.

What do you mean by this? What is it that you are having trouble understanding?

arduinodlb:
What do you mean by this? What is it that you are having trouble understanding?

This code for basic on/off:

int inPin = 4;         
int outPin = 5;      
int outPin2 = 6;

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

long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers

void setup()
{
  pinMode(inPin, INPUT);
  pinMode(outPin, OUTPUT);
  pinMode(outPin2, OUTPUT);
}

void loop()
{
  reading = digitalRead(inPin);

  if (reading == LOW && previous == HIGH && millis() - time > debounce) {
    if (state == LOW)
      state = HIGH;
    else
      state = LOW;

    time = millis();    
  }

  digitalWrite(outPin, state);
  digitalWrite(outPin2, state);

  previous = reading;
}

If it reads the pin as LOW, pressing the button will make it HIGH (turn on), defined by "state" correct?

A friend edited the code for me to insert the functions, my only programming experience up till now has been tiny amounts of javascript for websites so yeah this is a bit over my head. I'm working my way thru tutorials and articles but I really just started. I really do appreciate this help though.

with functions. using this code in loop makes it run baseFlicker() only and the button does not work to turn it on or off anymore:

void loop()
{
  reading = digitalRead(button);

  if (reading == LOW && previous == HIGH && millis() - time > debounce) {
    if (state == LOW){
      state = HIGH;
      powerUp();
    }else{
      state = LOW;
      fadeOff();
    }  

    time = millis();    
  }

  if(state = HIGH){
    baseFlicker();
  }

  previous = reading;
}

I know this is super basic, but this is the difference between these bits of code that I am having trouble with. The reading I have done on calling functions hasn't been specific enough for me to figure out how to apply it here. Actually if you have any learning resource reccomendations I would be very grateful. I've mostly been studying the information on this site (tutorials/playground/etc) and tutorials on adafruit, and various C++ tutorials.

A function is just a way of organising code.

So, for example, you can either do:

{
    if (state == LOW)
    {
       analogWrite(led1, 50);
       analogWrite(led2, 50);
       delay(50);
    }
}

or

{
    if (state == LOW)
    {
         PowerUp();
    }
}

void PowerUp()
{
       analogWrite(led1, 50);
       analogWrite(led2, 50);
       delay(50);
}

Does that make sense?