Arduino UNO R4 - DIYables Bluetooth App RTC
The Bluetooth RTC example provides real-time clock synchronization through the DIYables Bluetooth STEM app. Designed for Arduino UNO R4 WiFi using BLE (Bluetooth Low Energy) to sync the board's built-in hardware RTC with your smartphone's clock and display the time. The Arduino UNO R4 WiFi has a built-in RTC module, making it ideal for timekeeping projects without needing external RTC hardware. Perfect for clocks, data logging with timestamps, scheduled automation, and time-based projects.
Note: The Arduino UNO R4 WiFi only supports BLE (Bluetooth Low Energy). It does not support Classic Bluetooth. The DIYables Bluetooth App supports both BLE and Classic Bluetooth on Android, and BLE on iOS. Since this board uses BLE, the app works on both Android and iOS.
Built-in Hardware RTC: Uses Arduino UNO R4 WiFi's onboard RTC — no external module needed
Phone Time Sync: Sync time from smartphone via Unix timestamp or local time components
Real-Time Display: Show current time on the app, updated every second
Time Request: App can request current time from the board
Persistent Timekeeping: RTC keeps time while board is powered
Works on Android & iOS: BLE is supported on both platforms
No Pairing Required: BLE auto-connects without manual pairing
Or you can buy the following kits:
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand,
DIYables .
Note: No external RTC module is needed! The Arduino UNO R4 WiFi has a built-in hardware RTC accessible via the RTC.h library.
Follow these instructions step by step:
Connect the Arduino UNO R4 WiFi board to your computer using a USB cable.
Launch the Arduino IDE on your computer.
Select Arduino UNO R4 WiFi board and the appropriate COM port.
Navigate to the Libraries icon on the left bar of the Arduino IDE.
Search "DIYables Bluetooth", then find the DIYables Bluetooth library by DIYables
Click Install button to install the library.


