Hello all, I came across this nifty code for PWM dimming a sunrise and sunset but it is pretty basic and Id like to add some simulated cloud cover throughout the day as well as the ability to change the sunrise and sunset times with some buttons and possibly a test button that will fade all the channels from their current state down to 0 then up to 100% and back to their previous state in like 30-60 seconds.
here is the main code I'm starting with:
const int kChan0Pin = 9; // Channel 0 Pin
const int kChan1Pin = 10; // Channel 1 Pin
// All times are in seconds since midnight (valid 0 - 86399)
const long kTurnOn = 32400; // time dawn begins - 0900hrs
const long kTurnOff = 75600; // time sunset begins - 2100hrs
/*
* Light "state" represents the PWM duty cycle for each channel This normally
* dictates light intensity. It is an array { duty_chan_1, duty_chan_2 }.
* Possible values for duty cycle are 0 - 1023.
*/
const int kDayState[] = { 600, 400 }; // daytime LED state
const int kNightState[] = { 0, 0 }; // nighttime LED state
/*
* Duration (in seconds) of fade. At the moment the only fades are sunrise and
* sunset but this value will apply to any other fades you came up with
*/
const long kFadeDuration = 3600; // 60 minutes
long ctr;
/* hold state info */
int state_chan1, state_chan2;
/*
* fader -- Determine output state for a given time to provide smooth fade from
* one state to another.
* Args:
* start_time -- time (in seconds) of start of fade
* start_state -- beginning state
* end_state -- ending state
* out -- array to update with state
*/
void fader(long start_time, const int start_state[], const int end_state[], int out[2]) {
float per_second_delta_0 = (float) (end_state[0]-start_state[0])/kFadeDuration;
float per_second_delta_1 = (float) (end_state[1]-start_state[1])/kFadeDuration;
long elapsed = ctr-start_time;
out[0] = start_state[0] + per_second_delta_0 * elapsed;
out[1] = start_state[1] + per_second_delta_1 * elapsed;
}
// return seconds elapsed since midnight
long seconds_since_midnight() {
time_t t = now();
long hr = hour(t);
long min = minute(t);
long sec = second(t);
long total = hr * 3600 + min * 60 + sec;
return total;
}
// set output state
void set_state(const int state[]) {
if (state[0] >= 0 && state[0] <= 1023) {
Timer1.setPwmDuty(kChan0Pin, state[0]);
state_chan1 = state[0]; }
if (state[1] >= 0 && state[1] <= 1023) {
Timer1.setPwmDuty(kChan1Pin, state[1]);
state_chan2 = state[1]; }
}
/*
* determine_state -- This is where the actual timing logic resides. We
* examine ctr (seconds since midnight) and then set output state accordingly.
* Variable ctr rolls back to 0 at midnight so stages that cross midnight (ie:
* nighttime) are broken up into two stages.
*/
void determine_state() {
if ( ctr >= 0 && ctr < kTurnOn ) { // night
set_state(kNightState);
} else if ( ctr >= kTurnOn && ctr <= (kTurnOn+kFadeDuration) ) { // sunrise
int foo[2];
fader(kTurnOn, kNightState, kDayState, foo);
set_state(foo);
} else if ( ctr > (kTurnOn+kFadeDuration) && ctr < kTurnOff ) { // day
set_state(kDayState);
} else if ( ctr >= kTurnOff && ctr <= (kTurnOff+kFadeDuration) ) { // sunset
int foo[2];
fader(kTurnOff, kDayState, kNightState, foo);
set_state(foo);
} else if ( ctr > (kTurnOff+kFadeDuration) && ctr < 86400 ) { // night
set_state(kNightState);
}
}
First, coding in the ability to set the sun rise/set times. As far as the buttons go I have some code from an RTC timer sketch:
//You need 4 buttons like this,to enter the set points, with 10K resistor to ground (for each one)
const int DOWN_BUTTONon =3; //Buttons Pins
const int UP_BUTTONon =4;
const int DOWN_BUTTONoff =5;
const int UP_BUTTONoff =6;
//-----Variables for debouncing------//
boolean lastDownONButton = LOW;
boolean currentDownONButton = LOW;
boolean lastUpONButton = LOW;
boolean currentUpONButton = LOW;
boolean lastDownOFFButton = LOW;
boolean currentDownOFFButton = LOW;
boolean lastUpOFFButton = LOW;
boolean currentUpOFFButton = LOW;
int set_on = 12; //The default "ON" desired time
int set_off= 12; //The default "OFF" desired time
How do I work this into the sketch? Can I tell it that int set_on is const long kTurnOn and int set_off is const long kTurnOff?
Secondly, the matter of stimulating clouds. Can I just add cloud states to day and night like this?
const int kDayState[] = { 900, 900 }; // daytime LED state 88% light
const int kNightState[] = { 0, 0 }; // nighttime LED state 0 % light
const int kCloudState1[] = {780,780}; // light clouds 76% light
const int kCloudState2[] = {675,675}; // medium clouds 66% light
const int kCloudState3[] = {580,580}; // dark clouds 56% light
Then, how do I define the logic to choose which state and when? I was thinking something along the lines of the random() function; How can I tell it between sunrise and sunset to pick 4 random times to fade to a random cloud state?
Lastly, how can I tell it to interrupt the current state at the push of a button to sweep from current state down to {0,0} then up to {1000,1000} and back to its current state? can I add a const int kTestState[]; ?
I know I'm a beginner at this and asking alot of questions, so I appreciate anyone with the patience to help, i'm having a hard time finding tutorials with my exact needs