ماژول ساعت واقعی DS3231
ماژول ساعت واقعی DS3231 را با I2C به آردوینو وصل میکنید، با کتابخانهٔ RTClib زمان را تنظیم و میخوانید و تفاوت DS3231 با DS1307 و رفتار باتری پشتیبان CR2032 را میآموزید.
آنچه در این درس میآموزید
- توضیح دهید چرا آردوینو ساعت داخلی ندارد و ماژول RTC چه مشکلی را حل میکند
- DS3231 را روی گذرگاه I2C سیمکشی کنید و کتابخانهٔ RTClib را نصب کنید
- زمان را هنگام کامپایل تنظیم کنید و پس از قطع تغذیه، با باتری پشتیبان حفظش کنید
فهرست مطالب
هر برنامهای که با «ساعت چند است؟» سروکار دارد — آبیاری گلدان ساعت ۷ صبح، ثبت زمان ورود کارت، نمایشگر دیواری — به یک ساعت واقعی نیاز دارد. اما یک واقعیت ناخوشایند: آردوینو Uno هیچ ساعتی ندارد. millis فقط مدتزمان از شروع روشن بودن را میشمارد و با قطع تغذیه، همهچیز از صفر میشود. ماژول ساعت واقعی (Real-Time Clock یا RTC) دقیقاً همین شکاف را پر میکند: یک چیپ اختصاصی شمارش زمان که با باتری سکهای، از قطع برق هم عبور میکند. در این درس ماژول محبوب DS3231 را سیمکشی میکنید، با کتابخانهٔ RTClib زمان را تنظیم و میخوانید و یاد میگیرید چرا این چیپ به دقت معروف است.
DS3231 و راز دقتش
سازندهٔ DS3231 شرکت Maxim است که امروز بخشی از Analog Devices است. این ماژول جایگزین مدرن نسل قدیمی DS1307 است و تفاوتشان یک تفاوت مهندسی جدی است: هر بلور کوارتز با دما، کمی در فرکانس لغزش میکند. DS1307 یک کریستال ۳۲٫۷۶۸ کیلوهرتزی خارجی کنار خودش میخواهد و به تغییر دما بیتوجه است — نتیجه، چند ثانیه لغزش در روز. DS3231 اما کریستال را داخل خودش دارد و با سنسور دمایی داخلی، خطای دما را لحظهبهلحظه جبران میکند (TCXO — اسیلاتور جبرانشدهٔ دمایی)؛ دیتاشیت خطایش را فقط حدود ±۲ دقیقه در سال اعلام میکند و کریستال جداگانه هم نمیخواهد. اگر ماژولی خریدید، تعداد پینها را ببینید: DS3231 فقط ۶ پین دارد و DS1307 معمولاً ۵ پین با کریستال بیرونی.
وقت خواندن و نوشتن هم روی گذرگاه I2C رد و بدل میشود و آدرس ماژول 0x68 است. اگر با این گذرگاه کار نکردهاید، درس پروتکل I2C پیشنیاز خوبی است؛ اسکنر آدرسی که آنجا ساختید، اینجا هم برای اطمینان از دیدن 0x68 به کار میآید.
پینها و سیمکشی
| پین ماژول | نقش |
|---|---|
| VCC | تغذیه؛ ۳٫۳ تا ۵ ولت |
| GND | زمین |
| SDA | خط دادهٔ I2C |
| SCL | خط ساعت I2C |
| SQW | خروجی موج مربع با فرکانس قابل تنظیم (در این درس بلااستفاده) |
| 32K | خروجی کلاک ۳۲٫۷۶۸ کیلوهرتز خام (در این درس بلااستفاده) |
| آردوینو Uno | ماژول DS3231 |
|---|---|
| 5V | VCC |
| GND | GND |
| A4 | SDA |
| A5 | SCL |
پشت ماژول، جای باتری سکهای CR2032 است. با نصب باتری، وقتی VCC قطع شود، RTC با همان چند میکروآمپر مصرف دائمی، زمان را شمارش ادامه میدهد؛ به محض برگشت تغذیهٔ اصلی، ماژول بدون هیچ تنظیم مجددی زمان درست میدهد.
نصب کتابخانه
- در Arduino IDE به Tools ← Manage Libraries بروید (یا آیکن کتابخانه در نوار کناری).
- عبارت
RTClibرا جستوجو کنید. - بستهٔ RTClib از Adafruit را نصب کنید؛ اگر پنجرهٔ وابستگیها باز شد، Install all بزنید.
- برای تأیید، منوی File > Examples باید مثالهای RTClib را نشان دهد.
اسکچ کامل: تنظیم و خواندن زمان
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;
void setup() {
Serial.begin(9600);
if (!rtc.begin()) {
Serial.println("RTC not found");
while (1) delay(10);
}
// Set the RTC time to the moment this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
if (rtc.lostPower()) {
Serial.println("RTC lost power, time was just set");
}
Serial.println("DS3231 ready");
}
void loop() {
DateTime now = rtc.now();
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(" ");
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.println(now.second(), DEC);
delay(1000);
}توضیح نکتههای تازه:
rtc.begin()— راهاندازی RTC روی گذرگاه I2C؛ اگر ماژول پاسخ ندهد پیام RTC not found چاپ میشود و برنامه میایستد تا دادهٔ غلط تولید نشود.rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));— نکتهٔ کلیدی درس.__DATE__و__TIME__ماکروهای کامپایلرند که هنگام ساختن فایل، تاریخ و ساعت کامپیوتر شما را در کد میگذارند؛ یعنی RTC دقیقاً با لحظهٔ آپلود اسکچ تنظیم میشود.F()رشته را در فلش نگه میدارد تا RAM هدر نرود.rtc.lostPower()— اگر RTC بهخاطر قطع کامل تغذیه و نبود باتری، زمان را از دست داده باشد true میدهد؛ اینجا از آن فقط برای گزارش استفاده میکنیم.- چاپ دو رقمی — بهجای کتابخانهٔ قالببندی، اعداد تکرقمی را با یک صفر پیشوند میچاپیم تا
09:05به شکل9:5خراب نشود.
خروجی سریال مانیتور هر ثانیه یک خط است (تاریخ و ساعت با زمان واقعی شما یکی است؛ این نمونه است):
DS3231 ready 2026-10-31 14:20:05 2026-10-31 14:20:06 2026-10-31 14:20:07
رفتار باتری پشتیبان
CR2032 حدود ۳ ولت میدهد و در حالت عادی چند سال دوام میآورد؛ RTC در تغذیهٔ باتری فقط چند میکروآمپر میکشد. دو نشانهٔ سلامت را به خاطر بسپارید: اگر پس از قطع تغذیهٔ اصلی و وصلکردن مجدد، زمان درست بود، باتری کار میکند؛ اگر زمان به مقدار پیشفرض چیپ برگشته بود، باتری تمام یا جابهجا شده است. پین SQW هم اگر روزی به آن نیاز داشتید، موج مربع ۱ هرتز تا ۸ کیلوهرتز میدهد و برای وقفهٔ ثانیهشمار بهکار میآید.
اشتباهات رایج و عیبیابی
| نشانه | علت رایج | راهحل |
|---|---|---|
| تاریخ و زمان غلط و ثابت | باتری تمام یا نصب نشده و چیپ به مقدار پیشفرض برگشته | ولتاژ باتری را با مولتیمتر ببینید؛ حدود ۳ ولت باید باشد؛ باتری نو بگذارید |
| ساعت هر بار آپلود به یک زمان برمیگردد | باقیماندن خط rtc.adjust در کد |
پس از تنظیم اولیه، آن خط را کامنتگذاری و دوباره آپلود کنید |
| پیام RTC not found | سیمکشی SDA/SCL جابهجا یا تغذیه قطع | A4→SDA و A5→SCL را چک کنید؛ با اسکنر I2C آدرس 0x68 را تأیید کنید |
| زمان میلغزد یا پرش دارد | ماژول تقلبی با کریستال بیکیفیت یا دمای شدید | ماژول از فروشندهٔ معتبر بخرید؛ DS3231 اصل دما را جبران میکند |
تمرینها
تمرین
تمرین ۱ — ساعت با فرمت ساده
اسکچ درس را طوری تغییر دهید که علاوه بر خط کامل تاریخوساعت، اگر ساعت ۶ تا ۱۸ بود پیام Daytime و در غیر این صورت پیام Nighttime چاپ شود.
نمایش راهحل
شرط ساده روی now.hour() کافی است؛ ترتیب چاپ مهم نیست:
// in loop(), after printing the full timestamp:
if (now.hour() >= 6 && now.hour() < 18) {
Serial.println("Daytime");
} else {
Serial.println("Nighttime");
}با ساعت ۱۴ و ۲۰ دقیقه، خروجی سریال مانیتور چنین است:
DS3231 ready 2026-10-31 14:20:05 Daytime 2026-10-31 14:20:06 Daytime
::: :::
خلاصه
- آردوینو Uno ساعت داخلی ندارد؛ RTC ماژولی اختصاصی است که با باتری سکهای، زمان را از قطع تغذیه عبور میدهد.
- DS3231 با اسیلاتور جبرانشدهٔ دمایی، دقیقتر از DS1307 است و کریستال خارجی نمیخواهد.
- ماژول با آدرس
0x68روی I2C کار میکند و کتابخانهٔ RTClib از Adafruit نصب میشود. rtc.adjust(DateTime(F(__DATE__), F(__TIME__)))زمان را به لحظهٔ کامپایل تنظیم میکند و باید پس از تنظیم اولیه حذف یا کامنت شود.- سلامت باتری CR2032 را با ~۳ ولت و بقای زمان پس از قطع برق میسنجید؛ پین SQW موج مربع قابل تنظیم میدهد.
حالا پروژهتان حرکت را میبیند، موتور میچرخاند، کارت را میشناسد و زمان را میداند؛ با این چهار ماژول، فهرست پروژههای قابلساخت عملاً باز شده است.