Difference between revisions of "Analog Clock OLED"

From
Jump to: navigation, search
(Analog Clock OLED 4)
(Analog Clock OLED 2)
Line 126: Line 126:
 
=== Analog Clock OLED 2 ===
 
=== Analog Clock OLED 2 ===
  
Analog Clock OLED Code 2<br>
+
Ajout de const int Y_OFFSET = 16;<br>
 +
Application de + Y_OFFSET sur toutes les coordonnées Y (drawStr, drawLine, drawCircle, calcul des aiguilles).<br>
  
 
<pre>
 
<pre>

Revision as of 23:53, 13 November 2025

Analog Clock OLED 1

Analog Clock OLED Code 1

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

// ---- WiFi ----
const char* ssid = "TonSSID";
const char* password = "TonMotDePasse";

// ---- Serveurs NTP ----
const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";

// ---- OLED Grove 1.12" SH1107 ----
// U8G2_SH1107_PIMAR_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
U8G2_SH1107_SEEED_128X128_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);

// ---- Variables temps ----
int hrs, mins, secs;
int day, month, year, wday;

// ---- Tableau des jours (français) ----
const char* jours[] = {"Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"};

// ---- Cadran ----
const int CENTER_X = 64;   // centre écran
const int CENTER_Y = 64;
const int RADIUS   = 55;   // grand rayon pour 128x128

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

  // Connexion WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" CONNECTÉ");

  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST
  configTzTime("CET-1CEST,M3.5.0/2,M10.5.0/3", ntpServer1, ntpServer2);

  // Init OLED
  u8g2.begin();
}

void loop() {
  setLocalTime();

  // ---- Calcul des angles ----
  float secAngle = secs * 6;
  float minAngle = mins * 6 + secs * 0.1;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;

  // ---- Positions des aiguilles ----
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180);

  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180);

  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180);

  // ---- Dessin ----
  u8g2.clearBuffer();

  // ---- Affichage jour + date en haut ----
  char bufferDate[30];
  sprintf(bufferDate, "%s %02d/%02d/%04d", jours[wday], day, month, year);
  u8g2.setFont(u8g2_font_6x13_tr);
  u8g2.drawStr(CENTER_X - 45, 12, bufferDate);

  // Cadran principal
  u8g2.drawCircle(CENTER_X, CENTER_Y, RADIUS);

  // Chiffres 12-3-6-9
  u8g2.setFont(u8g2_font_ncenB08_tr);
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5, "12");
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4, "3");
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12, "6");
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4, "9");

  // Aiguilles
  u8g2.drawLine(CENTER_X, CENTER_Y, hrX, hrY);   // heures
  u8g2.drawLine(CENTER_X, CENTER_Y, minX, minY); // minutes
  u8g2.drawLine(CENTER_X, CENTER_Y, secX, secY); // secondes

  // ---- Affichage digital en bas ----
  char bufferTime[10];
  sprintf(bufferTime, "%02d:%02d:%02d", hrs, mins, secs);
  u8g2.setFont(u8g2_font_ncenB14_tr);
  u8g2.drawStr(CENTER_X - 30, 120, bufferTime);

  u8g2.sendBuffer();

  delay(1000);
}

void setLocalTime() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Pas encore d'heure disponible");
    return;
  }
  hrs   = timeinfo.tm_hour;
  mins  = timeinfo.tm_min;
  secs  = timeinfo.tm_sec;
  day   = timeinfo.tm_mday;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0
  year  = timeinfo.tm_year + 1900;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)

  Serial.printf("%s %02d/%02d/%04d %02d:%02d:%02d\n",
                jours[wday], day, month, year, hrs, mins, secs);
}

Analog Clock OLED 2

Ajout de const int Y_OFFSET = 16;
Application de + Y_OFFSET sur toutes les coordonnées Y (drawStr, drawLine, drawCircle, calcul des aiguilles).

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

