Help needed to display external RTC date and time on DWIN display using ESP32

Hello everyone,

I am a university student working on a project using an ESP32, DWIN display, MAX6675 temperature sensor, and an external RTC module to make a temperature recorder.

I am facing a problem with displaying the date and time from the external RTC on the DWIN display.

I have already tried several methods and also took help from the internet and other people, but unfortunately I have still not been able to get the required result, in result I am getting dots,nothing else.

Thanks in advance.

Regards,
Dino

Welcome to the forum

Can you print anything such as "Hello World" on the display ?

#include <Arduino.h>

#include <Wire.h>

#include <max6675.h>

#include <RTClib.h>

// -----------------------------------------------------------------------------------------

// HARDWARE PINS

// -----------------------------------------------------------------------------------------

// MAX6675 Thermocouple

#define MAX6675_SCK 18

#define MAX6675_CS 5

#define MAX6675_SO 19

MAX6675 thermocouple(MAX6675_SCK, MAX6675_CS, MAX6675_SO);

// DWIN UART2

#define DWIN_RX 25

#define DWIN_TX 26

#define DWIN_SERIAL Serial2

// External Real-Time Clock

RTC_DS3231 rtc;

bool rtcFound = false;

// -----------------------------------------------------------------------------------------

// DWIN VARIABLE POINTERS (VPs)

// -----------------------------------------------------------------------------------------

const uint16_t TEMP_VP = 0x1000; // Temperature Display (Numeric 2 Digits)

const uint16_t DATE_VP = 0x1010; // Date Display (Text Display, Length 12)

const uint16_t TIME_VP = 0x1020; // Time Display (Text Display, Length 10)

// Update timing

unsigned long lastUpdate = 0;

const unsigned long UPDATE_INTERVAL = 1000; // Update display every 1 second

// Software Clock Fallback (used if physical RTC is disconnected)

uint16_t softYear = 2026;

uint8_t softMonth = 10;

uint8_t softDay = 2;

uint8_t softHour = 20;

uint8_t softMinute = 20;

uint8_t softSecond = 0;

// -----------------------------------------------------------------------------------------

// DWIN PROTOCOL HELPERS

// -----------------------------------------------------------------------------------------

// Send 16-bit integer to DWIN numeric VP

void sendDwinWord(uint16_t address, uint16_t value) {

byte pkt[8];

pkt[0] = 0x5A;

pkt[1] = 0xA5;

pkt[2] = 0x05;

pkt[3] = 0x82; // Write Command

pkt[4] = highByte(address);

pkt[5] = lowByte(address);

pkt[6] = highByte(value);

pkt[7] = lowByte(value);

DWIN_SERIAL.write(pkt, 8);

DWIN_SERIAL.flush();

}

// Send ASCII text string to DWIN Text Display with dual 0xFF terminator

void sendDwinString(uint16_t address, String text, int maxLen = 12) {

byte pkt[36];

byte payloadLen = 3 + maxLen; // 0x82 + vpH + vpL + maxLen

pkt[0] = 0x5A;

pkt[1] = 0xA5;

pkt[2] = payloadLen;

pkt[3] = 0x82; // Write Command

pkt[4] = highByte(address);

pkt[5] = lowByte(address);

int textLen = text.length();

for (int i = 0; i < maxLen; i++) {

if (i < textLen) {

  pkt\[6 + i\] = (byte)text\[i\];

} else if (i == textLen || i == textLen + 1) {

  pkt\[6 + i\] = 0xFF; // DWIN standard string terminator

} else {

  pkt\[6 + i\] = 0x00;

}

}

DWIN_SERIAL.write(pkt, 3 + payloadLen);

DWIN_SERIAL.flush();

}

// -----------------------------------------------------------------------------------------

// SOFTWARE CLOCK TICKER (Fallback if physical RTC disconnects)

// -----------------------------------------------------------------------------------------

void tickSoftwareClock() {

softSecond++;

if (softSecond >= 60) {

softSecond = 0;

softMinute++;

if (softMinute >= 60) {

  softMinute = 0;

  softHour++;

  if (softHour >= 24) {

    softHour = 0;

    softDay++;

  }

}

}

}

// -----------------------------------------------------------------------------------------

// SETUP

// -----------------------------------------------------------------------------------------

