No title

 #include <WiFi.h>

#include <WebServer.h>


#include <Adafruit_GFX.h>

#include <Adafruit_ST7735.h>

#include <SPI.h>

#include <Wire.h>

#include <Adafruit_BME280.h>

#include <math.h>


// =====================================================

// ESP32-C3 SAFE PINS

// =====================================================

#define TFT_CS    7

#define TFT_RST   2

#define TFT_DC    3

#define TFT_SCLK  4

#define TFT_MOSI  6


// =====================================================

// BME280 I2C

// =====================================================

#define BME_SDA   8

#define BME_SCL   9


Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

Adafruit_BME280 bme;


// =====================================================

// WIFI HOTSPOT

// =====================================================

const char* AP_SSID = "ESP32-Weather";

const char* AP_PASSWORD = "12345678";


WebServer server(80);


// =====================================================

// COLORS

// =====================================================

#define BLACK          0x0000

#define WHITE          0xFFFF

#define BLUE           0x001F

#define YELLOW         0xFFE0

#define RED            0xF800

#define GREEN          0x07E0

#define CYAN           0x07FF

#define PINK           0xF81F

#define ORANGE         0xFD20

#define CLOUD          0xFFFF

#define LIGHT_PURPLE   0xB81F


// =====================================================

// DATE & TIME

// Internally 24-hour format

// TFT par 12-hour format show hoga

// =====================================================

int hours   = 12;

int minutes = 0;

int seconds = 0;


int day   = 26;

int month = 9;

int year  = 2026;


int dayOfWeek = 6;


// =====================================================

// DAY NAMES

// =====================================================

const char* dayNames[] = {

  "Sunday",

  "Monday",

  "Tuesday",

  "Wednesday",

  "Thursday",

  "Friday",

  "Saturday"

};


// =====================================================

// TIMERS

// =====================================================

unsigned long lastSecond = 0;

unsigned long lastSensorUpdate = 0;


// =====================================================

// BME VALUES

// =====================================================

float temperature = 0.0;

float humidity = 0.0;

float pressure = 0.0;


// =====================================================

// TIME STATUS

// =====================================================

bool timeSynced = false;


// =====================================================

// SETUP

// =====================================================

void setup() {


  Serial.begin(115200);


  // =================================================

  // TFT SPI

  // =================================================

  SPI.begin(

    TFT_SCLK,

    -1,

    TFT_MOSI,

    TFT_CS

  );


  tft.initR(INITR_MINI160x80);


  tft.setRotation(3);


  tft.fillScreen(BLACK);


  // =================================================

  // BME280

  // =================================================

  Wire.begin(

    BME_SDA,

    BME_SCL

  );


  bool bmeOK = bme.begin(0x76);


  if (!bmeOK) {

    bmeOK = bme.begin(0x77);

  }


  if (!bmeOK) {


    Serial.println(

      "BME280 NOT FOUND!"

    );

  }

  else {


    Serial.println(

      "BME280 OK"

    );

  }


  // First sensor reading

  readBME280();


  // =================================================

  // ESP32 HOTSPOT

  // =================================================

  WiFi.mode(WIFI_AP);


  WiFi.softAP(

    AP_SSID,

    AP_PASSWORD

  );


  IPAddress IP = WiFi.softAPIP();


  Serial.println();

  Serial.println(

    "=============================="

  );


  Serial.println(

    "ESP32 HOTSPOT STARTED"

  );


  Serial.print(

    "SSID: "

  );


  Serial.println(

    AP_SSID

  );


  Serial.print(

    "PASSWORD: "

  );


  Serial.println(

    AP_PASSWORD

  );


  Serial.print(

    "OPEN: http://"

  );


  Serial.println(

    IP

  );


  Serial.println(

    "=============================="

  );


  // =================================================

  // WEB SERVER

  // =================================================

  server.on(

    "/",

    handleRoot

  );


  server.on(

    "/settime",

    handleSetTime

  );


  server.begin();


  Serial.println(

    "Web server started"

  );


  // =================================================

  // DRAW UI

  // =================================================

  drawUI();


  lastSecond = millis();


  lastSensorUpdate = millis();

}


// =====================================================

// LOOP

// =====================================================

