#include <FastLED.h>
uint32_t timeToSecs(float hour, uint8_t minute=0, uint8_t sec =0){
uint32_t seconds = hour * 60 * 60;
seconds += minute * 60;
seconds += sec;
return seconds;
}
CRGB sunRiseColor(uint8_t currentTimeRatio8){
byte hue1 = 160;
byte hue2 = 255;
byte hue3 = lerp8by8(hue1,hue2,currentTimeRatio8);
byte saturation = sin8((currentTimeRatio8/2)-192);
saturation -= 255; //flip over;
// for (int i = 0; i < 600; i++) { printf("%i , %i \n" , i, sin8(i));delay(100); }
CRGB rgb = CHSV(hue3, saturation, currentTimeRatio8);
printf(" %i , %i , %i \n" , rgb.r, rgb.g ,rgb.b);
return rgb;
}
#define DATA_PIN 5
//#define CLK_PIN 4
#define LED_TYPE WS2812
#define COLOR_ORDER GRB
#define NUM_LEDS 6
CRGB leds[NUM_LEDS];
//#define BRIGHTNESS 96
//#define FRAMES_PER_SECOND 120
#include <WiFi.h>
#include "time.h"
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = -3600*7;
const int daylightOffset_sec = 3600;
#include <FastLED.h>
class SunriseAlarm {
private:
float _sunrise8ratio;
public:
uint32_t startTime_sec;
uint32_t riseTime_sec;
uint32_t holdTime_sec;
bool isAlarmActive =0;
void setSunrise(uint32_t start_sec, uint32_t riseLength_sec, uint32_t hold_sec){
startTime_sec = start_sec;
riseTime_sec = riseLength_sec;
holdTime_sec = hold_sec;
_sunrise8ratio = (float)256/(float)riseTime_sec;
// printf("riseTime_sec = %i\n" , riseTime_sec);
// printf("_sunrise8ratio = %f\n" , _sunrise8ratio);
}
uint8_t getSunriseRatio8(uint32_t currentTime_sec){
// printf(" sunriseRatio8 currentTime = %i \n" ,currentTime_sec );
//if time is not above start time check if alarm wraps around 2400hrs
if(currentTime_sec < startTime_sec){ currentTime_sec += 3600 * 24;}
// printf("check wrap around time %i :: %i\n" , currentTime_sec , startTime_sec + riseTime_sec);
if(currentTime_sec > startTime_sec && currentTime_sec <= startTime_sec + riseTime_sec ){
//inside riseTime
// printf("rising time %f \n", (currentTime_sec-startTime_sec)*_sunrise8ratio );
isAlarmActive = true;
return (currentTime_sec-startTime_sec)*_sunrise8ratio;
}else if(currentTime_sec > startTime_sec + riseTime_sec && currentTime_sec < startTime_sec + riseTime_sec +holdTime_sec){
//inside hold time
// printf("hold time \n" );
isAlarmActive = true;
return 255;
}else{
isAlarmActive = false;
return 0;}
}
};
void sunriseOutput(tm &timeinfo, SunriseAlarm &sunriseAlarm);
//not going to Use
//going to try with just rtc clock
class TimeMillis{
public:
int32_t offset_millis; //not sure if I need signed or unsigned or if it even matters
float timeCorrection = 1.0;
uint32_t lastTime_sec;
uint32_t lastTime_millis;
void setMillisOffset(uint32_t currentTime_sec){
offset_millis = currentTime_sec*1000-millis();
}
void setTimeCorrection(uint32_t currentTimeWeb_sec, uint64_t currentTime_millis ){
// currentTime_millis += 500; //add half to prevent over rounding down.
// currentTime_millis /= 1000;
if(lastTime_sec != 0){
//because we are working with 2 differen't
if(lastTime_sec > currentTimeWeb_sec){ currentTimeWeb_sec += 3600*24; }//add a whole day if clock rolls over
// if(lastTime_millis > currentTime_millis){ currentTime_millis += 0xffffffff; }//add 4bytes if clock rolls over
float elapsedWebMilli = (currentTimeWeb_sec - lastTime_sec)*1000;
float elapsedInternalTimeMilli = currentTime_millis - lastTime_millis; //add half to prevent over rounding down.
timeCorrection = elapsedWebMilli / elapsedInternalTimeMilli;
lastTime_sec = currentTimeWeb_sec;
lastTime_millis = currentTime_millis;
}else{
lastTime_sec = currentTimeWeb_sec;
lastTime_millis = currentTime_millis;
}
}
};
SunriseAlarm sunriseAlarm;
TimeMillis timeMillis;
// struct tm timeinfo;
tm timeinfo;
void setup()
{
Serial.begin(115200);
pinMode(27, OUTPUT);
sunriseAlarm.setSunrise(timeToSecs(3,10), timeToSecs(0,10), timeToSecs(0,3) ); //start , riseTime, holdOnTime
// printf(" alarm Start time %i = \n", timeToSecs(23,28) );
// printf(" alarm top time %i = \n", timeToSecs(23,28) + timeToSecs(0,1) );
FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
//connect to WiFi
getTimeFromWeb();
sunriseOutput(timeinfo, sunriseAlarm);
}
//uint8_t x=0;
bool refreshTime = false;
void loop()
{
// printLocalTime();
Serial.println("loop");
///rainbow();
// x+=5;
// uint8_t timeRatio8 = sunriseAlarm.getSunriseRatio8(timeToSecs(timeinfo.tm_hour,timeinfo.tm_min,timeinfo.tm_sec) );
sunriseOutput( timeinfo,sunriseAlarm);
digitalWrite(27, sunriseAlarm.isAlarmActive); // turn the LED on (HIGH is the voltage level)
if(timeinfo.tm_min == 16 && refreshTime){
refreshTime = false;
getTimeFromWeb();
}else if(timeinfo.tm_min != 16){
refreshTime = true;
}
delay(1000);
}
void rainbow() {
// FastLED's built-in rainbow generator
fill_rainbow( leds, NUM_LEDS, 20, 10);
}
void getTimeFromWeb(){
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED");
//init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime();
//disconnect WiFi as it's no longer needed
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
}
void printLocalTime(){
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println();
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
Serial.println(timeinfo.tm_sec);
timeMillis.setMillisOffset(timeToSecs(timeinfo.tm_hour,timeinfo.tm_min,timeinfo.tm_sec));
Serial.println(timeMillis.offset_millis);
}
void sunriseOutput(tm &timeinfo, SunriseAlarm &sunriseAlarm){
if(!getLocalTime(&timeinfo)){
Serial.println();
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
// Serial.println(timeinfo.tm_sec);
printf(" time to second = %i \n" , timeToSecs(timeinfo.tm_hour,timeinfo.tm_min,timeinfo.tm_sec));
uint8_t x = sunriseAlarm.getSunriseRatio8(timeToSecs(timeinfo.tm_hour,timeinfo.tm_min,timeinfo.tm_sec));
CRGB color1 = sunRiseColor(x);
printf("sunrise progress = %i \n" , x);
for (int i = 0; i < NUM_LEDS; i++) { leds[i] = color1; }
FastLED.show();
//not trying
//timeMillis.setMillisOffset(timeToSecs(timeinfo.tm_hour,timeinfo.tm_min,timeinfo.tm_sec));
//Serial.println(timeMillis.offset_millis);
}