// 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 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; }