void loop() {


  // =================================================

  // WEB SERVER

  // =================================================

  server.handleClient();


  // =================================================

  // CLOCK UPDATE

  // =================================================

  if (millis() - lastSecond >= 1000) {


    lastSecond += 1000;


    seconds++;


    // Seconds

    if (seconds >= 60) {


      seconds = 0;


      minutes++;

    }


    // Minutes

    if (minutes >= 60) {


      minutes = 0;


      hours++;

    }


    // New day

    if (hours >= 24) {


      hours = 0;


      // Next weekday

      dayOfWeek++;


      if (dayOfWeek >= 7) {


        dayOfWeek = 0;

      }


      // Next date

      day++;


      // New month

      if (day > daysInMonth(month, year)) {


        day = 1;


        month++;


        // New year

        if (month > 12) {


          month = 1;


          year++;

        }

      }


      drawDate();

    }


    // Update time

    drawTime();

  }


  // =================================================

  // BME280 UPDATE

  // =================================================

  if (millis() - lastSensorUpdate >= 500) {


    lastSensorUpdate = millis();


    readBME280();


    drawSensorValues();

  }

}


// =====================================================

// DAYS IN MONTH

// =====================================================

int daysInMonth(

  int m,

  int y

) {


  switch (m) {


    case 1:

      return 31;


    case 2:


      if (

        (y % 400 == 0) ||

        (

          (y % 4 == 0) &&

          (y % 100 != 0)

        )

      ) {


        return 29;

      }


      return 28;


    case 3:

      return 31;


    case 4:

      return 30;


    case 5:

      return 31;


    case 6:

      return 30;


    case 7:

      return 31;


    case 8:

      return 31;


    case 9:

      return 30;


    case 10:

      return 31;


    case 11:

      return 30;


    case 12:

      return 31;

  }


  return 30;

}


// =====================================================

// CALCULATE DAY OF WEEK

// =====================================================

int calculateDayOfWeek(

  int d,

  int m,

  int y

) {


  int yy = y;


  int mm = m;


  if (mm < 3) {


    mm += 12;


    yy--;

  }


  int k = yy % 100;


  int j = yy / 100;


  int h =

    (

      d +

      (13 * (mm + 1)) / 5 +

      k +

      k / 4 +

      j / 4 +

      5 * j

    ) % 7;


  // Zeller:

  // 0 = Saturday

  // 1 = Sunday

  // ...

  int result =

    (h + 6) % 7;


  return result;

}


// =====================================================

// READ BME280

// =====================================================

void readBME280() {


  temperature =

    bme.readTemperature();


  humidity =

    bme.readHumidity();


  pressure =

    bme.readPressure()

    / 100.0F;


  Serial.print(

    "Temp: "

  );


  Serial.print(

    temperature,

    1

  );


  Serial.print(

    " C | Hum: "

  );


  Serial.print(

    humidity,

    0

  );


  Serial.print(

    "% | Press: "

  );


  Serial.print(

    pressure,

    0

  );


  Serial.println(

    " hPa"

  );

}


// =====================================================

// WEB PAGE

// =====================================================

void handleRoot() {


  String html = "";


  html += "<!DOCTYPE html>";


  html += "<html>";


  html += "<head>";


  html +=

    "<meta name='viewport' "

    "content='width=device-width, "

    "initial-scale=1'>";


  html +=

    "<title>ESP32 Weather Clock</title>";


  html += "<style>";


  html +=

    "body{"

    "background:#111;"

    "color:white;"

    "font-family:Arial;"

    "text-align:center;"

    "padding-top:40px;"

    "}";


  html +=

    "button{"

    "background:#00c8ff;"

    "color:#000;"

    "border:0;"

    "padding:15px 30px;"

    "font-size:18px;"

    "border-radius:10px;"

    "}";


  html += "</style>";


  html += "</head>";


  html += "<body>";


  html +=

    "<h1>ESP32 Weather Clock</h1>";


  html +=

    "<p>Mobile Date & Time Sync</p>";


  html +=

    "<button onclick='syncTime()'>"

    "SYNC TIME NOW"

    "</button>";


  html +=

    "<p id='status'>"

    "Syncing..."

    "</p>";


  html += "<script>";


  // =================================================

  // SEND MOBILE DATE/TIME

  // =================================================

  html +=

    "function syncTime(){";


  html +=

    "let d=new Date();";


  html +=

    "let data="


    "d.getFullYear()+','+"


    "(d.getMonth()+1)+','+"


    "d.getDate()+','+"


    "d.getHours()+','+"


    "d.getMinutes()+','+"


    "d.getSeconds();";


  html +=

    "fetch('/settime?t='+data)"


    ".then(r=>r.text())"


    ".then(x=>{"


    "document.getElementById('status')"

    ".innerHTML=x;"


    "});";


  html += "}";


  // Automatically sync when page opens

  html +=

    "window.onload=function(){"

    "syncTime();"

    "};";


  html += "</script>";


  html += "</body>";


  html += "</html>";


  server.send(

    200,

    "text/html",

    html

  );

}


