#include <WiFi.h>
#include "time.h"
#include <Adafruit_NeoPixel.h>
#include "SPI.h"
unsigned long miliStart;
byte TMRsecs;
byte TMRmins;
byte TMRhrs;
byte NTPrefresh=60; //how many mins before we request the NTP time again.
byte doNTPRefresh;
byte minPins[4]={26,27,25,33};
const char * ssid="Wokwi-GUEST";
const char * wifipw="";
// ------------------74HC595 SIPO LED Driver---------------
// Which pin on the Arduino is connected to the NeoPixels?
#define NEO_PIN 21 // On Trinket or Gemma, suggest changing this to 1
#define NUMPIXELS 12 // Popular NeoPixel ring size
Adafruit_NeoPixel pixels(NUMPIXELS, NEO_PIN, NEO_GRB + NEO_KHZ800);
void setTimezone(String timezone){
Serial.printf(" Setting Timezone to %s\n",timezone.c_str());
setenv("TZ",timezone.c_str(),1); // Now adjust the TZ. Clock settings are adjusted to show the new local time
tzset();
}
void initTime(String timezone){
struct tm timeinfo;
Serial.println("Setting up time");
configTime(0, 0, "pool.ntp.org"); // First connect to NTP server, with 0 TZ offset
if(!getLocalTime(&timeinfo)){
Serial.println(" Failed to obtain time");
return;
}
Serial.println(" Got the time from NTP");
// Now we can set the real timezone
setTimezone(timezone);
}
void getNTPTime(){
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time 1");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S zone %Z %z FROM NTP");
TMRhrs=timeinfo.tm_hour; // Set time
TMRmins=timeinfo.tm_min;
TMRsecs=timeinfo.tm_sec;
}
void startWifi(){
WiFi.begin(ssid, wifipw);
Serial.println("Connecting Wifi");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.print("Wifi RSSI=");
Serial.println(WiFi.RSSI());
}
void setTime(int yr, int month, int mday, int hr, int minute, int sec, int isDst){
struct tm tm;
tm.tm_year = yr - 1900; // Set date
tm.tm_mon = month-1;
tm.tm_mday = mday;
tm.tm_hour = hr; // Set time
tm.tm_min = minute;
tm.tm_sec = sec;
tm.tm_isdst = isDst; // 1 or 0
time_t t = mktime(&tm);
Serial.printf("Setting time: %s", asctime(&tm));
struct timeval now = { .tv_sec = t };
settimeofday(&now, NULL);
TMRhrs=tm.tm_hour; // Set time
TMRmins=tm.tm_min;
TMRsecs=tm.tm_sec;
}
void setup(){
int lp;
Serial.begin(115200);
Serial.setDebugOutput(true);
for (lp=0;lp<4;lp++) {
pinMode(minPins[lp],OUTPUT);
}
startWifi();
initTime("GMT0BST,M3.5.0/1,M10.5.0"); // Set for London UK
getNTPTime(); //Setup the time
miliStart=millis(); //Flag for screen / LED refresh
doNTPRefresh=false;
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
pixels.clear(); // Set all pixel colors to 'off'
//setTime(2023, 7, 4, 20, 40, 35, 1);
}
void loop() {
int hour_d;
int min_d;
int min_r;
int secs_d;
int h_sat;
int m_sat;
int s_sat;
boolean showSecs;
boolean showMins;
// uint32_t h_RGB = strip.ColorHSV(hue, saturation, value);
// uint32_t clrRed = pixels.ColorHSV(0, 255, 255); //red
// uint32_t clrBlue = pixels.ColorHSV(43690, 255, 255); //blue
// uint32_t clrWhite= pixels.ColorHSV(43690, 0, 255); //white
// uint32_t clrPurple = pixels.ColorHSV(54613, 255, 255); //Purple
// uint32_t clrPurpleLight = pixels.ColorHSV(54613, 170, 255); //Purple
uint32_t clrHrs;
uint32_t clrMins;
uint32_t clrSecs;
uint32_t clrAll;
h_sat=255;
m_sat=255;
s_sat=255;
//lets say that saturation is 255 (eg full), when the seconds are merged also, it is halved.
if (millis() > miliStart+1000) {
TMRsecs++;
if (TMRsecs>59) {
TMRsecs=0;
TMRmins++;
doNTPRefresh=(TMRmins>=NTPrefresh);
if (TMRmins>59) {
TMRmins=0;
TMRhrs++;
if (TMRhrs>12) {
TMRhrs=0;
}
}
}
Serial.println(String(TMRhrs)+":"+String(TMRmins)+":"+String(TMRsecs));
hour_d = TMRhrs%12;
min_d = TMRmins/5;
min_r = TMRmins%5;
secs_d=TMRsecs/5;
showSecs=true;
showMins=true;
//Set the default colours
clrHrs=0; //red
clrMins=43690; //blue
clrSecs=43690; //blue but will have saturation=0
if (secs_d==min_d) {
m_sat=128;
showSecs=false;
}
if (secs_d==hour_d) {
h_sat=128;
showSecs=false;
}
if (min_d==hour_d) {
clrHrs=54613; //Purple
showMins=false;
}
pixels.clear();
clrAll=pixels.ColorHSV(clrHrs, h_sat, 255);
pixels.setPixelColor(hour_d, clrAll); //we always show the hours
if (showMins==true) {
clrAll=pixels.ColorHSV(clrMins, m_sat, 255);
pixels.setPixelColor(min_d, clrAll); //mins in blue
}
if (showSecs==true) {
clrAll=pixels.ColorHSV(clrSecs, 0, 255);
pixels.setPixelColor(secs_d, clrAll);
}
showModMins(min_r);
pixels.show();
miliStart=millis();
}
if (doNTPRefresh) {
getNTPTime(); //this just tightens up the timers every hour (or so)
}
}
void showModMins(int mins) {
int lp;
int LEDval=0;
Serial.print("mins="+String(mins));
for(lp=1;lp<5;lp++) {
LEDval=(mins>=lp);
digitalWrite(minPins[lp-1],LEDval);
Serial.print(" "+String(LEDval));
}
Serial.println();
}