void setup() {

Serial.begin(115200);

// Initialize I2C for External RTC (SDA=21, SCL=22)

Wire.begin(21, 22);

// Start DWIN hardware serial communication (UART2)

DWIN_SERIAL.begin(115200, SERIAL_8N1, DWIN_RX, DWIN_TX);

// Cold-boot delay: Give DWIN screen 2 seconds to complete power-on self-test

delay(2000);

Serial.println("\n=======================================================");

Serial.println(" ESP32 TEMPERATURE, DATE & TIME RECORDER CONTROLLER ");

Serial.println("=======================================================");

// Initialize External RTC

if (rtc.begin()) {

rtcFound = true;

Serial.println("\[RTC\] External Hardware RTC detected on I2C (GPIO 21/22)!");

if (rtc.lostPower()) {

  Serial.println("\[RTC\] Battery was disconnected, setting to compile time.");

  rtc.adjust(DateTime(F(\__DATE_\_), F(\__TIME_\_)));

}

} else {

rtcFound = false;

Serial.println("\[RTC\] Warning: No external RTC detected. Running software clock.");

}

}

// -----------------------------------------------------------------------------------------

// MAIN LOOP

// -----------------------------------------------------------------------------------------

void loop() {

unsigned long now = millis();

// Execute update every 1 second

if (now - lastUpdate >= UPDATE_INTERVAL) {

lastUpdate = now;



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

// 1. READ & DISPLAY TEMPERATURE (MAX6675)

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

float tempC = thermocouple.readCelsius();



if (isnan(tempC)) {

  Serial.println("\[ERROR\] Thermocouple disconnected or reading failed!");

  sendDwinWord(TEMP_VP, 0);

} else {

  Serial.printf("\[TEMP\] Sensor Output: %.1f °C\\n", tempC);



  // Warning diagnostic for reversed thermocouple polarity

  if (tempC >= 5.0 && tempC <= 16.0) {

    Serial.println(">>> \[NOTICE\] Reading 8-13°C at room temperature indicates REVERSED WIRES!");

    Serial.println(">>> Please swap the (+) and (-) wires on the MAX6675 screw terminal.");

  }



  // Send whole integer (e.g. 26 °C) to fit 2-digit display

  uint16_t dwinIntVal = (uint16_t)round(tempC);

  sendDwinWord(TEMP_VP, dwinIntVal);

}



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

// 2. READ & FORMAT DATE AND TIME FROM EXTERNAL RTC

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

uint16_t year;

uint8_t month, day, hour, minute, second;



if (rtcFound) {

  DateTime dt = rtc.now();

  year   = dt.year();

  month  = dt.month();

  day    = dt.day();

  hour   = dt.hour();

  minute = dt.minute();

  second = dt.second();

} else {

  tickSoftwareClock();

  year   = softYear;

  month  = softMonth;

  day    = softDay;

  hour   = softHour;

  minute = softMinute;

  second = softSecond;

}



// Format Date String: "DD-MM-YYYY" (10 chars, fits 12-byte VP 0x1010)

char dateBuf\[12\];

snprintf(dateBuf, sizeof(dateBuf), "%02d-%02d-%04d", day, month, year);



// Format Time String: "HH:MM:SS" (8 chars, fits 10-byte VP 0x1020)

char timeBuf\[10\];

snprintf(timeBuf, sizeof(timeBuf), "%02d:%02d:%02d", hour, minute, second);



Serial.printf("\[CLOCK\] Date: %s | Time: %s\\n", dateBuf, timeBuf);



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

// 3. SEND DATE & TIME TO DWIN SCREEN

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

sendDwinString(DATE_VP, String(dateBuf), 12);

delay(5);

sendDwinString(TIME_VP, String(timeBuf), 10);

}

}Use code tags to format code for the forum

Note this message

Please post your sketch, using code tags when you do

Posting your code using code tags prevents parts of it being interpreted as HTML coding and makes it easier to copy for examination

In my experience the easiest way to tidy up the code and add the code tags is as follows

Start by tidying up your code by using Tools/Auto Format in the IDE to make it easier to read. Then use Edit/Copy for Forum and paste what was copied in a new reply. Code tags will have been added to the code to make it easy to read in the forum thus making it easier to provide help.

Sir, I am very new in this forum, so forbid my mistakes

#include <Arduino.h>

#include <Wire.h>

#include <max6675.h>

#include <RTClib.h>




// -----------------------------------------------------------------------------------------

// HARDWARE PINS

// -----------------------------------------------------------------------------------------

// MAX6675 Thermocouple

#define MAX6675_SCK 18

#define MAX6675_CS   5

#define MAX6675_SO  19

MAX6675 thermocouple(MAX6675_SCK, MAX6675_CS, MAX6675_SO);




// DWIN UART2

#define DWIN_RX 25

#define DWIN_TX 26

#define DWIN_SERIAL Serial2




// External Real-Time Clock

RTC_DS3231 rtc;

bool rtcFound = false;




// -----------------------------------------------------------------------------------------

// DWIN VARIABLE POINTERS (VPs)

// -----------------------------------------------------------------------------------------

const uint16_t TEMP_VP = 0x1000; // Temperature Display (Numeric 2 Digits)