// ---- WiFi ----
const char* ssid = "TonSSID";
const char* password = "TonMotDePasse";

// ---- Serveurs NTP ----
const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";

// ---- OLED Grove 1.12" SH1107 ----
U8G2_SH1107_SEEED_128X128_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);

// ---- Variables temps ----
int hrs, mins, secs;
int day, month, year, wday;

// ---- Tableau des jours (français) ----
const char* jours[] = {"Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"};

// ---- Cadran ----
const int CENTER_X = 64;   // centre écran
const int CENTER_Y = 64;
const int RADIUS   = 55;   // grand rayon pour 128x128

// ---- Correction Y pour SH1107 ----
const int Y_OFFSET = 16;

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

  // Connexion WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" CONNECTÉ");

  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST
  configTzTime("CET-1CEST,M3.5.0/2,M10.5.0/3", ntpServer1, ntpServer2);

  // Init OLED
  u8g2.begin();
}

void loop() {
  setLocalTime();

  // ---- Calcul des angles ----
  float secAngle = secs * 6;
  float minAngle = mins * 6 + secs * 0.1;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;

  // ---- Positions des aiguilles ----
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;

  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;

  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;

  // ---- Dessin ----
  u8g2.clearBuffer();

  // ---- Affichage jour + date en haut ----
  char bufferDate[30];
  sprintf(bufferDate, "%s %02d/%02d/%04d", jours[wday], day, month, year);
  u8g2.setFont(u8g2_font_6x13_tr);
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);

  // Cadran principal
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);

  // Chiffres 12-3-6-9
  u8g2.setFont(u8g2_font_ncenB08_tr);
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, "12");
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, "3");
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, "6");
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, "9");

  // Aiguilles
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes

  // ---- Affichage digital en bas ----
  char bufferTime[10];
  sprintf(bufferTime, "%02d:%02d:%02d", hrs, mins, secs);
  u8g2.setFont(u8g2_font_ncenB14_tr);
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);

  u8g2.sendBuffer();

  delay(1000);
}

void setLocalTime() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Pas encore d'heure disponible");
    return;
  }
  hrs   = timeinfo.tm_hour;
  mins  = timeinfo.tm_min;
  secs  = timeinfo.tm_sec;
  day   = timeinfo.tm_mday;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0
  year  = timeinfo.tm_year + 1900;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)

  Serial.printf("%s %02d/%02d/%04d %02d:%02d:%02d\n",
                jours[wday], day, month, year, hrs, mins, secs);
}

Analog Clock OLED 3

Si tu utilises SH1107, laisse #define SCREEN_SH1107 actif → offset = 16.
Si tu passes à SSD1327, commente SCREEN_SH1107 et décommente SCREEN_SSD1327 → offset = 0.

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

// ---- Sélection écran ----
// Décommente la ligne correspondant à ton écran
#define SCREEN_SH1107
// #define SCREEN_SSD1327

// ---- WiFi ----
const char* ssid = "TonSSID";
const char* password = "TonMotDePasse";

// ---- Serveurs NTP ----
const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";

// ---- OLED Grove 1.12" SH1107 ----
// (Même constructeur pour SSD1327, mais offset différent)
U8G2_SH1107_SEEED_128X128_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);

// ---- Variables temps ----
int hrs, mins, secs;
int day, month, year, wday;

// ---- Tableau des jours (français) ----
const char* jours[] = {"Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"};

// ---- Cadran ----
const int CENTER_X = 64;   // centre écran
const int CENTER_Y = 64;
const int RADIUS   = 55;   // grand rayon pour 128x128

// ---- Correction Y selon écran ----
int Y_OFFSET = 0;

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

  // Choix offset selon écran
  #ifdef SCREEN_SH1107
    Y_OFFSET = 16;   // correction typique pour SH1107
  #endif

  #ifdef SCREEN_SSD1327
    Y_OFFSET = 0;    // pas besoin de correction
  #endif

  // Connexion WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" CONNECTÉ");

  // Fuseau CET/CEST (Suisse) avec gestion automatique du DST
  configTzTime("CET-1CEST,M3.5.0/2,M10.5.0/3", ntpServer1, ntpServer2);

  // Init OLED
  u8g2.begin();
}

