Millis() fade in--hold--fade out over hours; LEDs

Hi! From looking at the other threads on here, I attempted to code a daylight/noon/night cycle for my LED project.

I ran it overnight to see if it actually works…and it in fact doesn’t. According to the serial.Print function, I can see it actually is counting up when connected to the computer.

/*
 Nano_R With Fading
 
 The circuit:
 * Two strings of LEDS with separate drivers attached to digital pin 9 and pin 10.
 * Fade in over 2 hours, hold max brightness for 3 hours, fade out over 3 hours.
*/


int whiPin = 9;   
int bluPin = 10;

long intervalmorn = 28235;   // 2 hours--frequency of changes, sunrise
long intervalnoon = 42352; // 3 hours--frequency of changes, max brightness
long intervalnite = 42352; // 3 hours--frequency of changes, sunset

  int fadeValuerise = 0;
  int fadeValueset = 255;
  int holdValuenoon = 0; 
  
void setup()  { 
} 

void loop()  { 
  // fade in from min to max in increments of 28235 points:

  while(fadeValuerise < 255) {
    // sets the value (range from 0 to 255):
    analogWrite(whiPin, fadeValuerise);
    analogWrite(bluPin, fadeValuerise);  
    
   unsigned long currentMillis = millis();
      if(currentMillis = fadeValuerise*intervalmorn) {
        fadeValuerise ++;
       }                      
  } 
  
long oldmillis1 = 7199925; //millis counter continuation from above
  
  while(holdValuenoon < 255) { 
    analogWrite(whiPin, 245);
    analogWrite(bluPin, 255);  
    
    unsigned long currentMillis = millis();
      if(currentMillis = oldmillis1 + (holdValuenoon*intervalnoon)) {
        holdValuenoon ++;
      }
  }
  
long oldmillis2 = 17999685; ////millis counter continuation from above
 
 
  // fade out from max to min in increments of 42352 points:
  while(fadeValueset > 0) { 
    // sets the value (range from 255 to 0):
    analogWrite(whiPin, fadeValueset);         
    analogWrite(bluPin, fadeValueset);
    
   unsigned long currentMillis = millis();
    if(currentMillis = oldmillis2 + (fadeValueset*intervalnite)) {
      fadeValueset --;                         
    }
  }
}

I hope someone can help me out here! Really bummed out since it all made sense to me in my head. :frowning:

Thanks in advance!
Jonathan

if(currentMillis [glow]=[/glow] fadeValuerise*intervalmorn)
if(currentMillis [glow]=[/glow] oldmillis2 + (fadeValueset*intervalnite))

http://arduino.cc/en/Reference/If

Can you explain some of the constants?

long intervalmorn = 28235;

Thanks for the crazy fast reply!

I thought that to make it easier, I'd use a rounded number (in milliseconds) equivalent for 2 hours, 3 hours, and 3 hours. These rounded numbers are the first three longs in the beginning of the code.

If these numbers, multiplied by the place in the while loop (0-255), can be compared to the currentMillis counter, then we can use it to trigger when to move the loop from 0 to 1, and from 1-2, etc. This should increase the loop linearly over a course of roughly 2 hours, or so i think..?

The others (hold 3 hours, fade over 3 hours) were made with the same thought process.

Summary: Compare the currentMIllis counter to the multiplied out value (2 hours divided by 255 and current pwm value [0-255]). If comparison = true, increase loop counter by 1.

Maybe helps?

I thought that to make it easier, I’d use a rounded number (in milliseconds) equivalent for 2 hours, 3 hours, and 3 hours

Nope, still not seeing it.

long intervalmorn = 28235;

28235 / 1000 (milliseconds) = 2823.5 seconds = 47 minutes 3.5 seconds. Quite a way short of an hour.

Make it easy for yourself, ues the compiler and the preprocessor,

const unsigned long MILLIS_PER_SECOND = 1000UL;
const unsigned long MILLIS_PER_MINUTE = 60UL * MILLIS_PER_SECOND;
const unsigned long MILLIS_PER_HOUR = 60UL * MILLIS_PER_MINUTE;

or something similar.

What I meant with the 28235 is 2 hours convert to--> milliseconds = 7,200,000 milliseconds, which is then divided by 255 "steps" for 28235.

I kinda understand what you're getting at with the MILLIS_PER_SECOND, etc. I'll update my code now to make it less stupid. ;)

Would this work out for what we’re trying to do?

/*
 Nano_R With Fading
 
 The circuit:
 * Two strings of LEDS with separate drivers attached to digital pin 9 and pin 10.
 * Fade in over 2 hours, hold max brightness for 3 hours, fade out over 3 hours.
*/


int whiPin = 9;   
int bluPin = 10;

  int fadeValuerise = 0;
  int fadeValueset = 255;
  int holdValuenoon = 0; 
  
const unsigned long MILLIS_PER_SECOND = 1000UL;
const unsigned long MILLIS_PER_MINUTE = 60UL * MILLIS_PER_SECOND;
const unsigned long MILLIS_PER_HOUR = 60UL * MILLIS_PER_MINUTE; 

long intervalmorn = 2*MILLIS_PER_HOUR;   // 2 hours--frequency of changes, sunrise
long intervalnoon = 3*MILLIS_PER_HOUR; // 3 hours--frequency of changes, max brightness
long intervalnite = 3*MILLIS_PER_HOUR; // 3 hours--frequency of changes, sunset

void setup()  {
} 

void loop()  { 

  while(fadeValuerise < 255) {
    analogWrite(whiPin, fadeValuerise);
    analogWrite(bluPin, fadeValuerise);  
    
   unsigned long currentMillis = millis();
      if(currentMillis = (fadeValuerise*2*MILLIS_PER_HOUR)/intervalmorn) {
        fadeValuerise ++;
       }                      
  } 
  
const long oldmillis1 = millis(); //millis counter continuation from above
  
  while(holdValuenoon < 255) { 
    analogWrite(whiPin, 230);
    analogWrite(bluPin, 245);  
    
    unsigned long currentMillis = millis();
      if(currentMillis = oldmillis1 + ((holdValuenoon*3*MILLIS_PER_HOUR)/intervalnoon)) {
        holdValuenoon ++;
      }
  }
  
long oldmillis2 = millis() ///millis counter point after completing second loop above
 
 
  // fade out from max to min
  while(fadeValueset > 0) { 
    // sets the value (range from 255 to 0):
    analogWrite(whiPin, fadeValueset);         
    analogWrite(bluPin, fadeValueset);
    
   unsigned long currentMillis = millis();
    if(currentMillis = oldmillis2 + ((fadeValueset*3*MILLIS_PER_HOUR)/intervalnite)) {
      fadeValueset --;                         
    }
  }
}

Fewer giant numbers–more easily accessed hopefully…

Need help...I'm getting 0V out of the PWM pins using this code. Anyone?

How are you measuring that 0V? A PWM pin is turned on and off for various (short) durations, such that the ON time is the specified ratio of total time. Many multi-meters do not measure voltage well on PWM pins. LEDs connected to PWM pins appear to work correctly because the brain can not process the on/off cycling fast enough, so the LED appears to be on all the time.

You still have some coding issues that you have not addressed.

if(currentMillis = (fadeValuerise*2*MILLIS_PER_HOUR)/intervalmorn)

This statement will compute a value, and assign it to currrentMillis. This is probably not what you want to be doing. You want to compare the value currently in currentMillis to the computed value (using ==).

Thanks for the help paul. I changed the conditionals to == per your suggestions. I didn’t measure the 0v, I just guessed that was the case because the LED’s stayed completely unlit for hours.

After adding the ==, it puts out light, but heavily dimmed. Stays constant like this otherwise.

There’s gotta be something wrong with this structure huh…

  while(fadeValuerise < 255) {
    analogWrite(whiPin, fadeValuerise);
    analogWrite(bluPin, fadeValuerise);  
    
   unsigned long currentMillis = millis();
      if (currentMillis == ((fadeValuerise*2*MILLIS_PER_HOUR)/intervalmorn)) {
        fadeValuerise ++;
       }                      
  }

Almost there…! i’m hopeful :slight_smile:

Since intervalmorn is set to 2*MILLIS_PER_HOUR, the if test boils down to:

if (currentMillis == fadeValuerise) {
        fadeValuerise ++;
       }

But, currentMillis is the number of milliseconds since the Arduino was restarted. Expecting that value to EQUAL a counter seems unreasonable.