const uint16_t DATE_VP = 0x1010; // Date Display (Text Display, Length 12)

const uint16_t TIME_VP = 0x1020; // Time Display (Text Display, Length 10)




// Update timing

unsigned long lastUpdate = 0;

const unsigned long UPDATE_INTERVAL = 1000; // Update display every 1 second




// Software Clock Fallback (used if physical RTC is disconnected)

uint16_t softYear   = 2026;

uint8_t  softMonth  = 10;

uint8_t  softDay    = 2;

uint8_t  softHour   = 20;

uint8_t  softMinute = 20;

uint8_t  softSecond = 0;




// -----------------------------------------------------------------------------------------

// DWIN PROTOCOL HELPERS

// -----------------------------------------------------------------------------------------

// Send 16-bit integer to DWIN numeric VP

void sendDwinWord(uint16_t address, uint16_t value) {

  byte pkt[8];

  pkt[0] = 0x5A;

  pkt[1] = 0xA5;

  pkt[2] = 0x05;

  pkt[3] = 0x82; // Write Command

  pkt[4] = highByte(address);

  pkt[5] = lowByte(address);

  pkt[6] = highByte(value);

  pkt[7] = lowByte(value);




  DWIN_SERIAL.write(pkt, 8);

  DWIN_SERIAL.flush();

}




// Send ASCII text string to DWIN Text Display with dual 0xFF terminator

void sendDwinString(uint16_t address, String text, int maxLen = 12) {

  byte pkt[36];

  byte payloadLen = 3 + maxLen; // 0x82 + vpH + vpL + maxLen




  pkt[0] = 0x5A;

  pkt[1] = 0xA5;

  pkt[2] = payloadLen;

  pkt[3] = 0x82; // Write Command

  pkt[4] = highByte(address);

  pkt[5] = lowByte(address);




  int textLen = text.length();

  for (int i = 0; i < maxLen; i++) {

    if (i < textLen) {

      pkt[6 + i] = (byte)text[i];

    } else if (i == textLen || i == textLen + 1) {

      pkt[6 + i] = 0xFF; // DWIN standard string terminator

    } else {

      pkt[6 + i] = 0x00;

    }

  }




  DWIN_SERIAL.write(pkt, 3 + payloadLen);

  DWIN_SERIAL.flush();

}




// -----------------------------------------------------------------------------------------

// SOFTWARE CLOCK TICKER (Fallback if physical RTC disconnects)

// -----------------------------------------------------------------------------------------

void tickSoftwareClock() {

  softSecond++;

  if (softSecond >= 60) {

    softSecond = 0;

    softMinute++;

    if (softMinute >= 60) {

      softMinute = 0;

      softHour++;

      if (softHour >= 24) {

        softHour = 0;

        softDay++;

      }

    }

  }

}




// -----------------------------------------------------------------------------------------

// SETUP

// -----------------------------------------------------------------------------------------

void setup() {

  Serial.begin(115200);




  // Initialize I2C for External RTC (SDA=21, SCL=22)

  Wire.begin(21, 22);




  // Start DWIN hardware serial communication (UART2)

  DWIN_SERIAL.begin(115200, SERIAL_8N1, DWIN_RX, DWIN_TX);




  // Cold-boot delay: Give DWIN screen 2 seconds to complete power-on self-test

  delay(2000);




  Serial.println("\n=======================================================");

  Serial.println("  ESP32 TEMPERATURE, DATE & TIME RECORDER CONTROLLER  ");

  Serial.println("=======================================================");




  // Initialize External RTC

  if (rtc.begin()) {

    rtcFound = true;

    Serial.println("[RTC] External Hardware RTC detected on I2C (GPIO 21/22)!");

    if (rtc.lostPower()) {

      Serial.println("[RTC] Battery was disconnected, setting to compile time.");

      rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

    }

  } else {

    rtcFound = false;

    Serial.println("[RTC] Warning: No external RTC detected. Running software clock.");

  }

}




// -----------------------------------------------------------------------------------------

// MAIN LOOP

// -----------------------------------------------------------------------------------------