// =====================================================

// RECEIVE MOBILE TIME

// =====================================================

void handleSetTime() {


  if (!server.hasArg("t")) {


    server.send(

      400,

      "text/plain",

      "Time data missing"

    );


    return;

  }


  String data =

    server.arg("t");


  Serial.println();


  Serial.print(

    "Mobile time received: "

  );


  Serial.println(

    data

  );


  int values[6];


  int index = 0;


  int start = 0;


  for (

    int i = 0;

    i <= data.length();

    i++

  ) {


    if (

      i == data.length() ||

      data[i] == ','

    ) {


      if (index < 6) {


        values[index] =

          data.substring(

            start,

            i

          ).toInt();


        index++;

      }


      start = i + 1;

    }

  }


  // =================================================

  // CHECK DATA

  // =================================================

  if (index == 6) {


    year =

      values[0];


    month =

      values[1];


    day =

      values[2];


    hours =

      values[3];


    minutes =

      values[4];


    seconds =

      values[5];


    // Calculate weekday

    dayOfWeek =

      calculateDayOfWeek(

        day,

        month,

        year

      );


    timeSynced = true;


    // Reset one-second timer

    lastSecond =

      millis();


    // Update display

    drawDate();


    drawTime();


    // Serial

    Serial.println(

      "TIME UPDATED FROM MOBILE!"

    );


    Serial.print(

      "Date: "

    );


    Serial.print(day);


    Serial.print("/");


    Serial.print(month);


    Serial.print("/");


    Serial.println(year);


    Serial.print(

      "24H Time: "

    );


    Serial.print(hours);


    Serial.print(":");


    Serial.print(minutes);


    Serial.print(":");


    Serial.println(seconds);


    server.send(

      200,

      "text/plain",

      "Time synced successfully!"

    );

  }


  else {


    server.send(

      400,

      "text/plain",

      "Invalid time data"

    );

  }

}


// =====================================================

// MAIN UI

// =====================================================

void drawUI() {


  tft.fillScreen(

    BLACK

  );


  // =================================================

  // CITY

  // =================================================

  tft.setTextSize(2);


  tft.setTextColor(

    LIGHT_PURPLE

  );


  tft.setCursor(

    5,

    5

  );


  tft.print(

    "London"

  );


  // =================================================

  // DATE

  // =================================================

  drawDate();


  // =================================================

  // WEATHER

  // =================================================

  tft.setTextSize(1);


  tft.setTextColor(

    ORANGE

  );


  tft.setCursor(

    5,

    25

  );


  tft.print(

    "Clouds"

  );


  // =================================================

  // TIME

  // =================================================

  drawTime();


  // =================================================

  // LABELS

  // =================================================

  tft.setTextSize(1);


  tft.setTextColor(

    PINK

  );


  tft.setCursor(

    60,

    53

  );


  tft.print(

    "Press"

  );


  tft.setCursor(

    101,

    53

  );


  tft.print(

    "Temp"

  );


  tft.setCursor(

    136,

    53

  );


  tft.print(

    "Humi"

  );


  // =================================================

  // VALUES

  // =================================================

  drawSensorValues();


  // =================================================

  // WEATHER ICON

  // =================================================

  drawWeatherIcon();

}


// =====================================================

// DATE + DAY

// =====================================================

void drawDate() {


  // Clear day

  tft.fillRect(

    88,

    0,

    72,

    16,

    BLACK

  );


  tft.setTextSize(1);


  tft.setTextColor(

    ORANGE

  );


  // Wednesday

  if (dayOfWeek == 3) {


    tft.setCursor(

      87,

      5

    );

  }


  // Thursday

  else if (dayOfWeek == 4) {


    tft.setCursor(

      91,

      5

    );

  }


  else {


    tft.setCursor(

      98,

      5

    );

  }


  tft.print(

    dayNames[dayOfWeek]

  );


  // =================================================

  // DATE

  // =================================================

  tft.fillRect(

    88,

    17,

    72,

    10,

    BLACK

  );


  tft.setTextColor(

    GREEN

  );


  tft.setCursor(

    91,

    19

  );


  if (day < 10)

    tft.print("0");


  tft.print(day);


  tft.print("/");


  if (month < 10)

    tft.print("0");


  tft.print(month);


  tft.print("/");


  tft.print(year);

}