#include <DIYables_BluetoothServer.h>
#include <DIYables_BluetoothRTC.h>
#include <platforms/DIYables_ArduinoBLE.h>
#include "RTC.h"
const char* DEVICE_NAME = "Arduino_RTC";
const char* SERVICE_UUID = "19B10000-E8F2-537E-4F6C-D104768A1214";
const char* TX_UUID = "19B10001-E8F2-537E-4F6C-D104768A1214";
const char* RX_UUID = "19B10002-E8F2-537E-4F6C-D104768A1214";
DIYables_ArduinoBLE bluetooth(DEVICE_NAME, SERVICE_UUID, TX_UUID, RX_UUID);
DIYables_BluetoothServer bluetoothServer(bluetooth);
DIYables_BluetoothRTC bluetoothRTC;
void setup() {
Serial.begin(9600);
delay(1000);
Serial.println("DIYables Bluetooth - RTC Example");
RTC.begin();
RTCTime savedTime;
RTC.getTime(savedTime);
if (!RTC.isRunning() || savedTime.getYear() == 2000) {
Serial.println("RTC is NOT running, setting initial time...");
RTCTime startTime(28, Month::AUGUST, 2025, 12, 0, 0, DayOfWeek::THURSDAY, SaveLight::SAVING_TIME_ACTIVE);
RTC.setTime(startTime);
Serial.println("RTC initialized with default time");
} else {
Serial.println("RTC is already running");
}
RTCTime initialTime;
RTC.getTime(initialTime);
Serial.print("Initial RTC Time: ");
Serial.print(initialTime.getYear());
Serial.print("/");
Serial.print(Month2int(initialTime.getMonth()));
Serial.print("/");
Serial.print(initialTime.getDayOfMonth());
Serial.print(" - ");
if (initialTime.getHour() < 10) Serial.print("0");
Serial.print(initialTime.getHour());
Serial.print(":");
if (initialTime.getMinutes() < 10) Serial.print("0");
Serial.print(initialTime.getMinutes());
Serial.print(":");
if (initialTime.getSeconds() < 10) Serial.print("0");
Serial.print(initialTime.getSeconds());
Serial.println();
bluetoothServer.begin();
bluetoothServer.addApp(&bluetoothRTC);
bluetoothServer.setOnConnected([]() {
Serial.println("Bluetooth connected!");
sendCurrentTimeToApp();
});
bluetoothServer.setOnDisconnected([]() {
Serial.println("Bluetooth disconnected!");
});
bluetoothRTC.onTimeSync(onTimeSyncReceived);
bluetoothRTC.onLocalTimeSync(onLocalTimeSyncReceived);
bluetoothRTC.onTimeRequest(onTimeRequested);
Serial.println("Waiting for Bluetooth connection...");
Serial.println("Connect via app to sync time");
}
void loop() {
bluetoothServer.loop();
static unsigned long lastUpdate = 0;
if (millis() - lastUpdate >= 1000) {
lastUpdate = millis();
RTCTime currentTime;
RTC.getTime(currentTime);
bluetoothRTC.sendTime(currentTime.getYear(), Month2int(currentTime.getMonth()),
currentTime.getDayOfMonth(), currentTime.getHour(),
currentTime.getMinutes(), currentTime.getSeconds());
Serial.print("RTC Time: ");
Serial.print(currentTime.getYear());
Serial.print("/");
Serial.print(Month2int(currentTime.getMonth()));
Serial.print("/");
Serial.print(currentTime.getDayOfMonth());
Serial.print(" - ");
if (currentTime.getHour() < 10) Serial.print("0");
Serial.print(currentTime.getHour());
Serial.print(":");
if (currentTime.getMinutes() < 10) Serial.print("0");
Serial.print(currentTime.getMinutes());
Serial.print(":");
if (currentTime.getSeconds() < 10) Serial.print("0");
Serial.print(currentTime.getSeconds());
Serial.println();
}
delay(10);
}
void onTimeSyncReceived(unsigned long unixTimestamp) {
Serial.print("Time sync received (Unix): ");
Serial.println(unixTimestamp);
RTCTime newTime;
newTime.setUnixTime(unixTimestamp);
RTC.setTime(newTime);
Serial.println("Arduino RTC synchronized from Unix timestamp!");
}
void onLocalTimeSyncReceived(int year, int month, int day, int hour, int minute, int second) {
Serial.print("Local time sync received: ");
Serial.print(year);
Serial.print("/");
Serial.print(month);
Serial.print("/");
Serial.print(day);
Serial.print(" ");
Serial.print(hour);
Serial.print(":");
Serial.print(minute);
Serial.print(":");
Serial.println(second);
Month monthEnum;
switch(month) {
case 1: monthEnum = Month::JANUARY; break;
case 2: monthEnum = Month::FEBRUARY; break;
case 3: monthEnum = Month::MARCH; break;
case 4: monthEnum = Month::APRIL; break;
case 5: monthEnum = Month::MAY; break;
case 6: monthEnum = Month::JUNE; break;
case 7: monthEnum = Month::JULY; break;
case 8: monthEnum = Month::AUGUST; break;
case 9: monthEnum = Month::SEPTEMBER; break;
case 10: monthEnum = Month::OCTOBER; break;
case 11: monthEnum = Month::NOVEMBER; break;
case 12: monthEnum = Month::DECEMBER; break;
default: monthEnum = Month::JANUARY; break;
}
RTCTime newTime(day, monthEnum, year, hour, minute, second, DayOfWeek::MONDAY, SaveLight::SAVING_TIME_ACTIVE);
RTC.setTime(newTime);
Serial.println("Arduino RTC synchronized from local time components!");
}
void onTimeRequested() {
Serial.println("Time requested by app");
sendCurrentTimeToApp();
}
void sendCurrentTimeToApp() {
RTCTime currentTime;
RTC.getTime(currentTime);
bluetoothRTC.sendTime(currentTime.getYear(), Month2int(currentTime.getMonth()),
currentTime.getDayOfMonth(), currentTime.getHour(),
currentTime.getMinutes(), currentTime.getSeconds());
}
DIYables Bluetooth - RTC Example
Waiting for Bluetooth connection...
RTC not running or year is 2000, waiting for time sync...
Install the DIYables Bluetooth App on your smartphone:
Android |
iOS
Note: The DIYables Bluetooth App supports both BLE and Classic Bluetooth on Android, and BLE on iOS. Since the Arduino UNO R4 WiFi uses BLE, the app works on both Android and iOS. No manual pairing is needed for BLE — just scan and connect.
Open the DIYables Bluetooth App
When opening the app for the first time, it will ask for permissions. Please grant the following:
Nearby Devices permission (Android 12+) / Bluetooth permission (iOS) - required to scan and connect to Bluetooth devices
Location permission (Android 11 and below only) - required by older Android versions to scan for BLE devices
Make sure Bluetooth is turned on on your phone
On the home screen, tap the Connect button. The app will scan for BLE devices.
Find and tap "Arduino_RTC" in the scan results to connect.
Once connected, the app automatically goes back to the home screen. Select the RTC app from the app menu.
Note: You can tap the settings icon on the home screen to hide/show apps on the home screen. For more details, see the DIYables Bluetooth App User Manual.
The app will display the current time from the Arduino's RTC
Use the Sync button to sync the phone's time to the Arduino
The time updates every second
Now look back at the Serial Monitor on Arduino IDE. You will see:
Bluetooth connected!
Time sync received (unix): 1719849600
RTC set to: 2025/07/01 12:00:00
Current time: 2025/07/01 12:00:01
Current time: 2025/07/01 12:00:02
The app can sync time to the Arduino using two methods:
bluetoothRTC.onTimeSync([](unsigned long unixTime) {
Serial.print("Unix time: ");
Serial.println(unixTime);
});
bluetoothRTC.onLocalTimeSync([](int year, int month, int day, int hour, int minute, int second) {
Serial.print("Local time: ");
Serial.print(year);
Serial.print("/");
Serial.print(month);
Serial.print("/");
Serial.println(day);
});
bluetoothRTC.sendTime(year, month, day, hour, minute, second);
bluetoothRTC.onTimeRequest([]() {
RTCTime currentTime;
RTC.getTime(currentTime);
bluetoothRTC.sendTime(
currentTime.getYear(),
Month2int(currentTime.getMonth()),
currentTime.getDayOfMonth(),
currentTime.getHour(),
currentTime.getMinutes(),
currentTime.getSeconds()
);
});
The Arduino UNO R4 WiFi's built-in RTC is accessed via the RTC.h library:
#include "RTC.h"
void setup() {
RTC.begin();
}
RTCTime timeToSet;
timeToSet.setYear(2025);
timeToSet.setMonth(Month::JULY);
timeToSet.setDayOfMonth(1);
timeToSet.setHour(12);
timeToSet.setMinute(0);
timeToSet.setSecond(0);
RTC.setTime(timeToSet);
RTCTime currentTime;
RTC.getTime(currentTime);
int year = currentTime.getYear();
int month = Month2int(currentTime.getMonth());
int day = currentTime.getDayOfMonth();
int hour = currentTime.getHour();
int minute = currentTime.getMinutes();
int second = currentTime.getSeconds();
void loop() {
bluetoothServer.loop();
static unsigned long lastTime = 0;
if (millis() - lastTime >= 1000) {
lastTime = millis();
RTCTime currentTime;
if (RTC.getTime(currentTime)) {
char timeStr[20];
sprintf(timeStr, "%04d/%02d/%02d %02d:%02d:%02d",
currentTime.getYear(),
Month2int(currentTime.getMonth()),
currentTime.getDayOfMonth(),
currentTime.getHour(),
currentTime.getMinutes(),
currentTime.getSeconds());
Serial.println(timeStr);
bluetoothRTC.sendTime(
currentTime.getYear(),
Month2int(currentTime.getMonth()),
currentTime.getDayOfMonth(),
currentTime.getHour(),
currentTime.getMinutes(),
currentTime.getSeconds()
);
}
}
}
void logSensorData() {
RTCTime currentTime;
RTC.getTime(currentTime);
float temperature = readSensor();
char logEntry[50];
sprintf(logEntry, "%04d/%02d/%02d %02d:%02d:%02d - Temp: %.1f°C",
currentTime.getYear(),
Month2int(currentTime.getMonth()),
currentTime.getDayOfMonth(),
currentTime.getHour(),
currentTime.getMinutes(),
currentTime.getSeconds(),
temperature);
Serial.println(logEntry);
}
1. Cannot find the device in the app
Make sure the Arduino UNO R4 WiFi is powered on and the sketch is uploaded
Ensure your phone's Bluetooth is enabled
On Android 11 and below, also enable Location services
2. Time shows 2000/01/01 or incorrect time
The RTC needs to be synced at least once after power-up
Use the Sync button in the app to set the time
The RTC loses time when the board is powered off (no battery backup)
3. Time not syncing from app
Verify the onTimeSync and onLocalTimeSync callbacks are set up
Check the Serial Monitor for sync messages
Ensure the BLE connection is stable
4. RTC drifts over time
The built-in RTC crystal has limited accuracy
Re-sync periodically via the app
For critical timing, consider using NTP over WiFi as well
5. Month conversion issues
The Arduino UNO R4 WiFi RTC uses a Month enum, not integer
Use a conversion function (like Month2int() in the example) for integer months
Months are 1-based (January = 1)
6. Upload fails or board not recognized
Digital clock with BLE time sync
Data logger with accurate timestamps
Scheduled task automation (turn on/off at specific times)
Alarm clock with smartphone control
Time-stamped event recorder
After mastering the Bluetooth RTC example, try:
Bluetooth Monitor - For text-based status display with timestamps
Bluetooth Table - For structured data with time fields
Bluetooth Chat - For two-way communication
Multiple Bluetooth Apps - Combining RTC with other apps