#include <RTClib.h>
#include <Adafruit_NeoPixel.h>
#define PIN 9 // On Trinket or Gemma, suggest changing this to 1
// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 16 // Popular NeoPixel ring size
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
RTC_DS1307 rtc;
const int strategy_none = -1;
const int strategy_night = 0; // 23 to 5
const int strategy_morning = 1; // 5 to 8am
const int strategy_daylight = 2; // 8 to 6 pm
const int strategy_dusk = 3; // 6 pm to 9 pm
const int strategy_evening = 4; // 9pm to 11pm blended
const int night_starts = 23;
const int dusk_end = night_starts;
const int dusk_start = 21;
const int evening_starts = 17;
const int day_starts = 9;
const int morning_starts = 7;
const int slide_steps = 30;
const int slider_max = 1024;
const int time_to_hold_new_value_in_seconds = 5;
bool in_slide = false;
int strategy = strategy_night;
int previous_strategy = strategy_none;
int light_step = 0;
int previous_light_step = -1;
int last_R = 0;
int last_G = 0;
int last_B = 0;
const int max_evening_steps = (dusk_end - dusk_start) * 60 * 60;
int last_slider = -1;
float current_dimming = -1;
int seconds_till_release = -1;
// #define warm_white = #FDF4DC;
void setup() {
Serial.begin(9600);
//Serial.println("Compilation time: ");
//rtc.adjust(DateTime(F(__DATE__), F("15:59:50")));
// SETUP RTC MODULE
if (!rtc.begin()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
} else {
// Set for debugging purposes
//rtc.adjust(DateTime(2022, 11, 11, day_starts-1, 59, 57));
}
pixels.begin();
pixels.clear(); // Set all pixel colors to 'off'
}
void setLightColors(int R, int G, int B) {
if(current_dimming!=1) {
//Serial.print("current dimming:");
//Serial.print(current_dimming);
R = (int)(((float)R)*current_dimming);
G = (int)(((float)G)*current_dimming);
B = (int)(((float)B)*current_dimming);
}
if ((R != last_R) || (G != last_G) || (B != last_B)) {
Serial.print("R:");
Serial.print(R);
Serial.print(" G:");
Serial.print(G);
Serial.print(" B:");
Serial.println(B);
for (int i = 0; i < NUMPIXELS; i++) { // For each pixel...
pixels.setPixelColor(i, pixels.Color(R, G, B));
}
pixels.show();
last_R = R;
last_G = G;
last_B = B;
}
}
void loop() {
DateTime now = rtc.now();
int hour = now.hour();
int minute = now.minute();
int seconds = now.second();
int slider_signal = analogRead(A0);
//Serial.println(slider_signal);
float slider_dimming_value = (float)slider_signal/(float)slider_max;
if(last_slider==-1) last_slider = slider_signal; // initialize
if(seconds_till_release<0) current_dimming = 1;
if(slider_signal!=last_slider) {
// we have slider movement! set the current dimming and timer for release back to normal
current_dimming = slider_dimming_value;
seconds_till_release = time_to_hold_new_value_in_seconds;
last_slider = slider_signal;
}
if(seconds_till_release>=0) seconds_till_release -=1;
if ((hour >= morning_starts) && (hour < day_starts)) {
strategy = strategy_morning;
} else if ((hour >= day_starts) && (hour < evening_starts)) {
strategy = strategy_daylight;
} else if ((hour >= evening_starts) && (hour < dusk_start)) {
strategy = strategy_evening;
} else if ((hour >= dusk_start) && (hour < dusk_end)) {
strategy = strategy_dusk;
} else strategy = strategy_night;
//strategy = strategy_night;
/*Serial.print("Date & Time: ");
Serial.print(hour, DEC);
Serial.print(':');
Serial.print(minute, DEC);
Serial.print(':');
Serial.println(seconds, DEC);*/
if ((previous_strategy != strategy) || (light_step != previous_light_step)) {
if (strategy == strategy_daylight) {
if ((minute == 0) && (seconds < slide_steps)) {
float percentage = (float)(seconds) / float(slide_steps);
setLightColors(0xFD + (int)round(percentage * (0xFF - 0xFD)), 0xF4 + (int)round(percentage * (0xFF - 0xF4)), 0xDC + (int)round(percentage * (0xFF - 0xDC)));
} else {
setLightColors(255, 255, 255);
}
} else if (strategy == strategy_morning) {
if ((minute == 0) && (seconds < slide_steps)) {
float percentage = (float)(seconds) / float(slide_steps);
setLightColors(0xFF - (int)round(percentage * (0xFF - 0xFD)), (int)round(percentage * 0xF4), (int)round(percentage * 0xDC));
} else {
setLightColors(0xFD, 0xF4, 0xDC);
}
} else if (strategy == strategy_night) {
// No slide necessary
setLightColors(0xFF, 0x00, 0x00);
} else if (strategy == strategy_evening) {
if ((hour == evening_starts) && (minute == 0) && (seconds < slide_steps)) {
float percentage = (float)(seconds) / float(slide_steps);
setLightColors(0xFF - (int)round(percentage * (0xFF - 0xFD)), 0xFF - (int)round(percentage * (0xFF - 0xF4)), 0xFF - (int)round(percentage * (0xFF - 0xDC)));
} else {
setLightColors(0xFD, 0xF4, 0xDC);
}
}
else if (strategy == strategy_dusk) {
light_step = (hour - dusk_start) * 60 * 60 + minute * 60 + now.second();
previous_light_step = light_step - 1;
float percentage = (float)light_step / (float)max_evening_steps;
setLightColors(0xFD + (int)round((0xFF - 0xFD) * percentage), 0xF4 - (int)round(0xF4 * percentage), 0xDC - (int)round(0xDC * percentage));
}
previous_strategy = strategy;
}
delay(1000); // delay 1 seconds
}