void loop() {
  setLocalTime();

  // ---- Calcul des angles ----
  float secAngle = secs * 6;
  float minAngle = mins * 6 + secs * 0.1;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;

  // ---- Positions des aiguilles ----
  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;

  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;

  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;

  // ---- Dessin ----
  u8g2.clearBuffer();

  // ---- Affichage jour + date en haut ----
  char bufferDate[30];
  sprintf(bufferDate, "%s %02d/%02d/%04d", jours[wday], day, month, year);
  u8g2.setFont(u8g2_font_6x13_tr);
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);

  // Cadran principal
  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);

  // Chiffres 12-3-6-9
  u8g2.setFont(u8g2_font_ncenB08_tr);
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, "12");
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, "3");
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, "6");
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, "9");

  // Aiguilles
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);   // heures
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY); // minutes
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY); // secondes

  // ---- Affichage digital en bas ----
  char bufferTime[10];
  sprintf(bufferTime, "%02d:%02d:%02d", hrs, mins, secs);
  u8g2.setFont(u8g2_font_ncenB14_tr);
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);

  u8g2.sendBuffer();

  delay(1000);
}

void setLocalTime() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Pas encore d'heure disponible");
    return;
  }
  hrs   = timeinfo.tm_hour;
  mins  = timeinfo.tm_min;
  secs  = timeinfo.tm_sec;
  day   = timeinfo.tm_mday;
  month = timeinfo.tm_mon + 1; // tm_mon commence à 0
  year  = timeinfo.tm_year + 1900;
  wday  = timeinfo.tm_wday;    // jour de la semaine (0 = dimanche)

  Serial.printf("%s %02d/%02d/%04d %02d:%02d:%02d\n",
                jours[wday], day, month, year, hrs, mins, secs);
}

Analog Clock OLED 4

Au démarrage → attend 10 secondes une commande série.
Si tu tapes t → mode test offset (lignes horizontales).
Si tu tapes h → mode horloge.
Si rien n’est tapé → après 10 secondes → mode horloge par défaut.

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

// ---- Sélection écran ----
#define SCREEN_SH1107
// #define SCREEN_SSD1327

// ---- WiFi ----
const char* ssid = "TonSSID";
const char* password = "TonMotDePasse";

// ---- Serveurs NTP ----
const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";

// ---- OLED Grove 1.12" SH1107 ----
U8G2_SH1107_SEEED_128X128_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);

// ---- Variables temps ----
int hrs, mins, secs;
int day, month, year, wday;

// ---- Tableau des jours (français) ----
const char* jours[] = {"Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"};

// ---- Cadran ----
const int CENTER_X = 64;
const int CENTER_Y = 64;
const int RADIUS   = 55;

// ---- Correction Y selon écran ----
int Y_OFFSET = 0;

// ---- Mode ----
bool modeTest = false;

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

  // Choix offset selon écran
  #ifdef SCREEN_SH1107
    Y_OFFSET = 16;
  #endif
  #ifdef SCREEN_SSD1327
    Y_OFFSET = 0;
  #endif

  // Connexion WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" CONNECTÉ");

  // Fuseau CET/CEST (Suisse)
  configTzTime("CET-1CEST,M3.5.0/2,M10.5.0/3", ntpServer1, ntpServer2);

  // Init OLED
  u8g2.begin();

  // ---- Attente commande série pendant 10s ----
  Serial.println("Tapez 't' pour mode test offset, 'h' pour horloge. Sinon horloge par défaut après 10s.");
  unsigned long start = millis();
  while (millis() - start < 10000) {
    if (Serial.available()) {
      char c = Serial.read();
      if (c == 't') {
        modeTest = true;
        break;
      }
      if (c == 'h') {
        modeTest = false;
        break;
      }
    }
  }
}

