Aquarium LEDs and fading

hey

I am struggling with some code. I don't want the code written exactly for me, more i want to understand in idiot terms!

here is my code

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR    0x3F  // Define I2C Address where the SainSmart LCD is
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

LiquidCrystal_I2C	lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

int hour;
int minute;
int second;
int month;
int day_of_week;
int day;
int year;

char* dow[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

int gLEDpin = 11;
int bLEDpin = 10;
int rLEDpin = 6;

////////////////////////////////////////////////////////////
int sunRiseHour =      9; // sun rise start
int sunRiseMin =       0;

int dayHour =         10; // daylight starts
int dayMin =           0;

int sunSetHour =      16; // sun set start
int sunSetMin =        0;

int twilightHour =    16; //twilight start
int twilightMin  =     0;

int twilightSetHour = 20; // twilight set
int twilightSetMin  =  0;

int lightOffHour =    21; // night
int lightOffMin  =     1;
///////////////////////////////////////////////////////////////



void setup()
{
  Serial.begin(9600);
  Wire.begin();
    lcd.begin (20,4);
  
  // Switch on the backlight
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);
  
  digitalWrite(gLEDpin, LOW);
  digitalWrite(bLEDpin, LOW);
  digitalWrite(rLEDpin, LOW);
}

void loop()
{
  // Below required to reset the register address to 0.
  Wire.beginTransmission(104); // transmit to device #104, the ds 1307
  Wire.write(0x00);
  Wire.endTransmission();    // stop transmitting
 
  Wire.requestFrom(104, 7);    // request 7 bytes from slave ds1307, we'll assume it'll send them all even though it doesn't have to
  second = Wire.read(); 
  minute = Wire.read(); 
  hour = Wire.read(); 
  day_of_week=Wire.read(); 
  day = Wire.read(); 
  month = Wire.read(); 
  year = Wire.read(); 

  // Convert all the BCD values that might have "tens" to decimal.  
  // Most arduino folks do this w/shifts but this just looks easier to me.
  hour=hour/16 * 10 + hour % 16;
  minute=minute/16 * 10 + minute % 16;
  second=second/16 * 10 + second % 16;
  day=day/16 * 10 + day % 16;
  month=month/16 * 10 + month % 16;
  year=year/16 * 10 + year % 16;
  
  Serial.print(hour);
  Serial.print(":");
  if (minute < 10) { Serial.print("0"); }
  Serial.print(minute);
  Serial.print(":");
  if (hour < 12) { Serial.print("am"); }
  if (hour > 12) { Serial.print("pm"); }
  
  Serial.print(" ");
  Serial.print(dow[day_of_week-1]);  // array is 0-6, but the dow register holds 1-7, so subtract 1.
  Serial.print(" ");
  Serial.print(month);
  Serial.print("/");
  Serial.print(day);
  Serial.print("/");
  Serial.print(year);
  Serial.print("\n");
  
    lcd.home ();   
  if (hour <= 9) {lcd.print("0"); }
  if (hour > 12 && hour < 22) {lcd.print("0"); }
  if (hour <= 12) {lcd.print(hour); }
  if (hour > 12) { lcd.print(hour - 12); }
    
  lcd.print(":");
  if (minute < 10) { lcd.print("0"); }
  lcd.print(minute);
  if (hour < 12) { lcd.print("am"); }
  if (hour >= 12) { lcd.print("pm"); }
  lcd.setCursor (8,0);
  lcd.print(dow[day_of_week-1]);  // array is 0-6, but the dow register holds 1-7, so subtract 1.
  lcd.setCursor (12,0);
  lcd.print(day);
  lcd.print("/");
  if (month < 10) { lcd.print("0"); }
  lcd.print(month);
  lcd.print("/");
  lcd.print(year);
  
  if ((hour >= sunRiseHour) &&  (hour < dayHour) && (minute >= sunRiseMin) && (minute < dayMin))
  {sunRise;}
  
  if ((hour >= dayHour) &&  (hour < sunSetHour) && (minute >= dayMin) && (minute < sunSetMin))
  {dayLight;}
  
  if ((hour >= sunSetHour) &&  (hour < twilightHour) && (minute >= sunSetMin) && (minute < twilightMin))
  {sunSet;}
  
  if ((hour >= twilightHour) &&  (hour < twilightSetHour) && (minute >= twilightMin) && (minute < twilightSetMin))
  {twilight;}
  
  if ((hour >= twilightSetHour) &&  (hour < lightOffHour) && (minute >= twilightSetMin) && (minute < lightOffMin))
  {twilightSet;}
  
  if ((hour >= lightOffHour) &&  (hour < sunRiseHour) && (minute >= lightOffMin) && (minute < sunRiseMin))
  {night;}
  
  delay(250);

}


