Hi There,
There's lots of tutorials and examples on how to fade a led up and down without using delay() and they are great because I've got lots else to do in the loop without having to wait for delay(). Here is my challenge and I haven't really found a way to do it successfully (yet):
1st - wait for a certain period time before Led fades up (called "event state = up" in my program below) w/o blocking
2nd - fade led up at a pre-determine interval without blocking
3rd - hold Led at full on state for predetermined invert without blocking
4th - fade led down at (at same rate as fade up) without blocking
5th - start over - i.e wait for next event trigger
In other words: I would like to set constants for when led fades up and how long it is on before it fades down.
I think that I've been over thinking this too long and I'm stuck. I think that this could be done much simpler than what I've put together. Below is combination of other's sketch and some of my own:
//predetermined LED sequence - mark biasotti 11/18
const byte pwmLED = 3;
int long const event_trigger_ledup = 6000;
int long const event_trigger_ledconstant = 2000;
// How smooth to fade?
byte fadeIncrement = 10;
// How fast to increment?
int fadeInterval = 5;
// define directions for LED fade
#define UP 0
#define DOWN 1
//define states for event state
#define fadeupled 0
#define ledonconstant 1
#define fadedownled 2
// constants for min and max PWM
const int minPWM = 0;
const int maxPWM = 255;
// State Variable for Fade Direction
byte fadeDirection;
byte event_state;
// Global Fade Value
// but be bigger than byte and signed, for rollover
int fadeValue = 0;
// millis() timing Variable, just for fading
unsigned long previousFadeMillis;
unsigned long event_trigger_prevmillis_ledup = 0;
unsigned long event_trigger_prevmillis_ledon = 0;
void setup() {
// put pwmLED into known state (off)
analogWrite(pwmLED, fadeValue);
Serial.begin(250000);
Serial.println("Starting!");
}
void doTheFade(unsigned long thisMillis) {
// is it time to update yet?
// if not, nothing happens
if (thisMillis - previousFadeMillis >= fadeInterval) {
// yup, it's time!
if (fadeDirection == UP && event_state == fadeupled) {
fadeValue = fadeValue + fadeIncrement;
if (fadeValue >= maxPWM) {
// At max, limit and change direction
fadeValue = maxPWM;
fadeDirection = DOWN;
event_state = ledonconstant;
}
}
// time to fade led down
if (fadeDirection == DOWN && event_state == fadedownled) {
fadeValue = fadeValue - fadeIncrement;
if (fadeValue <= minPWM) {
// At max, limit and change direction
fadeValue = minPWM;
fadeDirection = UP;
}
}
// Only need to update when it changes
analogWrite(pwmLED, fadeValue);
// reset millis for the next iteration (fade timer only)
previousFadeMillis = thisMillis;
}
}
void loop() {
// get the current time, for this time around loop
// all millis() timer checks will use this time stamp
unsigned long event_trigger_currentmillis_ledup = millis();
if (event_trigger_currentmillis_ledup - event_trigger_prevmillis_ledup >= event_trigger_ledup) { // triggers led into event to fade up
event_state = fadeupled;
event_trigger_prevmillis_ledup = event_trigger_currentmillis_ledup;
}
if (event_state == ledonconstant) {
unsigned long event_trigger_currentmillis_ledon = millis();
if (event_trigger_currentmillis_ledon - event_trigger_prevmillis_ledon >= event_trigger_ledconstant) { // when on_state is reached then timer starts and when timer triggered Fade led down is triggered
event_state = fadedownled;
event_trigger_prevmillis_ledon = event_trigger_currentmillis_ledon;
}
}
unsigned long currentMillis = millis();
doTheFade(currentMillis); // aways calling this in every loop
Serial.print(" event_state = ");
Serial.print(event_state);
Serial.print(" fade direction = ");
Serial.print(fadeDirection);
Serial.print(" led value = ");
Serial.println(fadeValue);
}