void loop() {
  if (modeTest) {
    testOffset();
  } else {
    afficherHorloge();
  }
}

// ---- Fonction horloge ----
void afficherHorloge() {
  setLocalTime();

  float secAngle = secs * 6;
  float minAngle = mins * 6 + secs * 0.1;
  float hrAngle  = (hrs % 12) * 30 + mins * 0.5;

  int hrX = CENTER_X + (RADIUS - 20) * cos((hrAngle - 90) * PI / 180);
  int hrY = CENTER_Y + (RADIUS - 20) * sin((hrAngle - 90) * PI / 180) + Y_OFFSET;

  int minX = CENTER_X + (RADIUS - 10) * cos((minAngle - 90) * PI / 180);
  int minY = CENTER_Y + (RADIUS - 10) * sin((minAngle - 90) * PI / 180) + Y_OFFSET;

  int secX = CENTER_X + (RADIUS - 2) * cos((secAngle - 90) * PI / 180);
  int secY = CENTER_Y + (RADIUS - 2) * sin((secAngle - 90) * PI / 180) + Y_OFFSET;

  u8g2.clearBuffer();

  char bufferDate[30];
  sprintf(bufferDate, "%s %02d/%02d/%04d", jours[wday], day, month, year);
  u8g2.setFont(u8g2_font_6x13_tr);
  u8g2.drawStr(CENTER_X - 45, 12 + Y_OFFSET, bufferDate);

  u8g2.drawCircle(CENTER_X, CENTER_Y + Y_OFFSET, RADIUS);

  u8g2.setFont(u8g2_font_ncenB08_tr);
  u8g2.drawStr(CENTER_X - 6, CENTER_Y - RADIUS - 5 + Y_OFFSET, "12");
  u8g2.drawStr(CENTER_X + RADIUS - 10, CENTER_Y + 4 + Y_OFFSET, "3");
  u8g2.drawStr(CENTER_X - 6, CENTER_Y + RADIUS + 12 + Y_OFFSET, "6");
  u8g2.drawStr(CENTER_X - RADIUS - 12, CENTER_Y + 4 + Y_OFFSET, "9");

  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, hrX, hrY);
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, minX, minY);
  u8g2.drawLine(CENTER_X, CENTER_Y + Y_OFFSET, secX, secY);

  char bufferTime[10];
  sprintf(bufferTime, "%02d:%02d:%02d", hrs, mins, secs);
  u8g2.setFont(u8g2_font_ncenB14_tr);
  u8g2.drawStr(CENTER_X - 30, 120 + Y_OFFSET, bufferTime);

  u8g2.sendBuffer();
  delay(1000);
}

// ---- Fonction utilitaire test offset ----
void testOffset() {
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_6x13_tr);

  u8g2.drawLine(0, CENTER_Y, 128, CENTER_Y);             // sans offset
  u8g2.drawLine(0, CENTER_Y + Y_OFFSET, 128, CENTER_Y + Y_OFFSET); // avec offset

  u8g2.drawStr(10, CENTER_Y - 5, "Sans offset");
  u8g2.drawStr(10, CENTER_Y + Y_OFFSET - 5, "Avec offset");

  u8g2.sendBuffer();
  delay(1000);
}

// ---- Récupération heure locale ----
void setLocalTime() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Pas encore d'heure disponible");
    return;
  }
  hrs   = timeinfo.tm_hour;
  mins  = timeinfo.tm_min;
  secs  = timeinfo.tm_sec;
  day   = timeinfo.tm_mday;
  month = timeinfo.tm_mon + 1;
  year  = timeinfo.tm_year + 1900;
  wday  = timeinfo.tm_wday;

  Serial.printf("%s %02d/%02d/%04d %02d:%02d:%02d\n",
                jours[wday], day, month, year, hrs, mins, secs);
}