Xiao ESP32-S3 Expansion Board pcf8563 WiFi UDP NTP? Can do

Hello!

Been fiddling with the Expansion Board and its NXP PCF8563 RTC. I tried the the Seeed Wiki (here). Meh. The lib is old as dirt and …

But, let’s address the solder blobs on the ground pad of the CR1220 battery carrier. Three boards and all required getting in there and sanding that down. If anyone else has problems with the RTC maintaining its time, yeah get in there and clean that pad up. Three of three boards presented with this problem. If not seeing power at the chip with a fresh CR1220? Check that pad.


1200-grit wet-dry swiping out ground pad

Moving on…

Not being a fan of this non-sense any longer…not since I got me some new WiFi-(on)boards…

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

…Time to work on using the ESP32-S3 to pull me down some time updates from the NTP pool. Yippee! And it was pretty quick.

Found the basics from this person’s post at Instructables. The article describes using the Adafruit fork of RTClib and the Adafruit GFX and SSD1306 libs, both of which I am familiar with. The RTClib offers far more utility than that offered in the Wiki referred to above. Not one I was familiar with, the EasyNTPClient lib will need be installed.

In the sketch below, the date, time, and day of week are printed to Serial and the OLED about every second using millis(). Serial can be turned off and on at the #define Serial. Wanting some routine NTP updates, for now about every 6 hours…

I write slow, bloaty, nooby code…but it works!

//  Xiao ESP32-S3 Expansion Board pcf8563 WiFi UDP NTP

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#include <RTClib.h>
#include <WiFi.h>
#include <WiFiUdp.h>
#include <EasyNTPClient.h>
#include "arduino_secrets.h"

#define SERIAL 1

#define SCREEN_WIDTH 128  // OLED display width, in pixels
#define SCREEN_HEIGHT 64  // OLED display height, in pixels

int timezone = -36000; // -10;  //this is GMT -10, HST.
// int wifiStatus = WL_IDLE_STATUS;
char ssid[] = SECRET_SSID;  // your network SSID (name)ntp
char pass[] = SECRET_PASS;  // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;           // your network key index number (needed only for WEP)

DateTime now;
WiFiUDP udp;

constexpr unsigned long printInterval{ 1000 };
unsigned long printNow{};

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

RTC_PCF8563 rtc;

char daysOfTheWeek[7][12] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };

EasyNTPClient ntpClient(udp, "pool.ntp.org", timezone); //-36000);  // HST = -36000 seconds


//  ************  SETUP  ***************  //
void setup() {
  Serial.begin(115200);

  WiFi.setSleep(false);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print("Connecting to SSID: ");
    Serial.println(ssid);
    /*wifiStatus = */ WiFi.begin(ssid, pass);
    delay(4000);  // can extend to 4-6secs if not connecting

    Serial.println("Connected to WiFi.");
    // printWifiStatus();
  }

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {  // Address 0x3C for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ;
  }

  rtc.begin();
  rtc.start();

  // WiFi.disconnect();

}  // end setup

//  *************  LOOP  **************  //
void loop() {

  if (millis() > printNow) {
    now = rtc.now();  // PCF8563 RTC
#if SERIAL
    printTime();
#endif
    displayTime();
    checkTime();
    printNow = millis() + printInterval;
  }
}  // end loop

//  **************  FUNCTIONS  ***************  //
void printWifiStatus() {
  IPAddress ip = WiFi.localIP();
  long rssi = WiFi.RSSI();

  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  //IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");

  display.clearDisplay();
  display.setCursor(0, 0);
  display.setTextSize(1);
  display.println("> Connxn -> ");
  display.setCursor(15, 15);
  display.println(ssid);
  display.display();
}

void printTime() {
  Serial.print(now.year(), DEC);
  Serial.print('/');
  if (now.month() < 10) { Serial.print("0"); }
  Serial.print(now.month(), DEC);
  Serial.print('/');
  if (now.day() < 10) { Serial.print("0"); }
  Serial.print(now.day(), DEC);
  Serial.print(" (");
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(") ");
  if (now.hour() < 10) { Serial.print("0"); }
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  if (now.minute() < 10) { Serial.print("0"); }
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  if (now.second() < 10) { Serial.print("0"); }
  Serial.print(now.second(), DEC);
  Serial.println();
}

void displayTime() {
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);

  display.setCursor(0, 0);
  display.print(now.year());
  display.print('/');
  if (now.month() < 10) { display.print("0"); }
  display.print(now.month());
  display.print('/');
  if (now.day() < 10) { display.print("0"); }
  display.println(now.day());

  display.setCursor(0, 22);
  if (now.hour() < 10) { display.print("0"); }
  display.print(now.hour());
  display.print(':');
  if (now.minute() < 10) { display.print('0'); }
  display.print(now.minute());
  display.print(':');
  if (now.second() < 10) { display.print('0'); }
  display.print(now.second());

  display.setCursor(0, 45);
  display.print(daysOfTheWeek[now.dayOfTheWeek()]);

  display.display();
}

void checkTime() {
  now = rtc.now();  // get latest time from PCF8563 RTC

  int currHour = now.hour();
  int currMin = now.minute();
  int currSec = now.second();

  if (currMin == 0) {
    if (currSec <= 1) {
      // insert here bell at top of hour
    }
  }

  if (currHour % 6 == 0) {
    if (currMin == 1) {
      if (currSec <= 1) {
        // insert here function to get NTP updated time
        now = ntpClient.getUnixTime() + 1;  // fetch time
        rtc.adjust(now);                    // set RTC
#if SERIAL
        Serial.println("Time set");
#endif
      }
    }
  }
}

All da best,