//pwm-fade-with-millis.ino
// Example Fading LED with analogWrite and millis()
// See baldengineer.com/fading-led-analogwrite-millis-example.html for more information
// Created by James Lewis

const byte pwmLED = 5;

// define directions for LED fade
#define UP 0
#define DOWN 1

// constants for min and max PWM
const int minPWM = 0;
const int maxPWM = 255;

// State Variable for Fade Direction
byte fadeDirection = UP;

// Global Fade Value
// but be bigger than byte and signed, for rollover
int fadeValue = 0;

// How smooth to fade?
byte fadeIncrement = 5;

// millis() timing Variable, just for fading
unsigned long previousFadeMillis;

// Number of microseconds between states
int fadeInterval = 50;

void setup() {
  Serial.begin(9600);
  // put pwmLED into known state (off)
  analogWrite(pwmLED, fadeValue);
}



void loop() {
   // get the current time, for this time around loop
   // all millis() timer checks will use this time stamp
   unsigned long currentMillis = millis();

   doTheFade(currentMillis);
   //Serial.print("currentMillis: "); Serial.println(millis());
}

void doTheFade(unsigned long thisMillis) {
  // is it time to update yet?
  // if not, nothing happens
  if (thisMillis - previousFadeMillis >= fadeInterval) { // 50 - 0 >= 50, 100 - 50 >= 50, etc.
    Serial.print("thisMillis: "); Serial.println(thisMillis);
    Serial.print("previousFadeMillis: "); Serial.println(previousFadeMillis);
    // yup, it's time!
    if (fadeDirection == UP) { // Initial state, True
      fadeValue = fadeValue + fadeIncrement; // 0 = 0 + 5
      if (fadeValue >= maxPWM) { // if = 255
        Serial.println("if DOWN:");
        // At max, limit and change direction
        fadeValue = maxPWM; // = 255
        fadeDirection = DOWN; // change state to DOWN
      }
    } 
    else {
      // fadeDirection is now DOWN
      fadeValue = fadeValue - fadeIncrement;
      if (fadeValue <= minPWM) {
        // At min, limit and change direction
        fadeValue = minPWM; // = 0
        fadeDirection = UP; // state change moves code to UP
      }
    }
      // Only need to update when it changes
      analogWrite(pwmLED, fadeValue);

      // reset millis for the next iteration (fade timer only)
      previousFadeMillis = thisMillis;
   }
}