void loop() {

  unsigned long now = millis();




  // Execute update every 1 second

  if (now - lastUpdate >= UPDATE_INTERVAL) {

    lastUpdate = now;




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

    // 1. READ & DISPLAY TEMPERATURE (MAX6675)

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

    float tempC = thermocouple.readCelsius();




    if (isnan(tempC)) {

      Serial.println("[ERROR] Thermocouple disconnected or reading failed!");

      sendDwinWord(TEMP_VP, 0);

    } else {

      Serial.printf("[TEMP] Sensor Output: %.1f °C\n", tempC);




      // Warning diagnostic for reversed thermocouple polarity

      if (tempC >= 5.0 && tempC <= 16.0) {

        Serial.println(">>> [NOTICE] Reading 8-13°C at room temperature indicates REVERSED WIRES!");

        Serial.println(">>> Please swap the (+) and (-) wires on the MAX6675 screw terminal.");

      }




      // Send whole integer (e.g. 26 °C) to fit 2-digit display

      uint16_t dwinIntVal = (uint16_t)round(tempC);

      sendDwinWord(TEMP_VP, dwinIntVal);

    }




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

    // 2. READ & FORMAT DATE AND TIME FROM EXTERNAL RTC

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

    uint16_t year;

    uint8_t month, day, hour, minute, second;




    if (rtcFound) {

      DateTime dt = rtc.now();

      year   = dt.year();

      month  = dt.month();

      day    = dt.day();

      hour   = dt.hour();

      minute = dt.minute();

      second = dt.second();

    } else {

      tickSoftwareClock();

      year   = softYear;

      month  = softMonth;

      day    = softDay;

      hour   = softHour;

      minute = softMinute;

      second = softSecond;

    }




    // Format Date String: "DD-MM-YYYY" (10 chars, fits 12-byte VP 0x1010)

    char dateBuf[12];

    snprintf(dateBuf, sizeof(dateBuf), "%02d-%02d-%04d", day, month, year);




    // Format Time String: "HH:MM:SS" (8 chars, fits 10-byte VP 0x1020)

    char timeBuf[10];

    snprintf(timeBuf, sizeof(timeBuf), "%02d:%02d:%02d", hour, minute, second);




    Serial.printf("[CLOCK] Date: %s | Time: %s\n", dateBuf, timeBuf);




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

    // 3. SEND DATE & TIME TO DWIN SCREEN

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

    sendDwinString(DATE_VP, String(dateBuf), 12);

    delay(5);

    sendDwinString(TIME_VP, String(timeBuf), 10);

  }

}

I see a lot of AI written code in there (the hallmarks aren't hard to see). Have you asked the AI to critique its own writing?

Failing that, you might investigate the routine that the code is using to display the date and time. Nothing else uses it. So how do you know it works?

Sir, As I said in the beginning I took help all around resources, to complete my project... people, internet etc

Your code does not stop if "no RTC found"

To stop the code (because the RTC is not responding), place this after the Serial.println()

    Serial.println("[RTC] Warning: No external RTC detected. Running software clock.");
    while (true) {}
  }

... and correct the RTC problem.

it may be a good idea to give some more details of the project aims and objectives, e.g. temperature range, accuracy required, etc

also links to the specific DWIN display and ESP32 module being used

have you tested each device in a separate program before attempting to implement the complete project?

And yet you avoided answering both questions I asked you. When asking for help, answer questions you are asked. Otherwise you're just wasting everyone's time.

Well, I'm not going to ask you twice. You had your chance. I will tell you this much before I leave you to it: even a cursory examination of that routine you're using to display the date and time would have told you that it's not correct. Your packets are malformed. But since you can't manage to be forthcoming, so be it. Good luck figuring it out!

Serial.printf("\[CLOCK\] Date: %s | Time: %s\\n", dateBuf, timeBuf);

What does your serial output tell you about the time/date character buffers you have created and filled?

Can you fill the time/date fields on the DWIN when you use the software clock?

That was an unfortunate "markdown" inclusion. The code block in Post #6 does not have those "escape" characters...

The Serial Monitor is happy with the "non-escaped" line... if sprintf() is correct and the buffer size is correct.

const char dateBuf[] = "20261002";  // 8 char
const char timeBuf[] = "20:35.00";  // 8 char
char buffer[41];                    // must contain the full buffer

void setup() {
  Serial.begin(115200);  // start Serial comm
  sprintf(buffer, "[CLOCK] Date: %s | Time: %s\n", dateBuf, timeBuf);
  Serial.print(buffer);
}

void loop() {}

Result of my example, above:

[CLOCK] Date: 20261002 | Time: 20:35.00

The code "works" (I do not have a thermometer, hence the error)

=======================================================
  ESP32 TEMPERATURE, DATE & TIME RECORDER CONTROLLER  
=======================================================
[RTC] External Hardware RTC detected on I2C (GPIO 21/22)!
[ERROR] Thermocouple disconnected or reading failed!
[CLOCK] Date: 02-10-2026 | Time: 16:17:39

It appears the DWIN display is a Serial device, using VCC, GND, TXD, RXD. The other peripherals are connected to (available pins) and communicated with (via library) the ESP32 normally.

Drawing from: Smart Home Controller using DWIN HMI Display & ESP32

Thank you Sirs, 5A A5 0B 82 00 10 [YY] [MM] [DD] [WW] [HH] [MM] [SS] 00" this solved my issue,now I am getting perfect display.