reloj 3 — Xiao Esp32 S3 simulation

An interactive Xiao Esp32 S3 circuit simulation you can run free in your browser on Velxio, by dave.

Components

Sketch code

// Reloj digital en la Seeed Round Display para XIAO ESP32-S3
//
// La pantalla redonda es un GC9A01 (240x240) por SPI y el shield trae un
// reloj de tiempo real PCF8563 por I2C: la hora sale del RTC, no de millis().
//
// Pines del shield tal como Seeed los cablea al header de la XIAO
// (Setup66_Seeed_XIAO_Round.h), escritos como GPIO para que el sketch diga
// lo que hace:
//   silk   XIAO ESP32S3
//   CS     D1  -> GPIO2      SCK   D8  -> GPIO7
//   DC     D3  -> GPIO4      MISO  D9  -> GPIO8
//   BL     D6  -> GPIO43     MOSI  D10 -> GPIO9
//   SDA    D4  -> GPIO5      SCL   D5  -> GPIO6
#include <M5GFX.h>
#include <lgfx/v1/panel/Panel_GC9A01.hpp>   // M5GFX.h no lo incluye
#include <Wire.h>
#include <SPI.h>

static const int PIN_CS = 2, PIN_DC = 4, PIN_BL = 43;
static const int PIN_SCK = 7, PIN_MISO = 8, PIN_MOSI = 9;

class RoundDisplay : public lgfx::LGFX_Device {
  lgfx::Panel_GC9A01 _gc9a01;
  lgfx::Bus_SPI _spi;
 public:
  RoundDisplay() {
    {
      auto cfg = _spi.config();
      cfg.spi_host = SPI2_HOST;
      cfg.spi_mode = 0;
      cfg.freq_write = 40000000;
      cfg.pin_sclk = PIN_SCK;
      cfg.pin_mosi = PIN_MOSI;
      cfg.pin_miso = PIN_MISO;
      cfg.pin_dc = PIN_DC;
      _spi.config(cfg);
      _gc9a01.setBus(&_spi);
    }
    {
      auto cfg = _gc9a01.config();
      cfg.pin_cs = PIN_CS;
      cfg.pin_rst = -1;          // el shield no tiene linea de reset
      cfg.panel_width = 240;
      cfg.panel_height = 240;
      cfg.invert = true;         // el cristal GC9A01 va invertido (INVON)
      _gc9a01.config(cfg);
    }
    setPanel(&_gc9a01);
  }
};

static RoundDisplay tft;

// ── PCF8563 (I2C 0x51): hora en BCD desde el registro 0x02 ──────────────
static const uint8_t RTC_ADDR = 0x51;
static uint8_t bcd2dec(uint8_t b) { return (b >> 4) * 10 + (b & 0x0f); }
static uint8_t dec2bcd(uint8_t d) { return ((d / 10) << 4) | (d % 10); }

static void rtcSet(uint8_t h, uint8_t m, uint8_t s) {
  Wire.beginTransmission(RTC_ADDR);
  Wire.write(0x02);
  Wire.write(dec2bcd(s));   // bit VL a 0: oscilador de confianza
  Wire.write(dec2bcd(m));
  Wire.write(dec2bcd(h));
  Wire.endTransmission();
}

// sec, min, hour, day, weekday, month, year (7 registros seguidos)
static bool rtcRead(uint8_t &h, uint8_t &m, uint8_t &s,
                    uint8_t &day, uint8_t &wd, uint8_t &mon, uint8_t &yr) {
  Wire.beginTransmission(RTC_ADDR);
  Wire.write(0x02);
  if (Wire.endTransmission() != 0) return false;
  if (Wire.requestFrom((int)RTC_ADDR, 7) != 7) return false;
  s   = bcd2dec(Wire.read() & 0x7f);
  m   = bcd2dec(Wire.read() & 0x7f);
  h   = bcd2dec(Wire.read() & 0x3f);
  day = bcd2dec(Wire.read() & 0x3f);
  wd  = Wire.read() & 0x07;
  mon = bcd2dec(Wire.read() & 0x1f);
  yr  = bcd2dec(Wire.read());
  return true;
}

static const char *DIAS[] = { "DOM", "LUN", "MAR", "MIE", "JUE", "VIE", "SAB" };

static const int CX = 120, CY = 120;
static uint8_t lastS = 255, lastM = 255, lastDay = 255;

static void drawFrame() {
  tft.fillScreen(TF

More projects by dave