e
sv

ESP32 ve SSD1306 Kullanarak Analog Saat Yapımı

978 Okunma — 26 Ocak 2024 20:48
ESP32 ve SSD1306 Kullanarak Analog Saat Yapımı
avatar

Admin

  • e 0

    Mutlu

  • e 0

    Eğlenmiş

  • e 0

    Şaşırmış

  • e 0

    Kızgın

  • e 0

    Üzgün

Dijital saatlerin ve akıllı telefonların her yerde yaygınlaştığı modern teknoloji dünyasında, analog saatin sadeliği ve zarafetinde büyüleyici nostaljik bir şeyler var. ESP32 mikro denetleyicisini ve SSD1306 OLED ekranı kullanarak kendi analog saatinizi oluşturmak, yalnızca her iki dünyanın en iyilerini (analog zaman işleyişinin klasik estetiği ve modern elektroniğin gücü) birleştirmekle kalmaz, aynı zamanda büyüleyici bir Kendin Yap projesine de olanak sağlar.

Bu projemizde NTP sunucusunun yardımıyla bir ESP32 Analog Saat oluşturacağız ve bunu OLED ekranda görüntüleyeceğiz.

NTP Sunucusu Nedir

ESP32 ve SSD1306 Kullanarak Analog Saat Yapımı
ESP32 ve SSD1306 Kullanarak Analog Saat Yapımı 5

NTP (Network Time Protocol), bir ağ üzerinden hassas bir saat senkronizasyonu sağlamak için kullanılan bir iletişim protokolüdür. NTP sunucusu, bu protokolü kullanarak zaman bilgilerini sağlayan ve alandan sistemlere gönderen bir sunucudur. NTP, genellikle bilgisayarlar, sunucular, ağ cihazları ve diğer sistemler arasında zamanın doğru bir şekilde senkronize edilmesini sağlamak için kullanılır.

NTP sunucuları, genellikle zamanla kayma olasılığını minimize etmek ve dünya genelinde yaygın olarak kullanılan bir referans zamanına (UTC – Coordinated Universal Time) yakın bir zamanı sağlamak için özel olarak yapılandırılmış, yüksek doğruluklu saatlere sahip cihazlardır. Bu sunucular, dünya genelinde birbirleriyle senkronize olabilirler ve kullanıcıların bu sunuculara erişerek zaman bilgilerini almasına izin verirler.

NTP’nin ana avantajları şunlardır:

  1. Hassas Senkronizasyon: NTP, bilgisayarlar ve ağ cihazları arasında çok hassas bir zaman senkronizasyonu sağlar.
  2. Zaman Kayması Azaltma: NTP sunucuları, zaman kaymasını düşük tutmak için çeşitli stratum seviyeleri üzerinden birbirleriyle iletişim kurar.
  3. UTC Referansı: NTP sunucuları genellikle UTC (Koordineli Evrensel Zaman) veya başka bir referans zamanını kullanarak zaman bilgilerini sağlar.
  4. Geniş Kapsama Alanı: NTP, dünya genelinde birçok NTP sunucusunun bulunması sayesinde geniş bir kapsama alanına sahiptir.

NTP sunucularının yanı sıra, dünya genelinde halka açık olarak kullanılabilen ve çeşitli organizasyonlar tarafından işletilen NTP sunucuları da bulunmaktadır. Bu halka açık sunucular, internete bağlı herhangi bir cihazın doğru zaman bilgisini almasına olanak tanır.

ESP32 ve SSD1306 Kullanarak Analog Saat Yapımı
ESP32 ve SSD1306 Kullanarak Analog Saat Yapımı 6
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <math.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

#define OLED_RESET    -1
#define SCREEN_ADDRESS 0x3C

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  Serial.begin(115200);

  if(!display.begin(SSD1306_I2C_ADDRESS, OLED_RESET, OLED_RESET)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }

  display.display();
  delay(2000);
  display.clearDisplay();
}

void loop() {
  display.clearDisplay();

  // Saat çerçevesini çiz
  display.drawCircle(SCREEN_WIDTH/2, SCREEN_HEIGHT/2, SCREEN_HEIGHT/2, SSD1306_WHITE);
  display.fillCircle(SCREEN_WIDTH/2, SCREEN_HEIGHT/2, 3, SSD1306_WHITE);

  // Saat ibresini çiz
  int saat = hour();
  int dakika = minute();
  int saniye = second();

  drawHand(saat * 30 + dakika / 2, 30, 3, SSD1306_WHITE);  // Saat ibresi
  drawHand(dakika * 6, 40, 2, SSD1306_WHITE);               // Dakika ibresi
  drawHand(saniye * 6, 50, 1, SSD1306_WHITE);               // Saniye ibresi

  display.display();
  delay(1000);
}

