Skip to content

Instantly share code, notes, and snippets.

@coza73
Created April 7, 2020 09:08
Show Gist options
  • Save coza73/3b9c645578f4b4c8723af891d09da2c3 to your computer and use it in GitHub Desktop.
Save coza73/3b9c645578f4b4c8723af891d09da2c3 to your computer and use it in GitHub Desktop.
//************* Wol Clock by Jon Fuge ******************************
// https://www.instructables.com/id/Wol-Clock-ESP8266-12E-60-LED-WS2812B-Analogue-Digi/
//************* Declare included libraries ******************************
#include <NTPClient.h>
#include <Time.h>
#include <TimeLib.h>
#include <Adafruit_NeoPixel.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <Timezone.h> // https://github.com/JChristensen/Timezone
// Australian Eastern Time Zone
TimeChangeRule mySTD = {"AEST", First, Sun, Apr, 3, 600}; // Standard time = UTC + 10 hours (hours offset is in minutes)see https://github.com/JChristensen/Timezone
TimeChangeRule myDST = {"AEDT", First, Sun, Oct, 2, 660}; // Daylight time = UTC + 11 hours (hours offset is in minutes) see https://github.com/JChristensen/Timezone
Timezone myTZ(myDST, mySTD);
TimeChangeRule *tcr; // pointer to the time change rule, use to get TZ abbrev
//************* Declare structures ******************************
//Create structure for LED RGB information
struct RGB {
byte r, g, b;
};
//Create structure for time information
struct TIME {
byte Hour, Minute;
};
//************* Editable Options ******************************
//The colour of the "12" to give visual reference to the top
const RGB Twelve = { 0, 0, 192 }; //purple
//The colour of the "quarters" 3, 6 & 9 to give visual reference
const RGB Quarters = { 0, 0, 128 }; //purple
//The colour of the "divisions" 1,2,4,5,7,8,10 & 11 to give visual reference
const RGB Divisions = { 0, 0, 64 }; //purple
//All the other pixels with no information
const RGB Background = { 0, 0, 8 };//blue
//The Hour hand
const RGB Hour = { 192, 0, 0 };//orange maximum
//The Minute hand
const RGB Minute = { 64, 0, 0 };//orange medium
//The Second hand
const RGB Sec = { 0, 64, 0 };//orange dim
// Make clock go forwards or backwards dependant on hardware and how you wire up the pixels
const char ClockGoBackwards = 1;
//Set your wifi details so the board can connect and get the time from the internet
const char *ssid = "ssid"; // your network SSID (name)
const char *password = "password"; // your network password
byte SetClock;
// By default 'time.nist.gov' is used.
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
// Which pin on the ESP8266 is connected to the NeoPixels?
#define PIN 14 // This is the D5 pin
#define ledONOFF LOW
//************* Declare user functions ******************************
void Draw_Clock(time_t t, byte Phase);
int ClockCorrect(int Pixel);
void SetClockFromNTP ();
bool IsDst();
String displaytime;
// Filter averaging factor - higher value means more sluggish response to changes in ambient brightness
#define FILTER_LEN 4
// Brightness level initial value
int level=15;
unsigned int ldr=0;
time_t old = now();
//************* Declare NeoPixel ******************************
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
//************* Setup function for Wol_Clock ******************************
void setup() {
Serial.begin(115200);
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
pinMode(LED_BUILTIN, OUTPUT);
pixels.begin(); // This initializes the NeoPixel library.
pixels.clear();
Draw_Clock(0, 0); // Just draw a blank clock
Draw_Clock(0, 0); // Draw the clock background
WiFi.begin(ssid, password); // Try to connect to WiFi
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Draw_Clock(0, 3); // Add the quater hour indicators
SetClockFromNTP(); // get the time from the NTP server with timezone correction
}
void SetClockFromNTP ()
{
timeClient.update(); // get the time from the NTP server
setTime(timeClient.getEpochTime()); // Set the system yime from the clock
}
//************* Main program loop for Wol_Clock ******************************
void loop() {
//time_t t = now();
// Get the current time
time_t utc = now();
// Adjust time to timezone plus daylight if nessessary
time_t t = myTZ.toLocal(utc, &tcr);
//get light level every second and blink builtin led
if (second(t)!=second(old)) {
old = t;
int level = doLDR();
pixels.setBrightness(level);
if ((digitalRead(LED_BUILTIN)) == LOW) {
digitalWrite(LED_BUILTIN, HIGH);
//ledONOFF == HIGH;
//Serial.println("LED Off");
}
else {
digitalWrite(LED_BUILTIN, LOW);
//ledONOFF == LOW;
//Serial.println("LED On");
}
Serial.print(hour(t));
Serial.print(":");
Serial.print(minute(t));
Serial.print(":");
Serial.println(second(t));
}
Draw_Clock(t, 4); // Draw the whole clock face with hours minutes and seconds
if (minute(t) == 0) // at the start of each hour, update the time from the time server
if (SetClock == 1)
{
SetClockFromNTP(); // get the time from the NTP server with timezone correction
SetClock = 0;
}
else
{
delay(200); // Just wait for 0.1 seconds
SetClock = 1;
}
}
//************* Functions to draw the clock ******************************
void Draw_Clock(time_t t, byte Phase)
{
if (Phase <= 0)
for (int i = 0; i < 60; i++)
pixels.setPixelColor(i, pixels.Color(0, 0, 0)); // for Phase = 0 or less, all pixels are black
if (Phase >= 1)
for (int i = 0; i < 60; i++)
pixels.setPixelColor(i, pixels.Color(Background.r, Background.g, Background.b)); // for Phase = 1 or more, draw minutes with Background colour
if (Phase >= 2)
for (int i = 0; i < 60; i = i + 5)
pixels.setPixelColor(i, pixels.Color(Divisions.r, Divisions.g, Divisions.b)); // for Phase = 2 or more, draw 5 minute divisions
if (Phase >= 3) {
for (int i = 0; i < 60; i = i + 15)
pixels.setPixelColor(ClockCorrect(i), pixels.Color(Quarters.r, Quarters.g, Quarters.b)); // for Phase = 3 or more, draw 15 minute divisions
pixels.setPixelColor(ClockCorrect(0), pixels.Color(Twelve.r, Twelve.g, Twelve.b)); // for Phase = 3 and above, draw 12 o'clock indicator
}
if (Phase >= 4) {
pixels.setPixelColor(ClockCorrect(second(t)), pixels.Color(Sec.r, Sec.g, Sec.b)); // draw the second hand first
if (second() % 2)
pixels.setPixelColor(ClockCorrect(minute(t)), pixels.Color(Minute.r, Minute.g, Minute.b)); // to help identification, minute hand flshes between normal and half intensity
else
pixels.setPixelColor(ClockCorrect(minute(t)), pixels.Color(Minute.r / 2, Minute.g / 2, Minute.b / 2)); // lower intensity minute hand
pixels.setPixelColor(ClockCorrect(((hour(t) % 12) * 5) + minute(t) / 12), pixels.Color(Hour.r, Hour.g, Hour.b)); // draw the hour hand last
}
pixels.show(); // show all the pixels
}
int doLDR() {
unsigned int ldr_value = analogRead(0); //reads the LDR values
//ldr follows ldr_value, but is averaged so that values only change gradually
ldr = ((unsigned long)(FILTER_LEN-1)*ldr+ldr_value)/FILTER_LEN;
unsigned int light_level=0;
// Convert LDR analog value to Pixel brigtness level
light_level=map(ldr,0,1023,255,0);
// Set Maximum and minimum brightness levels. Partly to stop devide by zero errors
if (light_level >= 255) light_level = 255;
if (light_level <= 20) light_level = 20;
//DEBUG SPI
//*
Serial.println();
Serial.print("ldr_value [0-1023]:");
Serial.println(ldr_value);
Serial.print("ldr:");
Serial.println(ldr);
Serial.print("light_level:");
Serial.println(light_level);
Serial.println();
// */
return light_level;
}
//************* This function reverses the pixel order ******************************
int ClockCorrect(int Pixel)
{
if (ClockGoBackwards == 1)
return ((60 - Pixel +30) % 60); // my first attempt at clock driving had it going backwards :)
else
return (Pixel);
}
@coza73
Copy link
Author

coza73 commented Apr 7, 2020

clock_schem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment