diff --git a/LICENSE b/LICENSE index f7007f3..3e6713a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,25 +1,27 @@ -This program is free software; you can redistribute it and/or modify it under the terms of the Do What Thou Wilt License. + This source code is released under the DWTW license. -Boundless Public License -DO WHAT THOU WILT -TO PUBLIC LICENSE + This program is free software; you can redistribute it and/or modify it under the terms of the Do What Thou Wilt License. -Version 2.55 + Boundless Public License + DO WHAT THOU WILT + TO PUBLIC LICENSE -Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it in full or in part is allowed without any restrictions. + Version 2.55 -TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it in full or in part is allowed without any restrictions. -0. Do what thou wilt shall be the whole of the Law. + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -DWTWL – a license with a single requirement: DO WHAT THOU WILT + 0. Do what thou wilt shall be the whole of the Law. -The license provides more freedom than any other one (such as GPL or BSD) and does not require saving the license text on copying. + DWTWL – a license with a single requirement: DO WHAT THOU WILT -DWTWL – an accomplished and eligible license for free text, code and any other symbols (including the software, documentation and artwork). + The license provides more freedom than any other one (such as GPL or BSD) and does not require saving the license text on copying. -The license does not contain a "no warranty" clause. DWTWL can be used in countries that do not legally acknowledge the transition to public domain. + DWTWL – an accomplished and eligible license for free text, code and any other symbols (including the software, documentation and artwork). -Summary: + The license does not contain a "no warranty" clause. DWTWL can be used in countries that do not legally acknowledge the transition to public domain. -An author-creator gives their source code to the world for free, without becoming distracted by worldly thinking regarding how and why the others will use it. + Summary: + + An author-creator gives their source code to the world for free, without becoming distracted by worldly thinking regarding how and why the others will use it. \ No newline at end of file diff --git a/README.md b/README.md index 6fd6349..f60460e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,11 @@ -# dclock +# Erisian digital clock -Digital erisian clock \ No newline at end of file +By default, it shows the erisian time (hours:minutes). Pressing the button temporary changes the mode to: erisian time (minutes:seconds), date (season and day), day of week, yold. + +Used hardware modules: DS1307 Real Time Clock and TM1637 Digit Display + +Check timezoneOffset variable for your local timezone. + +https://discordia.fandom.com/wiki/Erisian_Time + +![dclock](https://dev.ussr.win/zlax/dclock/raw/branch/master/dclock_bb.jpg) diff --git a/dclock.fzz b/dclock.fzz new file mode 100644 index 0000000..11fb16f Binary files /dev/null and b/dclock.fzz differ diff --git a/dclock.ino b/dclock.ino new file mode 100644 index 0000000..96f8cdb --- /dev/null +++ b/dclock.ino @@ -0,0 +1,218 @@ +// Erisian digital clock - v0.5 +#include +#include +#include +#include +#include // DisplayLib // Extended TM1637 library https://github.com/bremme/arduino-tm1637 +const byte PIN_CLK = 2; // DisplaySetting // CLK pin +const byte PIN_DIO = 3; // DisplaySetting // DIO pin +const byte buttonPin = 4; // ButtonSetting // Button pin (a 10K resistor is necessary) +SevenSegmentExtended display(PIN_CLK, PIN_DIO); // DisplaySetting +Thread mainThread = Thread(); // mainThread +long buttonPressed = 0; // Button press time counter +long previousButtonMillis = 0; // Time of last button press +byte viewMode = 0; // View mode after pressing button +int buttonInterval = 21600; // Interval for showing viewMode after pressing button +int buttonLongPress = 1728; // Long button press interval +int mainCheck = 108; // The main interval is an eighth of a decimal second +byte octavo = 0; // Eight-count counter +byte colon = 0; // Colon status +float erisiansec; // Erisian second + +// Custom settings: +int brightnessPercent = 32; // Display brightness percentage value +long timezoneOffset = (-28800); // Erisian timezoneOffset. Formula for calculating: ((-5 christian chours) - (GMT hours)) + // Examples: + // GMT+3: ( (-5)-(+3) )*60*60 = -28800 + // GMT-0: ( (-5)-(0) )*60*60 = -18000 + // GMT-3: ( (-5)-(-3) )*60*60 = -7200 + // GMT-5: ( (-5)-(-5) )*60*60 = 0 + // GMT-7: ( (-5)-(-7) )*60*60 = 7200 + // The beginning of Discordian day (0 hours, 0 minutes, 0 seconds) coincides + // with the beginning of Christian day on Easter Island on winter time (GMT-5). + // Details: https://discordia.fandom.com/wiki/Erisian_Time + +void setup() { + Serial.begin(9600); // Initializes the Serial connection @ 9600 baud for debug + display.begin(); // Display setting, initializes the display + display.setBacklight(brightnessPercent); // Display brightness setting + while (!Serial); // Wait until Arduino Serial Monitor opens + setSyncProvider(RTC.get); // The function to get the time from the RTC + if(timeStatus()!= timeSet) { // Checking the time setting + Serial.println("Unable to sync with the RTC"); + display.print("_time_not_set_"); // Shows warning "time not set" + } else { + Serial.println("RTC has set the system time"); + display.print("HAIL_EriS"); // Shows display initialization + } + pinMode(buttonPin, INPUT); // Button setting + // Main thread thread initialization: + mainThread.onRun(mainLoop); + mainThread.setInterval(mainCheck); +} + +void loop() { + // Main thread: + if (mainThread.shouldRun()) + mainThread.run(); + // Time check: + if (timeStatus() != timeSet) + display.print("SEt tiMe"); +} + +void mainLoop() { + // Counting an eighth part of a decimal second: + octavo++; + if (octavo == 8) octavo = 0; + // Update display every decimal second: + if (octavo == 0) { + if (viewMode == 0) { + dtime(); + } else if (viewMode == 1) { + dtime(); + } else if (viewMode == 2) { + ddate(); + } else if (viewMode == 3) { + ddate(); + } else if (viewMode == 4) { + dyold(); + } + } + // Resets the view mode to the default state after buttonInterval expires: + if (millis() - previousButtonMillis > buttonInterval) viewMode = 0; + // Check the button state: + if (digitalRead(buttonPin) == HIGH) { + buttonPressed = buttonPressed + mainCheck; + if (buttonPressed > buttonLongPress) { + buttonPressed = 0; + longPress(); + } + } else { + if (buttonPressed > 0) { + if (viewMode < 4) viewMode += 1; + else viewMode = 0; + buttonPressed = 0; + previousButtonMillis = millis(); + } + } +} + +void dtime() { + // Calculating discordian time: + uint32_t timec; + long christiansec; + float dtimeconv; + timec = now() + timezoneOffset; + christiansec = timec % 86400; + dtimeconv = float(86400) / float(christiansec); + erisiansec = float(100000) / dtimeconv; + if (viewMode == 0) dtimeHM(); + else if (viewMode == 1) dtimeMS(); + else dtimeHM(); + colon = !colon; + display.setColonOn(colon); +} + +void dtimeHM() { + // Displaying of erisian hours and minutes: + int dhour; + dhour = int(erisiansec / float(10000)); + int dminute; + dminute = (long(erisiansec) % 10000) / 100; + byte rawData[4]; + rawData[0] = display.encode(' '); + rawData[1] = display.encode(dhour); + rawData[2] = display.encode(dminute / 10); + rawData[3] = display.encode(dminute % 10); + display.printRaw(rawData); +} + +void dtimeMS() { + // Displaying of erisian minutes and seconds: + int dminute; + dminute = (long(erisiansec) % 10000) / 100; + int dsecond; + dsecond = (long(erisiansec) % 100); + byte rawData[4]; + rawData[0] = display.encode(dminute / 10); + rawData[1] = display.encode(dminute % 10); + rawData[2] = display.encode(dsecond / 10); + rawData[3] = display.encode(dsecond % 10); + display.printRaw(rawData); +} + +void ddate() { + // Calculating and displaying discordian date: + uint32_t timec; + timec = now() + timezoneOffset; + byte dseason; + short dday; + short daynumber; + short y = year(timec); + short m = month(timec); + short d = day(timec); + // The algorithm for calculating the day's number is from here: https://forum.arduino.cc/index.php?topic=44476.0 + int days[]={0,31,59,90,120,151,181,212,243,273,304,334}; // Number of days at the beginning of the month in a not leap year. + String outputstr; + display.setColonOn(0); + if (viewMode == 2) { + if (m == 1 || m == 2) { + daynumber = days[(m - 1)] + d; // for any type of year, it calculate the number of days for January or February + dday = daynumber; + dseason = 0; + } // Now, try to calculate for the other months + else if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) { //those are the conditions to have a leap year + daynumber = days[(m - 1)] + d + 1; // if leap year, calculate in the same way but increasing one day + dday = (daynumber % 73) - 1; + dseason = (daynumber - 1) / 73; + } + else { // if not a leap year, calculate in the normal way, such as January or February + daynumber = days[(m - 1)] + d; + dday = daynumber % 73; + dseason = daynumber / 73; + } + if ( m == 2 && d == 29 ) outputstr = " tib"; + else { + if (dseason == 0) outputstr = "ch"; + else if (dseason == 1) outputstr = "di"; + else if (dseason == 2) outputstr = "co"; + else if (dseason == 3) outputstr = "bu"; + else outputstr = "af"; + outputstr += (dday / 10); + outputstr += (dday % 10); + } + display.print(outputstr); + } else { + // Calculating and displaying discordian weekday: + byte dweekday; + daynumber = days[(m - 1)] + d; + if (daynumber < 6) dweekday = daynumber; + else dweekday = daynumber % 5; + if ( m == 2 && d == 29 ) outputstr = " tib"; + else { + if (dweekday == 1) outputstr = "swee"; + else if (dweekday == 2) outputstr = "boom"; + else if (dweekday == 3) outputstr = "pung"; + else if (dweekday == 4) outputstr = "pric"; + else outputstr = "sett"; + } + display.print(outputstr); + } +} + +void dyold() { + // Calculating and displaying discordian yold: + uint32_t timec; + timec = now() + timezoneOffset; + int yold; + yold = year(timec) + 1166; + display.setColonOn(0); + display.print(yold); +} + +void longPress() { + // Long button press function + display.setColonOn(0); + display.print("HAIL_EriS"); + viewMode = 0; +} diff --git a/dclock_bb.jpg b/dclock_bb.jpg new file mode 100644 index 0000000..23e7496 Binary files /dev/null and b/dclock_bb.jpg differ