void sunRise()
{
 
}

void dayLight()
{
  digitalWrite(gLEDpin, HIGH);
  digitalWrite(bLEDpin, HIGH);
  digitalWrite(rLEDpin, HIGH);
}




void sunSet()
{

}

void twilight()
{
  digitalWrite(bLEDpin, HIGH);
  digitalWrite(rLEDpin, LOW);
  digitalWrite(gLEDpin, LOW);
}

void twilightSet(){}

void night()
{
  digitalWrite(bLEDpin, LOW);
  digitalWrite(rLEDpin, LOW);
  digitalWrite(gLEDpin, LOW);
}

basically i want to all LEDs to begin fading on at a time set and go from zero to 255 over an hour (sunRise. then all lights to stay on (dayLight). Then at a time, begin to fade over an hour from 255 to zero except bLEDpin, this needs to stay on (sunSet). then the bLEDpin to stay on until a time (twilight, then fade off (twilightSet). and then all off (night)

i have got dayLight, twilight and night sorted. but cant seem to get the fading sorted. I cant use delays as there will be other functions, such as button push, that will be added later, so i dont want the program to stop at a delay. i cant seem to see how to write the code for millis. Or can it be mapped to 60 mins?

i know my code is not efficient, but i will improve on this as my experience grows. I am still a newbie!

Kr
Craig

Wouldn't this:

  // Below required to reset the register address to 0.
  Wire.beginTransmission(104); // transmit to device #104, the ds 1307
  Wire.write(0x00);
  Wire.endTransmission();    // stop transmitting
 
  Wire.requestFrom(104, 7);    // request 7 bytes from slave ds1307, we'll assume it'll send them all even though it doesn't have to
  second = Wire.read(); 
  minute = Wire.read(); 
  hour = Wire.read(); 
  day_of_week=Wire.read(); 
  day = Wire.read(); 
  month = Wire.read(); 
  year = Wire.read();

make more sense in a function? Then, in loop(), you'd have one line of code, not 13.

Overall, wouldn't a factor of 13 reduction in the amount of code in loop() make it easier to understand?

Here's another function opportunity:

  // Convert all the BCD values that might have "tens" to decimal.  
  // Most arduino folks do this w/shifts but this just looks easier to me.
  hour=hour/16 * 10 + hour % 16;
  minute=minute/16 * 10 + minute % 16;
  second=second/16 * 10 + second % 16;
  day=day/16 * 10 + day % 16;
  month=month/16 * 10 + month % 16;
  year=year/16 * 10 + year % 16;

And another:

  Serial.print(hour);
  Serial.print(":");
  if (minute < 10) { Serial.print("0"); }
  Serial.print(minute);
  Serial.print(":");
  if (hour < 12) { Serial.print("am"); }
  if (hour > 12) { Serial.print("pm"); }
  
  Serial.print(" ");
  Serial.print(dow[day_of_week-1]);  // array is 0-6, but the dow register holds 1-7, so subtract 1.
  Serial.print(" ");
  Serial.print(month);
  Serial.print("/");
  Serial.print(day);
  Serial.print("/");
  Serial.print(year);
  Serial.print("\n");

And, look, another one:

    lcd.home ();   
  if (hour <= 9) {lcd.print("0"); }
  if (hour > 12 && hour < 22) {lcd.print("0"); }
  if (hour <= 12) {lcd.print(hour); }
  if (hour > 12) { lcd.print(hour - 12); }
    
  lcd.print(":");
  if (minute < 10) { lcd.print("0"); }
  lcd.print(minute);
  if (hour < 12) { lcd.print("am"); }
  if (hour >= 12) { lcd.print("pm"); }
  lcd.setCursor (8,0);
  lcd.print(dow[day_of_week-1]);  // array is 0-6, but the dow register holds 1-7, so subtract 1.
  lcd.setCursor (12,0);
  lcd.print(day);
  lcd.print("/");
  if (month < 10) { lcd.print("0"); }
  lcd.print(month);
  lcd.print("/");
  lcd.print(year);

Now, to the heart of the matter. Exactly what do you think this block of code is doing?

  {sunRise;}

That might as well be:

47;

that line of code is telling the arduino that if the above if statement is satisfied, carry out function sunRise.

if you go further down you will see void sunRise(). I need help with the code to fade the LEDs that will go in the sunRise function

kr
Craig

that line of code is telling the arduino that if the above if statement is satisfied, carry out function sunRise.

No, it isn't.

sunrise(); // call the function

ahh ok. thanks!

i did say my code is not efficient. I will tidy it up as i near the final version. Its like that because i have been testing a tiny piece of code, if it works i have then added to it. Once i get a code that does what i need (which will be long), and works, i will then go back through it and make it more efficient. If i change to many things along the way and something doesnt work it will be harder for me to narrow it down. Plus i will be ordering some parts that may be expensive, so i just want a piece of code that works on a prototype. If i can get there i wil order the bits and then go from there

i am really only starting to learn C, so go easy on me. i am trying to learn the words that will be used, before i write a shakespear.

So any thoughts on the original question instead to pulling my humble attemps at code writing apart? :blush:

kr
Craig

So any thoughts on the original question instead to pulling my humble attemps at code writing apart?

Since your code was not doing what you thought it was doing, it's going to be impossible to determine what the problem is.

Once you fix the code so that it does what you think it is doing, then the problem might go away, or it might not. If not, post the modified code, explain what it does, and how that differs from what you want.

thanks for your replies

I think you have missed the point. the code does work, with the exception of the fading, which is in void sunRise, void sunSet and void twilightSet.

These functions dont work as i have not written the code for them. I have not written the code because i am unsure how to. I am not asking why my code does not work, i am asking how, in this code / situation, would you write a short piece of code to fade on and fade off leds over an hour or a variable such as fade time without using delays.

is this any better:

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR    0x3F  // Define I2C Address where the SainSmart LCD is
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

LiquidCrystal_I2C	lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

int hour;
int minute;
int second;
int month;
int day_of_week;
int day;
int year;

char* dow[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

int gLEDpin = 11;
int bLEDpin = 10;
int rLEDpin = 6;

////////////////////////////////////////////////////////////
int sunRiseHour =      9; // sun rise start
int sunRiseMin =       0;

int dayHour =         10; // daylight starts
int dayMin =           0;

int sunSetHour =      16; // sun set start
int sunSetMin =        0;

int twilightHour =    16; //twilight start
int twilightMin  =     0;

int twilightSetHour = 20; // twilight set
int twilightSetMin  =  0;

int lightOffHour =    21; // night
int lightOffMin  =     1;
///////////////////////////////////////////////////////////////


void setup()
{
  Serial.begin(9600);
  Wire.begin();
    lcd.begin (20,4);
  
  // Switch on the backlight
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);
  
  analogWrite(gLEDpin, 0);
  analogWrite(bLEDpin, 0);
  analogWrite(rLEDpin, 0);
}

void loop()
{
  readtime();
  
  bcdToDec();

  printSerial();

  printLCD();
      
  if ((hour >= sunRiseHour) &&  (hour < dayHour) && (minute >= sunRiseMin) && (minute < dayMin))
  {sunRise();}
  
  if ((hour >= dayHour) &&  (hour < sunSetHour) && (minute >= dayMin) && (minute < sunSetMin))
  {dayLight();}
  
  if ((hour >= sunSetHour) &&  (hour < twilightHour) && (minute >= sunSetMin) && (minute < twilightMin))
  {sunSet();}
  
  if ((hour >= twilightHour) &&  (hour < twilightSetHour) && (minute >= twilightMin) && (minute < twilightSetMin))
  {twilight();}
  
  if ((hour >= twilightSetHour) &&  (hour < lightOffHour) && (minute >= twilightSetMin) && (minute < lightOffMin))
  {twilightSet();}
  
  if ((hour >= lightOffHour) &&  (hour < sunRiseHour) && (minute >= lightOffMin) && (minute < sunRiseMin))
  {night();}
  
  delay(250);

}

 void readtime()
 {
  // Below required to reset the register address to 0.
  Wire.beginTransmission(104); // transmit to device #104, the ds 1307
  Wire.write(0x00);
  Wire.endTransmission();    // stop transmitting
 
  Wire.requestFrom(104, 7);    // request 7 bytes from slave ds1307, we'll assume it'll send them all even though it doesn't have to
  second = Wire.read(); 
  minute = Wire.read(); 
  hour = Wire.read(); 
  day_of_week=Wire.read(); 
  day = Wire.read(); 
  month = Wire.read(); 
  year = Wire.read(); 
 }
 
 void bcdToDec()
{
  hour=hour/16 * 10 + hour % 16;
  minute=minute/16 * 10 + minute % 16;
  second=second/16 * 10 + second % 16;
  day=day/16 * 10 + day % 16;
  month=month/16 * 10 + month % 16;
  year=year/16 * 10 + year % 16;
}
 
  void printSerial()
 {
  Serial.print(hour);
  Serial.print(":");
  if (minute < 10) { Serial.print("0"); }
  Serial.print(minute);
  Serial.print(":");
  if (hour < 12) { Serial.print("am"); }
  if (hour > 12) { Serial.print("pm"); }
  
  Serial.print(" ");
  Serial.print(dow[day_of_week-1]);  // array is 0-6, but the dow register holds 1-7, so subtract 1.
  Serial.print(" ");
  Serial.print(month);
  Serial.print("/");
  Serial.print(day);
  Serial.print("/");
  Serial.print(year);
  Serial.print("\n");
 }
 
   void printLCD()
  {
    lcd.home ();   
  if (hour <= 9) {lcd.print("0"); }
  if (hour > 12 && hour < 22) {lcd.print("0"); }
  if (hour <= 12) {lcd.print(hour); }
  if (hour > 12) { lcd.print(hour - 12); }
    
  lcd.print(":");
  if (minute < 10) { lcd.print("0"); }
  lcd.print(minute);
  if (hour < 12) { lcd.print("am"); }
  if (hour >= 12) { lcd.print("pm"); }
  lcd.setCursor (8,0);
  lcd.print(dow[day_of_week-1]);  // array is 0-6, but the dow register holds 1-7, so subtract 1.
  lcd.setCursor (12,0);
  lcd.print(day);
  lcd.print("/");
  if (month < 10) { lcd.print("0"); }
  lcd.print(month);
  lcd.print("/");
  lcd.print(year);
  }
  
void sunRise()
{
 
}

void dayLight()
{
  digitalWrite(gLEDpin, 0);
  digitalWrite(bLEDpin, 0);
  digitalWrite(rLEDpin, 0);
}

void sunSet()
{

}

void twilight()
{
  digitalWrite(bLEDpin, 255);
  digitalWrite(rLEDpin, 0);
  digitalWrite(gLEDpin, 0);
}

void twilightSet()
{

}

void night()
{
  digitalWrite(bLEDpin, 0);
  digitalWrite(rLEDpin, 0);
  digitalWrite(gLEDpin, 0);
}

I think you have missed the point. the code does work, with the exception of the fading, which is in void sunRise, void sunSet and void twilightSet.

That is IMPOSSIBLE for you to know, since you were NOT calling the functions.

is this any better:

Hell if I know. I'm tired of being called an idiot.

hey
I am not saying you are an idiot! certainly not.

I was calling the functions, i simply missed the brackets! i would of spotted that as that little piece of code i added would not of worked!

i have corrected this in the last post

Can i rephrase the question?

how do you make an led fade on over a period of 60 mins without using the delay function

kr
craig

I was calling the functions, i simply missed the brackets!

Without the parentheses, you were NOT calling the functions, no matter how much wishful thinking is involved.

how do you make an led fade on over a period of 60 mins without using the delay function

Have you studied the blink without delay example? The difference between that example and what you want to do is that periodically you want to change the PWM value(s) applied to some pin(s), rather than turning a pin on or off.

The biggest problem is that you can't have sunRise() (or the others) be a blocking function. Which means that you need to call the function over and over between the start of fade time and the end of fade time. On each call, the function determines if it is time to do something. If it is, it does it.

Without the parentheses, you were NOT calling the functions, no matter how much wishful thinking is involved.

I understand that 100%. I missed the parentheses off. No big issue. As i see it, what i was trying to do was correct, i just didnt get the grammer correct. so it would not of called that function. Remember i am a newbie, so no need to go chapter and verse. All you had to say was you missed the parentheses off, but otherwise it looks like it will call the function as i have intended.

Anyways, i have studied that example. And i also understand i need to recall the function every time the code goes through the loop function. It cant stop the arduino during this process.

So how to i incorporate that code in to the function, and make it start at a time and continue for an hour?

Kr
Craig

So how to i incorporate that code in to the function, and make it start at a time and continue for an hour?

Isn't this:

  if ((hour >= sunRiseHour) &&  (hour < dayHour) && (minute >= sunRiseMin) && (minute < dayMin))
  {sunRise();}

Supposed to call the function over and over for an hour? Does it actually do that?

If so, then in sunRise(), you simply need to determine how long it's been since you last changed PWM value(s). To do that, you need to keep track of the last time you changed PWM values. That will present a bit of a challenge.

You need to have loop() determine if it has become time to start the sunrise fade effect. When that becomes true, you set the last fade time to 0 and set a flag that says that sunrise fading should happen.

You also need to have loop() determine if it has become time to stop the sunrise fade effect. If it has, set the flag to false.

Finally, you need to have loop() call the sunRise() function if the flag is true.

So, three separate tests. The state change detection example bears looking into.

Back to sunRise(). Now that you know when the last change happened, you can tell if it's time to change again (because 1/255th of the hour has passed). If it is, increment (or decrement) the PWM value(s), and apply the new value(s) to the pin(s).

ok, i think i see!

So in the loop(), i could of simply called a time. So for example if the time has reached the desired start time, do sunRise(). And then the rest of the commands are then put in the sunRise() loop.

I set the if statement that if its between a time run the sunRise() loop for example. I did this incase i had a power cut, then when the arduino turns back on, it will go back to the function it was doing when it turned off. That was the idea, and would work for any function that gives a set value, such as daylight! where the lights are on continuously.

But i think to get that to work across the board is beyond me for the time being.

So can you give me an example piece of code that would go in the function sunRise(). If i am going down the wrong track with my if statements in the loop(), can you explain an alternative?

Kr
Craig

If i am going down the wrong track with my if statements in the loop(), can you explain an alternative?

You need to add global variables:

bool sunriseFading = false;
unsigned long lastChange;
int pwmInit;

Then,

  if ((hour >= sunRiseHour) &&  (hour < dayHour) && (minute >= sunRiseMin) && (minute < dayMin))
  {sunRise();}

becomes:

  if ((hour >= sunRiseHour) && (minute >= sunRiseMin) && !sunriseFading)
  {
     sunriseFading = true;
     lastChange = 0;
     pwmInit = 0;
  }

  if ((hour < dayHour) && (minute < dayMin) && sunriseFading)
  {
     sunriseFading = false;
     lastChange = 0;
  }

  if(sunriseFading)
  {
      sunRise();
  }

See the three separate tests I was talking about?

Then, sunRise() is pretty simple:

void sunRise()
{
   unsigned long now = millis();
   if(now - lastChange > interval)
   {
      pwmInit++;

      // Apply the pwmInit value to the pin

      lastChange = now;
   }
}

You'll need to define interval somewhere, as 1/255th of an hour. If you are fading two colors, changing from red to blue, for instance, you'll need two variables - increment one and decrement the other.

ok thanks for that!

I am just going out now, but i will sit down and study what you have written. Thanks alot!

Kr
Craig

Hey PaulS

Just to make sure i understand every bit of code:

bool sunriseFading = false; //boolean value, either true or false. 
unsigned long lastChange; //long number from 0 upwards called lastchange
int pwmInit; // i think this is the counter used for increasing the brightness
  if ((hour >= sunRiseHour) && (minute >= sunRiseMin) && !sunriseFading) //if hour and min is more than or equal the target time and we are not sunrise fading, then
  {
     sunriseFading = true; //set sunrisefading to true
     lastChange = 0; //set lastchange to 0
     pwmInit = 0; // set to 0
  }

  if ((hour < dayHour) && (minute < dayMin) && sunriseFading) // confused here, should this be if current time is more than target time (day), and we are fading then stop?
  {
     sunriseFading = false;
     lastChange = 0;
  }

  if(sunriseFading) // if we are fading, run the function sunRise
  {
      sunRise();
  }
void sunRise() //sunrise function
{
   unsigned long now = millis(); // start counting millis
   if(now - lastChange > interval) //if now - last change is more than interval (in my case 14 seconds) then
   {
      pwmInit++; //increment brightness by this

      // Apply the pwmInit value to the pin. For example:

analogWrite(rLEDpin, pwmlnit);

      lastChange = now; sets last change to now. 
   }
}

So do we need to restrict the pwmlnit value to a max of 255?

I guess i could also set the interval as daylight time - sunrise time (in millis)?

Thanks for your advice so far!
Kr
Craig

So do we need to restrict the pwmlnit value to a max of 255?

Wouldn't hurt, but it shouldn't be necessary.

The comments are correct.

I guess i could also set the interval as daylight time - sunrise time (in millis)?

You could. That would let you change the length of time the fading takes without hard-coding anything.

this is the code so far, Surprise its not working! haha

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR    0x3F  // Define I2C Address where the SainSmart LCD is
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

LiquidCrystal_I2C	lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);



int hour;
int minute;
int second;
int month;
int day_of_week;
int day;
int year;

char* dow[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

int gLEDpin = 11;
int bLEDpin = 10;
int rLEDpin = 6;

////////////////////////////////////////////////////////////
int sunRiseHour =      23; // sun rise start
int sunRiseMin =       1;

int dayHour =         23; // daylight starts
int dayMin =           3;

int sunSetHour =      22; // sun set start
int sunSetMin =        4;

int twilightHour =    23; //twilight start
int twilightMin  =     6;

int twilightSetHour = 23; // twilight set
int twilightSetMin  =  7;

int lightOffHour =    23; // night
int lightOffMin  =     9;
///////////////////////////////////////////////////////////////

bool sunRiseFading = false;
bool sunSetFading = false;
bool twilightSetFading = false;

unsigned long lastChange;
int fadeUp;
int fadeDown;


void setup()
{
  Serial.begin(9600);
  Wire.begin();
    lcd.begin (20,4);
  
  // Switch on the backlight
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);
  
  analogWrite(gLEDpin, 0);
  analogWrite(bLEDpin, 0);
  analogWrite(rLEDpin, 0);
}

void loop()
{
  readtime();
  
  printSerial();

  printLCD();
  
  ////////////////////////////////////////////////////////////////////////////  
  if ((hour >= sunRiseHour) && (minute >= sunRiseMin) && !sunRiseFading)
  {
     sunRiseFading = true;
     lastChange = 0;
     fadeUp = 0;
  }

  if ((hour > dayHour) && (minute > dayMin) && sunRiseFading)
  {
     sunRiseFading = false;
     lastChange = 0;
  }

  if(sunRiseFading)
  {
      sunRise();
  }
 ////////////////////////////////////////////////////////////////////////////
if ((hour >= dayHour) && (minute >= dayMin) && (hour < sunSetHour) && (minute < sunSetMin))
    analogWrite(rLEDpin, 255);
    analogWrite(bLEDpin, 0);
    analogWrite(gLEDpin, 0);

////////////////////////////////////////////////////////////////////////////
  if ((hour >= sunSetHour) && (minute >= sunSetMin) && !sunSetFading)
  {
     sunSetFading = true;
     lastChange = 0;
     fadeUp = 0;
     fadeDown = 255;
  }

  if ((hour > lightOffHour) && (minute > lightOffMin) && sunSetFading)
  {
     sunSetFading = false;
     lastChange = 0;
  }

  if(sunSetFading)
  {
      sunSet();
  }

////////////////////////////////////////////////////////////////////////////

if ((hour >= twilightHour) && (minute >= twilightMin) && (hour < twilightSetHour) && (minute < twilightSetMin))
    analogWrite(rLEDpin, 0);
    analogWrite(bLEDpin, 255);
    analogWrite(gLEDpin, 0);

////////////////////////////////////////////////////////////////////////////
  if ((hour >= twilightSetHour) && (minute >= twilightSetMin) && !twilightSetFading)
  {
     twilightSetFading = true;
     lastChange = 0;
     fadeUp = 0;
     fadeDown = 255;
  }

  if ((hour > lightOffHour) && (minute > lightOffMin) && twilightSetFading)
  {
     twilightSetFading = false;
     lastChange = 0;
  }

  if(twilightSetFading)
  {
      twilightSet();
  }


///////////////////////////////////////////////////////////////////////////////

if ((hour > lightOffHour) && (minute > lightOffMin) && (hour <= 23) && (minute <= 59))
{
  night();
}
if ((hour < sunRiseHour) && (minute < sunRiseMin))
{
  night();
}
}

void sunRise()
{
      unsigned long now = millis();
   if(now - lastChange > 100) 
   {
      fadeUp ++; 
      fadeUp = constrain(fadeUp, 0, 255);
      analogWrite(rLEDpin, fadeUp);
      analogWrite(bLEDpin, 0);
      analogWrite(gLEDpin, 0);
      lastChange = now; 
    
  }
}

void dayLight()
{
  digitalWrite(gLEDpin, 0);
  digitalWrite(bLEDpin, 0);
  digitalWrite(rLEDpin, 255);
}




void sunSet()
{
        unsigned long now = millis();
   if(now - lastChange > 100) 
   {
      fadeDown --; 
      fadeUp ++;
      fadeDown = constrain(fadeDown, 255, 0);
      fadeUp = constrain(fadeUp, 0, 255);
      analogWrite(rLEDpin, fadeDown);
      analogWrite(bLEDpin, fadeUp);
      analogWrite(gLEDpin, 0); 
      lastChange = now; 

    }
}    

void twilight()
{
  digitalWrite(bLEDpin, 255);
  digitalWrite(rLEDpin, 0);
  digitalWrite(gLEDpin, 0);
}

void twilightSet()
{
        unsigned long now = millis();
   if(now - lastChange > 100) 
   {
      fadeDown --; 
      fadeUp ++;
      fadeDown = constrain(fadeDown, 255, 0);
      fadeUp = constrain(fadeUp, 0, 255);
      analogWrite(rLEDpin, 0);
      analogWrite(bLEDpin, fadeDown);
      analogWrite(gLEDpin, 0);
      lastChange = now; 


      }
}

void night()
{
  digitalWrite(bLEDpin, 0);
  digitalWrite(rLEDpin, 0);
  digitalWrite(gLEDpin, 0);
}

 void readtime()
 {
  // Below required to reset the register address to 0.
  Wire.beginTransmission(104); // transmit to device #104, the ds 1307
  Wire.write(0x00);
  Wire.endTransmission();    // stop transmitting
 
  Wire.requestFrom(104, 7);    // request 7 bytes from slave ds1307, we'll assume it'll send them all even though it doesn't have to
  second = Wire.read(); 
  minute = Wire.read(); 
  hour = Wire.read(); 
  day_of_week=Wire.read(); 
  day = Wire.read(); 
  month = Wire.read(); 
  year = Wire.read(); 

  hour=hour/16 * 10 + hour % 16;
  minute=minute/16 * 10 + minute % 16;
  second=second/16 * 10 + second % 16;
  day=day/16 * 10 + day % 16;
  month=month/16 * 10 + month % 16;
  year=year/16 * 10 + year % 16;
}
 
  void printSerial()
 {
  Serial.print(hour);
  Serial.print(":");
  if (minute < 10) { Serial.print("0"); }
  Serial.print(minute);
  Serial.print(":");
  if (hour < 12) { Serial.print("am"); }
  if (hour > 12) { Serial.print("pm"); }
  
  Serial.print(" ");
  Serial.print(dow[day_of_week-1]);  // array is 0-6, but the dow register holds 1-7, so subtract 1.
  Serial.print(" ");
  Serial.print(month);
  Serial.print("/");
  Serial.print(day);
  Serial.print("/");
  Serial.print(year);
  Serial.print("\n");
 }
 
   void printLCD()
  {
    lcd.home ();   
  if (hour <= 9) {lcd.print("0"); }
  if (hour > 12 && hour < 22) {lcd.print("0"); }
  if (hour <= 12) {lcd.print(hour); }
  if (hour > 12) { lcd.print(hour - 12); }
    
  lcd.print(":");
  if (minute < 10) { lcd.print("0"); }
  lcd.print(minute);
  if (hour < 12) { lcd.print("am"); }
  if (hour >= 12) { lcd.print("pm"); }
  lcd.setCursor (8,0);
  lcd.print(dow[day_of_week-1]);  // array is 0-6, but the dow register holds 1-7, so subtract 1.
  lcd.setCursor (12,0);
  lcd.print(day);
  lcd.print("/");
  if (month < 10) { lcd.print("0"); }
  lcd.print(month);
  lcd.print("/");
  lcd.print(year);
  }

I just set the sunrise time to 2 mins into the future, then the others either 1 or 2 mins after that. After i upload the sketch, the blue led comes on. Then as it hits sunrise, the blue stays on and the red blinks at various spacings. it seems to stay like that, and the time locks up on the display. When i hit the reset button, the blue led comes on again, and the red led fade on no mater what the time is! clock starts to read on lcd correct again tho?

kr
craig

  if ((hour >= sunRiseHour) && (minute >= sunRiseMin) && !sunRiseFading)
  {
     sunRiseFading = true;
     lastChange = 0;
     fadeUp = 0;
  }

Did this happen at the right time? Serial.print("It's sunrise!"); in the block to KNOW.

  if ((hour > dayHour) && (minute > dayMin) && sunRiseFading)
  {
     sunRiseFading = false;
     lastChange = 0;
  }

Did this happen at the right time?

   if(now - lastChange > 100) 
   {
      fadeUp ++; 
      fadeUp = constrain(fadeUp, 0, 255);
      analogWrite(rLEDpin, fadeUp);
      analogWrite(bLEDpin, 0);
      analogWrite(gLEDpin, 0);
      lastChange = now; 
    
  }

Same question. Does this happen only every 10th of a second? By the way, this will ramp the LED up in 2.5 seconds, not the two minutes you allocated for sunrise.

will add those lines in now, give me 10 mins!

it will ramp the led up in 25.5 seconds wont it, 255 * 100 = 25500 / 1000 = 25.5 seconds!

let me add the serial prints in, for this check i will delete the serial print time out of the code.

Strange why the blue is always on?

be right back