What Time Is It? Seeed XIAO with Expansion Board Answers

Alwin Arrasyid
3 min readJan 30, 2022

--

Alarm clock
Photo by Sarah Pflug from Burst.

Seeed Studio’s XIAO Expansion Board adds rich features to the already feature-rich XIAO boards, especially to XIAO BLE Sense. It adds a 128x64 pixels OLED screen with SSD1306 driver, SD card slot, battery charger with power path management, also real-time clock IC with a CR1220 battery slot.

The expansion board uses PCF8563, a CMOS real-time clock (RTC). It provides year, month, day, weekday, hours, minutes, and seconds based on a 32.768 kHz quartz crystal. The RTC consumes 250 nano amperes when the interface is inactive. It uses Inter-Integrated Circuit (IIC) as the communication protocol with the controller.

Before we go further, the rest of the post is only relevant to XIAO boards with Arduino Mbed Core support such as XIAO BLE (Sense) and XIAO RP2040. But you are free to read along even if you don’t have those boards.

The official documentation for Seeed XIAO Expansion Board provides an example that uses a library made by Krzysztof Adamkiewicz. The library is relatively easy to use. It allows us to get the current time, set the initial time (one-time activity), and enable or disable clock output.

Adamkiewicz’s library is probably good enough for your use cases. But, if your use case requires you to provide timestamps in epoch format, you need to do extra work. We can utilize the C time APIs for this purpose.

In short, we need to convert the date and time struct provided by Adamkiewicz’s library to the struct tm format. Then use the mktime function to convert the struct to the time_t data type representing the number of seconds since January 1, 1990. Then, we need to set the current time to that value using the set_time function. You only need to do this after booting the microcontroller.

In other words, do everything in the setup function, then get the current timestamp in the loop function. It is as easy as it sounds.

Include the necessary header file.

#include "platform/mbed_rtc_time.h"

Then create the conversion function.

time_t time_from_rtc(Time &pcfTime)
{
struct tm timeinfo = {0};
timeinfo.tm_year = pcfTime.year + 100;
timeinfo.tm_mon = pcfTime.month - 1;
timeinfo.tm_mday = pcfTime.day;
timeinfo.tm_hour = pcfTime.hour;
timeinfo.tm_min = pcftime.minute;
timeinfo.tm_sec = pcfTime.second;
timeinfo.tm_isdst = 0; // or 1
return mktime(&timeinfo);
}

The tm struct’s tm_year field requires the number of the year since 1900, but the pcfTime’s year field stores the number of years since 2000. So we need to add the number with 100. Also, the tm struct’s tm_mon field requires the months to start from 0, not 1. If your timezone uses daylight saving time (DST), you probably need to set the tm_isdst field to 1.

Time pcfTime = rtc.getTime();
time_t now = time_from_rtc(&pcfTime);
set_time(now);

Now you can get the current timestamp using the time function.

time_t now = time(nullptr);

You can see the complete code on my GitHub repository.

Thanks for reading! See you in the next post.

--

--

Alwin Arrasyid
Alwin Arrasyid

Written by Alwin Arrasyid

Principal Engineer, working on better IoT solutions and enabling AI on the edge.

No responses yet