Friday, October 25, 2024

Oled takvim projesi.

Esin kaynağım Pinterest'te rastlayıp aratınca en fazla şu kadarını bulabildiğim proje. Kod paylaşılmamış, ben de kendim yazdım.

Takvim şimdilik statik ve GUI tasarımından ibaret, yani aslında güncel tarihe göre çalışmıyor, sadece görsel kısmı kodladım ve bariz cool göründüğünü düşündüğüm için şimdiden buraya taşımak istedim. Yani her gün aynı güne uyanacağınız bir takvim bu😎 Tarihi RTC modülünden alıp gerçek zamanlı çalışan dinamik kısmı yakında geliştirip bu posta ekleyeceğim... 


Bağlantı şeması:
Arduino kodu:

/*
MIT License

You are free to use, copy, modify, and distribute this software.
The software is provided "as is," without any warranties.
No liability for any claims.

(c) 2024 Kadir Doğan
*/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128  // OLED display width, in pixels
#define SCREEN_HEIGHT 64  // OLED display height, in pixels

// Declaration for SSD1306 display connected using software SPI (default case):
#define OLED_MOSI   9
#define OLED_CLK    10
#define OLED_DC     11
#define OLED_CS     12
#define OLED_RESET  13

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
  OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

// Haftanın günleri
const char *daysOfWeek[] = {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"};

void setup() {
  Serial.begin(9600);
  display.begin(SSD1306_SWITCHCAPVCC);
  display.display();
  delay(1000);
}

void loop() {
  int year = 2024;   // Sabit yıl
  int month = 10;    // Sabit ay (Ekim)
  int today = 15;    // Sabit gün (15 Ekim 2024)
  
  drawCalendar(year, month, today);  // Sabit tarih ile takvim çiziliyor
  delay(10000);      // 10 saniyede bir takvimi güncelle
}

// Takvim çizme fonksiyonu
void drawCalendar(int year, int month, int today) {
  display.clearDisplay();
  
  // Takvim başlığı (günler)
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  
  for (int i = 0; i < 7; i++) {
    display.setCursor(5 + i * 18, 0);  // Günlerin başlangıç koordinatları
    display.print(daysOfWeek[i]);
  }

  // Takvim günlerini çizme
  int dayOffset = dayOfWeekOffset(year, month);  // Ayın ilk günü hangi günden başlıyor?
  int dayCounter = 1;
  
  for (int row = 0; row < 6; row++) {  // 6 satır, bazı aylar için gerekebilir
    for (int col = 0; col < 7; col++) {
      int x = 5 + col * 18;  // Sütunlar arası boşluk
      int y = 16 + row * 10;  // Satırlar arası boşluk
      
      if (row == 0 && col < dayOffset) {
        continue;  // İlk haftanın boş günleri
      }
      
      if (dayCounter <= daysInMonth(month, year)) {
        // Bugünü sabit olarak vurgulama
        if (dayCounter == today) {
          display.fillRect(x + 1, y - 2, 13, 11, SSD1306_WHITE);  // Bugünü vurgulamak için geniş kutu
          display.setTextColor(SSD1306_BLACK);  // Ters renk
        } else {
          display.setTextColor(SSD1306_WHITE);
        }
        
        display.setCursor(x + 2, y);  // Metni ortalamak için sağa kaydırma
        display.print(dayCounter);
        dayCounter++;
      }
    }
  }
  display.display();
}

// Ayın kaç gün olduğunu belirlemek için bir fonksiyon
int daysInMonth(int month, int year) {
  if (month == 2) {
    // Artık yıl kontrolü
    if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) {
      return 29;
    } else {
      return 28;
    }
  }
  if (month == 4 || month == 6 || month == 9 || month == 11) {
    return 30;
  }
  return 31;
}

// Haftanın ilk gününün yerini belirleyen fonksiyon (Zeller's Congruence)
int dayOfWeekOffset(int year, int month) {
  if (month < 3) {
    year--;
    month += 12;
  }
  int K = year % 100;
  int J = year / 100;
  int f = 1 + ((13 * (month + 1)) / 5) + K + (K / 4) + (J / 4) - 2 * J;
  return (f % 7 + 7) % 7;  // Haftanın günlerini sıfırdan başlatıyoruz
}