// =====================================================

// TIME - 12 HOUR FORMAT

// =====================================================

void drawTime() {


  // Clear complete time area

  tft.fillRect(

    55,

    30,

    105,

    22,

    BLACK

  );


  // =================================================

  // 12 HOUR CONVERSION

  // =================================================

  int displayHour =

    hours;


  if (displayHour == 0) {


    displayHour = 12;

  }


  else if (displayHour > 12) {


    displayHour -= 12;

  }


  // =================================================

  // MAIN TIME

  // =================================================

  tft.setTextSize(2);


  tft.setTextColor(

    CYAN

  );


  tft.setCursor(

    56,

    32

  );


  // Hour

  if (displayHour < 10)

    tft.print("0");


  tft.print(

    displayHour

  );


  tft.print(":");


  // Minute

  if (minutes < 10)

    tft.print("0");


  tft.print(

    minutes

  );


  tft.print(":");


  // Second

  if (seconds < 10)

    tft.print("0");


  tft.print(

    seconds

  );


  // =================================================

  // AM / PM

  // =================================================

  tft.setTextSize(1);


  tft.setTextColor(

    WHITE

  );


  tft.setCursor(

    139,

    34

  );


  if (hours < 12) {


    tft.print(

      "AM"

    );

  }


  else {


    tft.print(

      "PM"

    );

  }

}


// =====================================================

// BME280 VALUES

// =====================================================

void drawSensorValues() {


  tft.setTextSize(1);


  // =================================================

  // PRESSURE

  // =================================================

  tft.fillRect(

    58,

    64,

    45,

    10,

    BLACK

  );


  tft.setTextColor(

    YELLOW

  );


  tft.setCursor(

    58,

    65

  );


  int p =

    (int)round(

      pressure

    );


  if (p > 999)

    p = 999;


  if (p < 0)

    p = 0;


  tft.print(

    p

  );


  tft.print(

    "hPa"

  );


  // =================================================

  // TEMPERATURE

  // =================================================

  tft.fillRect(

    104,

    64,

    35,

    10,

    BLACK

  );


  tft.setTextColor(

    BLUE

  );


  tft.setCursor(

    101,

    65

  );


  tft.print(

    temperature,

    1

  );


  tft.print(

    "C"

  );


  // =================================================

  // HUMIDITY

  // =================================================

  tft.fillRect(

    140,

    64,

    20,

    10,

    BLACK

  );


  tft.setTextColor(

    RED

  );


  tft.setCursor(

    136,

    65

  );


  int h =

    (int)round(

      humidity

    );


  if (h > 99)

    h = 99;


  if (h < 0)

    h = 0;


  tft.print(

    h

  );


  tft.print(

    "%"

  );

}


// =====================================================

// WEATHER ICON

// =====================================================

void drawWeatherIcon() {


  int sunX = 23;


  int sunY = 55;


  // =================================================

  // SUN

  // =================================================

  tft.fillCircle(

    sunX,

    sunY,

    8,

    CYAN

  );


  // =================================================

  // SUN RAYS

  // =================================================

  for (

    int i = 0;

    i < 360;

    i += 45

  ) {


    float angle =

      i * 0.0174533;


    int x1 =

      sunX +

      cos(angle) * 11;


    int y1 =

      sunY +

      sin(angle) * 11;


    int x2 =

      sunX +

      cos(angle) * 14;


    int y2 =

      sunY +

      sin(angle) * 14;


    tft.drawLine(

      x1,

      y1,

      x2,

      y2,

      CYAN

    );

  }


  // =================================================

  // CLOUD

  // =================================================

  tft.fillCircle(

    25,

    65,

    7,

    CLOUD

  );


  tft.fillCircle(

    34,

    64,

    9,

    CLOUD

  );


  tft.fillCircle(

    44,

    66,

    6,

    CLOUD

  );


  tft.fillRect(

    22,

    65,

    27,

    7,

    CLOUD

  );

}


Post a Comment

Previous Post Next Post

Contact Form