void drawHand(int aci, int uzunluk, int kalinlik, uint16_t renk) {
  float radian = radians(aci);
  int x = SCREEN_WIDTH/2 + uzunluk * cos(radian);
  int y = SCREEN_HEIGHT/2 + uzunluk * sin(radian);
  display.drawLine(SCREEN_WIDTH/2, SCREEN_HEIGHT/2, x, y, renk);
}

Bu Proje içim iki farklı kod kullandık istediğinizi seçebilirsiniz

ESP32 ve SSD1306 Kullanarak Analog Saat Yapımı
ESP32 ve SSD1306 Kullanarak Analog Saat Yapımı 7
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#include <WiFi.h>
#include "time.h"
#include "sntp.h"

const char* ssid = "Circuits DIY";
const char* password = "20244064";

const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;

int hrs=0;
int mins=0;
int secs=0;

Adafruit_SSD1306 display(128, 64, &Wire, -1);

const int NUM_POINTS = 60;
const int RADIUS = 28;

int pointsX[NUM_POINTS];
int pointsY[NUM_POINTS];

void setup() {
  Serial.begin(115200);
  // set notification call-back function
  sntp_set_time_sync_notification_cb(timeavailable);
  //sntp_servermode_dhcp(1);  // (optional)
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);

  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" CONNECTED");

  /***************************************************/

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  //initialize the display with I2C address 0x3C
  display.clearDisplay();                     //clear the display buffer
  display.display();                          //update the display

  for (int i = 0; i < NUM_POINTS; i++) {
    pointsX[i] = 64 + RADIUS * cos(i * 6.28 / NUM_POINTS);
    pointsY[i] = 32 + RADIUS * sin(i * 6.28 / NUM_POINTS);
  }
}

void loop() {
  setLocalTime();
  //calculate the angle for each hand
  float secAngle = map(secs, 0, 60, 0, 360);
  float minAngle = map(mins, 0, 60, 0, 360);
  float hrAngle = map(hrs, 1, 12, 30, 360);

  //calculate the positions of the hands
  int hrX = 64 + (RADIUS - 11) * cos((hrAngle - 90) * PI / 180);
  int hrY = 32 + (RADIUS - 11) * sin((hrAngle - 90) * PI / 180);
  int minX = 64 + (RADIUS - 6) * cos((minAngle - 90) * PI / 180);
  int minY = 32 + (RADIUS - 6) * sin((minAngle - 90) * PI / 180);
  int secX = 64 + (RADIUS)*cos((secAngle - 90) * PI / 180);
  int secY = 32 + (RADIUS)*sin((secAngle - 90) * PI / 180);

  display.clearDisplay();  //clear the display buffer

  //draw the clock face
  display.drawCircle(64, 32, 32, WHITE);  //Draw a Center Point
  //Draw 12 Clock points
  for (int i = 0; i < NUM_POINTS; i += 5) {
    display.fillCircle(pointsX[i], pointsY[i], 1, WHITE);
  }

  //Display Numbers 12-3-6-9
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);

  for (int i = 12; i > 1; i -= 3) {
    float angle = map(i, 1, 12, 30, 360);
    int xPos = 64 + (RADIUS - 7) * cos((angle - 90) * PI / 180) - 3;
    int yPos = 32 + (RADIUS - 7) * sin((angle - 90) * PI / 180) - 3;
    display.setCursor(xPos, yPos);
    display.print(i);
  }

  //draw the hour hand
  display.drawLine(64, 32, hrX, hrY, WHITE);

  //draw the minute hand
  display.drawLine(64, 32, minX, minY, WHITE);

  //draw the Second hand
  //display.drawLine(64, 32, secX, secY, WHITE);
  display.drawCircle(secX, secY, 2, WHITE);

  //update the display
  display.display();
  delay(1000);
}


void setLocalTime() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("No time available (yet)");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
  
  hrs = timeinfo.tm_hour;
  mins = timeinfo.tm_min;
  secs = timeinfo.tm_sec;

}

// Callback function (get's called when time adjusts via NTP)
void timeavailable(struct timeval* t) {
  Serial.println("Got time adjustment from NTP!");
  setLocalTime();
}
okuyucu yorumlarıOKUYUCU YORUMLARI

Yorum yapabilmek için giriş yapmalısınız.

Sıradaki içerik:

ESP32 ve SSD1306 Kullanarak Analog Saat Yapımı

Araç çubuğuna atla