Issue with 0.96" display, code issue?

Here is a little (probably helpful) early Christmas present for you :wink:

/*

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

Feel free to check it out on Wokwi:

That's how it looks
image

No IR handling but the sketch uses Julian Day calculation (taken from here
DateTime calculations - #17 by jurs ) !

I have checked my calculation with libre Calc and it seems to be quite ok (one never knows :wink: ). It should even give the correct numbers after Christmas evening for the following year ...

Feel free to use it (or not)!

Good luck!
ec2021

1 Like