LED single shot fade and flash in a function

I am at my wits end, am about to tear whats left of my hair out

I simply want to write a function that when called from a switch press ramps a led up to a set value (say 50), then immediately turn on full and stay on for a period of time (say 3 seconds). My attempts so far all fail with differing results. I've attached my latest attempt which I haven't tried yet as I'm still at work, but I'm sure its faulty in some way as I don't seem to be able to work out how to stop the ramp up section from repeating every time through the function loop without using a host of flags to tell the processor to either ignore or perform each part (ie ramp up or flash) without doing both.

If flags are the way forward, then so be it and I'll have to lose more hair, but I'm sure I'm following the wrong though process - there has to be a more elegant solution I'm sure. Maybe its just my lack of C++ structure knowledge?

If anyone can point me in the correct direction, I'd be extremely grateful, not to say less follicly challenged!

I've cut out a lot of the working sketch that is working ok and included just the triggering switch and questionable function so as not to confuse the issue further in the attached sketch. It compiles, but I haven't tested it as a whole and yes, I know its naive!.

int ledPin = 6;                      // led pin
const byte switchPin = 12;          // led switch pin (other connection to ground)

boolean SwitchFlag = true;              //  switch blocker (switch routine not to be called during led flash)
byte oldSwitchState = HIGH;             // assume switch open because of pull-up resistor
const unsigned long debounceTime = 10;  // milliseconds debounce setting
unsigned long switchPressTime;          // when the switch last changed state

//boolean flashOff = false;               // led ramp flag, initially not active
unsigned long timeNow;                  // time tracker for ramp up
unsigned long timeThen;                 // time intervals during ramp up
int brightness = 0;                     // led ramp up brightness
unsigned long currentFlashTime;         // led flash time tracker
unsigned long previousFlashTime;        // last time led flash was updated
unsigned long flashInterval = 3000;     // led flash length

byte switchFlag = 0;                    // Will store the current switch choice

void setup () {

  pinMode (ledPin, OUTPUT);
  pinMode (switchPin, INPUT_PULLUP);

}

void loop ( ) {
  switchCall ();                                      // Check the switch
}  // end of loop

void switchCall () {
  if (switchFlag) {                                  // Has previous beamer firing activation completed?
    byte switchState = digitalRead (switchPin);      // if it has, see if switch is open or closed
    if (switchState != oldSwitchState) {                 // has it changed since last time it was read?
      if (millis () - switchPressTime >= debounceTime) { // has enough time passed with stable reading?
        switchPressTime = millis ();                     // update the time
        oldSwitchState =  switchState;                   // remember the switch state for next time
        if (switchState == LOW) {                        // if switch passes debounce test and is pressed
          //         upFlag = true;                                 // set ramp up flag to on
          switchFlag = false;                        // ignore further switch readings
          function();                                      // and call the function
        }
      }
    }
  }
}

void function () {
  if (!switchFlag) {      // Has previous function activation completed?
    timeNow = millis();
    if (timeNow >= (timeThen + 30)) {
      analogWrite (ledPin, brightness);
      brightness++;
      if (brightness >= 50) {
        digitalWrite (ledPin, HIGH);
        currentFlashTime = millis ();
        if (currentFlashTime -  previousFlashTime >= flashInterval); {
          previousFlashTime = currentFlashTime;
          digitalWrite (ledPin, LOW);
          //        flashOff = true;
          switchFlag = true;
        }
      }
    }
  }
}

I think you are going about this all wrong. You call the (stupidly named) function() once, and expect it to fade an LED over time, without using delay().

Given that you call the function once, how can you reasonably expect that to happen?

You need to determine, in your convoluted switch logic, whether or not the function needs to be called.

Then, independently of the switch mess, call the function, if it needs to be called.

That way, the function gets called on every pass through loop(), until it says that it should not be called anymore.

In the function, you determine whether you need to do anything, what you need to do, and whether it is time to do something. If there is something to do, and you know what to do, and it is time to do it, do it, and set everything as needed for the next call.

Haven't viewed all the code because it seems way to complex... If you use some libraries you can make your life easy. For example Bounce2 to handle the button and FadeLed for the fading

I should say this does the job

#include <FadeLed.h>
#include <Bounce2.h>

const byte ButtonPin = 12;

const unsigned int LedOnTime = 3000;
const byte LedFadeBrightness = 50;
const byte LedMaxBrightness = 100; //change to 255 if you disable gamma correction

FadeLed led(6);
Bounce button;

unsigned long ledOnMillis;

void setup() {
  button.attach(ButtonPin, INPUT_PULLUP);

  led.setTime(1000, true); //set it to fade in 1 second

  //uncomment to disable gamma correction.
  //led.noGammaTable();
}

void loop() {
  FadeLed::update();

  //if led is off and button pressed
  if(!led.get() && button.fell()){
    led.set(LedFadeBrightness);
  }

  //if the led is done fading, turned on but not at full brightness
  if(led.done() && led.get() && led.get() < LedMaxBrightness){
    //turn on led full without fading
    led.begin(LedMaxBrightness);
    //and remember when we did that
    ledOnMillis = millis();
  }
  
  //turn led off if it's on at full brightness and times up
  if(led.get() == LedMaxBrightness && millis() - ledOnMillis > LedOnTime){
    led.begin(0);
  }
}

This also does the led fading with gamma correction (hence the max brightness of 100). If you don't want that read the comments on how to set that.

Yes, you're right about the function name Paul S, I was in a bit of a hurry when I copied the problem areas of my code to the posted code.

As to the rest of your explanation, I'm going to have to get some sleep first then find out where I can learn about function operations, as I don't understand completely what you are trying to hammer into my thick head. I think I see a clue there, but its going to take some work on my part.

Thanks for your time :slight_smile:

Thanks to you too Septillion, as soon as I understand functions properly I may well look at those libraries.

STDummy:
Thanks to you too Septillion, as soon as I understand functions properly I may well look at those libraries.

That would be the wrong way around... You first want to build make a wedding cake and then learn how to bake biscuits...

And besides, functions are not that hard... You already use them all the time! You have no trouble calling digitalWrite() or something as scary as a method from a class like Serial.print()!