Ở các bài trước, chúng ta đã gửi dữ liệu realtime lên IoTLabs Cloud.
Tuy nhiên, một câu hỏi rất quan trọng trong hệ IoT thực tế là:
Nếu mất mạng, reboot, hoặc chạy offline thì thời gian lấy ở đâu?
Câu trả lời chính là RTC – Real Time Clock, và DS3231 là lựa chọn ổn định – chính xác – phổ biến nhất cho ESP32.
1. Vì sao IoT cần RTC?
Trong hệ IoT thực tế, RTC giúp bạn:
- Ghi timestamp chính xác khi:
- Mất WiFi
- MQTT chưa kết nối
- Thiết bị reboot
- Lưu log offline (SD / Flash)
- Đồng bộ dữ liệu khi online trở lại
- Giảm phụ thuộc vào NTP / Internet
👉 RTC là mảnh ghép bắt buộc khi IoT bước sang “production-ready”.
2. Giới thiệu cảm biến DS3231
DS3231 là RTC chất lượng cao, thường dùng trong:
- Data logger
- Thiết bị chạy lâu ngày
- IoT offline / intermittent network
Thông số nổi bật:
- Giao tiếp: I2C
- Độ chính xác cao (bù nhiệt)
- Có pin CR2032 → giữ giờ khi mất điện
- Địa chỉ I2C:
0x68
3. Chuẩn bị phần cứng & nối dây
Thiết bị
- ESP32-C3 SuperMini
- Module DS3231 (RTC + pin)
Kết nối I2C (chuẩn series)
| DS3231 | ESP32-C3 |
|---|---|
| VCC | 3.3 V |
| GND | GND |
| SDA | GPIO8 |
| SCL | GPIO9 |
📌 DS3231 dùng chung bus I2C với các sensor khác (BME280, SHT31…).
4. Kiểm tra địa chỉ I2C
#include <Wire.h>
void setup() {
Serial.begin(115200);
Wire.begin(8, 9);
}
void loop() {
for (byte addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) {
Serial.print("Found I2C device at 0x");
Serial.println(addr, HEX);
}
}
delay(5000);
}
👉 Thấy 0x68 → DS3231 hoạt động.
5. Ví dụ 1: Đọc thời gian từ DS3231 (local)
Thư viện
- RTClib (Adafruit)
Code mẫu
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;
void setup() {
Serial.begin(115200);
Wire.begin(8, 9);
if (!rtc.begin()) {
Serial.println("DS3231 not found");
while (1) delay(10);
}
// Set time 1 lần (comment lại sau khi set)
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
void loop() {
DateTime now = rtc.now();
Serial.print(now.year()); Serial.print("-");
Serial.print(now.month()); Serial.print("-");
Serial.print(now.day()); Serial.print(" ");
Serial.print(now.hour()); Serial.print(":");
Serial.print(now.minute()); Serial.print(":");
Serial.println(now.second());
delay(1000);
}
📌 Chỉ cần set thời gian 1 lần, sau đó RTC tự chạy bằng pin.
6. Chuẩn timestamp dùng trong IoTLabs Cloud
IoTLabs Cloud dùng Unix timestamp (seconds):
{
"ts": 1760000000,
"metrics": {
"temperature": 26.8
}
}
👉 ts lấy trực tiếp từ DS3231, không phụ thuộc millis() hay NTP.
7. Ví dụ 2: Gửi timestamp RTC lên IoTLabs Cloud MQTT
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;
// ===== CONFIG =====
const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASS = "YOUR_PASS";
const char* MQTT_HOST = "mqtt.iotlabs.vn";
const int MQTT_PORT = 8883;
const char* MQTT_USER = "YOUR_MQTT_USER";
const char* MQTT_PASS = "YOUR_MQTT_PASS";
const char* MQTT_TOPIC =
"iotlabs/<orgId>/devices/<deviceId>/telemetry";
WiFiClientSecure net;
PubSubClient mqtt(net);
unsigned long lastSend = 0;
void connectWiFi() {
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
}
void connectMQTT() {
net.setInsecure();
mqtt.setServer(MQTT_HOST, MQTT_PORT);
while (!mqtt.connected()) {
mqtt.connect("esp32c3-ds3231", MQTT_USER, MQTT_PASS);
delay(1000);
}
}
void setup() {
Serial.begin(115200);
Wire.begin(8, 9);
rtc.begin();
connectWiFi();
connectMQTT();
}
void loop() {
if (!mqtt.connected()) connectMQTT();
mqtt.loop();
if (millis() - lastSend > 5000) {
lastSend = millis();
DateTime now = rtc.now();
long ts = now.unixtime();
String payload = "{";
payload += "\"ts\":" + String(ts) + ",";
payload += "\"metrics\":{";
payload += "\"rtc\":1";
payload += "}}";
mqtt.publish(MQTT_TOPIC, payload.c_str());
Serial.println(payload);
}
}
8. RTC + IoT = tư duy hệ thống
Khi kết hợp DS3231 với các sensor khác, bạn có thể:
- Ghi log offline → sync khi online
- Gửi dữ liệu đúng timestamp
- Debug dễ hơn (biết chính xác lúc xảy ra sự kiện)
- Xây hệ store-and-forward chuẩn bài
👉 Đây là bước chuyển từ DIY → hệ IoT đúng nghĩa.
9. Tổng kết Bài 18
Sau bài này, bạn đã:
- Làm chủ RTC DS3231
- Tạo timestamp độc lập Internet
- Hoàn thiện tư duy I2C + multi-sensor + time
- Sẵn sàng bước sang Level 3 – hệ thống IoT thực tế
👉 Tiếp theo: Tổng kết Level 2 – I2C & tư duy hệ thống IoT


