M5Stack Dual‑Core RTC Clock

Articles

Overview

This project demonstrates how to build a smooth, accurate, and visually refined desk clock using:

  • M5Stack (ESP32 DualCore)
  • BM8563 RTC
  • M5FontRender for anti‑aliased text
  • DualCore task separation for stable rendering
  • Selective screen updates for flicker‑free UI

Compared to standard or binary fonts, it enables beautiful text rendering with anti-aliasing.

The result is a professional‑grade clock with precise timing and fluid animations.

🧩 System Architecture

Core 1 (Logic Core)

Handles:

  • RTC communication
  • Button input
  • Mode switching
  • Time/date comparison

Core 0 (Rendering Core)

Handles:

  • Heavy text rendering
  • Screen updates
  • Wi‑Fi/Bluetooth background tasks

Why this matters: Core 0 is responsible for system services. Without delay(1) or vTaskDelay(), the watchdog timer resets the device.

🕒 RTC (BM8563) Integration

Why BM8563?

  • Maintains time even when M5Stack is powered off
  • Low‑power, stable I²C interface
  • Simple BCD‑based registers

RTC Write Function (Optimized)

cpp

void setRTC(uint16_t year, uint8_t month, uint8_t day,
            uint8_t hour, uint8_t min, uint8_t sec) {
    Wire.beginTransmission(0x51);
    Wire.write(0x02);
    Wire.write(decToBcd(sec));
    Wire.write(decToBcd(min));
    Wire.write(decToBcd(hour));
    Wire.write(decToBcd(day));
    Wire.write(0x00);
    Wire.write(decToBcd(month));
    Wire.write(decToBcd(year % 100));
    Wire.endTransmission();
}

RTC Read Function (Optimized)

Reads 7 bytes and converts BCD → decimal.

🎨 High‑Quality Rendering with M5FontRender

M5FontRender provides:

  • Anti‑aliased text
  • Smooth curves
  • Better readability
  • Professional UI appearance

This is a major upgrade over default M5Stack fonts.

⚙️ DualCore Display Task (Enhanced Explanation)

The display task runs on Core 0 and updates only the areas that changed:

✔ Selective Redraw

  • Date area (x=30, y=80)
  • Time area (x=30, y=110)

✔ Mode‑based full refresh

When switching modes, the entire screen is cleared once.

✔ Flicker‑free updates

Only redraw when values change.

Optimized Display Task Snippet

cpp

if (task_no != last_task_no) {
    M5.Lcd.fillScreen(BLACK);
    last_task_no = task_no;
}

if (!isDateSame(now_date, old_date)) {
    M5.Lcd.fillRect(30, 80, 260, 26, BLACK);
    render.setCursor(30, 80);
    render.printf("Date: %04d/%02d/%02d", now_date.year, now_date.month, now_date.day);
    old_date = now_date;
}

if (!isTimeSame(now_time, old_time)) {
    M5.Lcd.fillRect(30, 110, 260, 26, BLACK);
    render.setCursor(30, 110);
    render.printf("Time: %02d:%02d:%02d", now_time.hour, now_time.min, now_time.sec);
    old_time = now_time;
}

📡 Future Communication Options (UDP vs TCP)

FeatureUDPTCP
ReliabilityMay drop packetsGuaranteed delivery
SpeedVery fastSlower
ComplexitySimpleMore complex
Best UseNTP, broadcastSettings, two‑way control

UDP is ideal for time sync, while TCP is ideal for configuration commands.

🚀 Why DualCore Was Essential

When Wi‑Fi communication (especially TCP sockets) is added:

  • Rendering may lag
  • Time updates may stutter
  • UI may freeze

DualCore ensures:

  • Rendering stays smooth
  • RTC updates remain accurate
  • Network tasks never block UI

🧭 Summary

This enhanced version of the M5Stack RTC clock provides:

  • Accurate RTC timekeeping
  • Smooth anti‑aliased rendering
  • Efficient DualCore task separation
  • Flicker‑free selective updates
  • Expandable communication options

It is a robust foundation for clocks, dashboards, IoT displays, and embedded UI systems.

コメント