Hi @atercor ,
hier gab es im englischsprachigen Bereich des Forums
https://forum.arduino.cc/t/issue-with-0-96-display-code-issue/1195653
jemanden, der gerne eine Anwendung programmieren wollte, welche die Zeit bis Weihnachten in verschiedenen Zeiteinheiten anzeigt.
Die Lösung der Aufgabe, die ich für ihn auf Wokwi bereitgestellt habe, sollte alles beinhalten, was Du für Deine Anwendung benötigst. Die Berechnung der Zeit zwischen zwei Daten ist dort allgemein und im speziellen für die Zeit bis zum nächsten Heiligabend nachzuvollziehen.
/*
Forum: https://forum.arduino.cc/t/issue-with-0-96-display-code-issue/1195653
Wokwi: https://wokwi.com/projects/383021035087828993
*/
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "RTClib.h"
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
RTC_DS1307 rtc;
DateTime now, prev;
void setup() {
Serial.begin(115200);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
for (;;); // Don't proceed, loop forever
}
// Clear the buffer
display.clearDisplay();
display.display();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
}
void loop () {
now = rtc.now();
if (now.second() != prev.second()) {
prev = now;
printTimeToSerial();
printTimeToDisplay();
}
}
void printTimeToDisplay() {
char buf[80];
sprintf(buf, " %0.2d.%0.2d.%4d %0.2d:%0.2d:%0.2d",
now.day(), now.month(), now.year(),
now.hour(), now.minute(), now.second()
);
display.clearDisplay();
display.setCursor(0, 2);
display.println(buf);
display.println();
display.println(" Still to go ...");
display.setCursor(0, 30);
display.print(" Days: ");
display.println(daysUntilXmas());
display.print(" or Hours: ");
display.println(hoursUntilXmas());
display.print(" or Minutes: ");
display.println(minutesUntilXmas());
display.print(" or Seconds: ");
display.println(secondsUntilXmas());
display.drawLine(0, 10, display.width(), 10, SSD1306_WHITE);
display.display();
}
void printTimeToSerial() {
char buf[80];
sprintf(buf, "Current time: %0.2d.%0.2d.%4d %0.2d:%0.2d:%0.2d",
now.day(), now.month(), now.year(),
now.hour(), now.minute(), now.second()
);
Serial.println(buf);
Serial.print("Days until Xmas: \t");
Serial.println(daysUntilXmas());
Serial.print("Hours until Xmas:\t");
Serial.println(hoursUntilXmas());
Serial.print("Minutes until Xmas:\t");
Serial.println(minutesUntilXmas());
Serial.print("Seconds until Xmas:\t");
Serial.println(secondsUntilXmas());
}
// "days difference" means "days" not (24 hours per day)!!!
// e.g. on 12/23 there will be "1 day to go" until 23:59:59 o'clock
long daysUntilXmas() {
int XmasYear = now.year();
if (now.month() == 12 && now.day() > 24) {
XmasYear++;
}
return daysDiff(now.year(), now.month(), now.day(),
XmasYear, 12, 24);
}
// Minutes difference based on 12/24 at 0 o'clock in the morning local RTC time
long minutesUntilXmas() {
int XmasYear = now.year();
if (now.month() == 12 && now.day() > 24) {
XmasYear++;
}
return minutesDiff(now.year(), now.month(), now.day(), now.hour(), now.minute(),
XmasYear, 12, 24, 0, 0);
}
// Full hours difference based on minutesUntilXmas
long hoursUntilXmas() {
long minutes = minutesUntilXmas();
return (minutes / 60);
}
// Seconds difference based on minutesUntilXmas() plus rest of recent minute
long secondsUntilXmas() {
long minutes = minutesUntilXmas();
return (60 - now.second() + minutes * 60);
}
//
// Source https://forum.arduino.cc/t/datetime-calculations/354776/16
// "Julian Day Number"
//
long JD(int year, int month, int day)
{ // COMPUTES THE JULIAN DATE (JD) GIVEN A GREGORIAN CALENDAR
return day - 32075 + 1461L * (year + 4800 + (month - 14) / 12) / 4 + 367 * (month - 2 - (month - 14) / 12 * 12) / 12 - 3 * ((year + 4900 + (month - 14) / 12) / 100) / 4;
}
long daysDiff(int year1, int mon1, int day1, int year2, int mon2, int day2)
{
return JD(year2, mon2, day2) - JD(year1, mon1, day1);
}
long minutesDiff(int year1, int mon1, int day1, int hour1, int min1, int year2, int mon2, int day2, int hour2, int min2 )
{
int mDiff = (hour2 * 60 + min2) - (hour1 * 60 + min1);
return daysDiff(year1, mon1, day1, year2, mon2, day2) * 1440 + mDiff;
}
Du kannst das Ergebnis beim Online-Simulator Wokwi anschauen und bei Bedarf auch auf dieser Plattform anpassen und testen.
https://wokwi.com/projects/383021035087828993
Viel Spaß damit!
ec2021