چگونه از DS1307 با آردوینو استفاده کنیم و یک یادآور هوشمند بسازیم؟

فهرست مطالب

مقدمه

دانستن ساعت و تاریخ همیشه امری مهم بوده و در بسیاری از پروژه های الکترونیکی نیز لازم است براساس ساعت و یا تاریخ عملیاتی صورت گیرد و حتی محاسبه ساعت و تاریخ با خاموش شدن سیستم نیز متوقف نگردد. برای این منظور از ماژول های ساعت زمان واقعی یا Real Time Clock استفاده می شود.  در این آموزش نحوه استفاده از ماژول DS1307 با بورد آردوینو را خواهید آموخت.

آنچه در این آموزش یاد می‌گیرید

ساعت زمان واقعی (RTC) چیست؟

ساعت زمان واقعی (Real Time Clock) که به اختصار RTC گفته می شود همانطور که از نامش پیداست سیستمی است که ساعت دقیق را نگاه می دارد و در همه سیستم هایی که نیاز به استفاده از ساعت دقیق دارند کاربرد دارد.
نگه داشتن زمان دقیق بدون استفاده از سیستم های RTC نیز میسر است ولی استفاده از RTCها نسبت به سایر روش ها مزایایی دارد. از جمله این مزایا می توان به موارد زیر اشاره کرد:
  • مصرف بسیار پایین توان
  • آزاد سازی وقت سیستم از مسئولیت محاسبه زمان(این ویژگی بسیار مهم است زیرا در بسیاری از مواقع پردازنده درحال انجام امور حساسی مانند دریافت اطلاعات سنسورها و … می باشد و درصورت عدم استفاده از RTC وظیفه سخت و زمانبر نگاه داشتن زمان نیز برعهده پردازنده مرکزی خواهد بود که در این حال ممکن است وظایف اصلی پردازنده مختل شود)
  • دقت بالا
RTCها علاوه بر تغذیه اصلی دارای منبع ثانویه هم هستند که درصورت قطع منبع اصلی شمارش ساعت مختل نشود و همچنان ساعت دقیق را نگاه دارند. RTCها برای شمارش زمان معمولا از یک کریستال 32.768 کیلوهرتزی استفاده می کنند، اما شاید برایتان این سوال پیش بیاید که چرا این عدد خاص استفاده شده است باید بگوییم دلیل استفاده از عدد 32768 از توان های 2 می باشد (15^2) و به سادگی قابلیت تولید 1 ثانیه را دارد بعلاوه ساخت کریستالی که هم کوچک باشد هم پهنای مناسبی داشته باشد و هم توان زیادی مصرف نکند، با مقدار 32768 هرتز ساده تر است، توان های 2 کمتر از این مقدار کریستال های بزرگ تر و شکننده ای هستند و توان های 2 بیشتر ازاین مقدار توان مصرفی بیشتری دارند.

معرفی ماژول DS1307

ماژول DS1307 از جمله ارزان ترین و رایج ترین ماژول های RTC است که زمان را به ساعت، دقیقه و ثانیه و تاریخ را به روز، ماه و سال نگاه می دارد. از مهمترین ویژگی های DS1307 می توانیم به موارد زیر اشاره کنیم:
  • قابلیت تولید موج مربعی قابل برنامه ریزی
  • مصرف کمتر از 500nA در مد باتری بکاپ
  • قابلیت تنظیم تاریخ تا سال 2100
  • دارای ارتباط I2C
ماژول DS1307 قابلیت نصب باتری بکاپ 3 ولت را دارا می باشد، این باتری از نوع CR2032 است. . همچنین روی این ماژول یک آیسی حافظه EEPROM 24c32 تعبیه شده که می توانید 32 کیلو بیت داده روی آن ذخیره کنید بعلاوه شما می توانید با نصب یک سنسور DS18B20 درجای تعبیه شده روی بورد دمای محیط را نیز اندازه گیری کنید، همچنین از طریق پایه BAT می توانید ولتاژ باتری بکاپ را نیز بخوانید.
PIN Operation
Vcc +5 v
GND GND
SDA,SCL RTC and EEPROM I2C communication
DS Temperature sensor – 1wire protocol
BAT Battery voltage – ADC
SQ Square wave output(1,4,8,32 KHz)

اتصال ماژول DS1307 به آردوینو

کار با ماژول DS1307 ساده می باشد، قسمت RTC این ماژول با پروتکل I2C با میکروکنترلر ارتباط برقرار می کند. برای استفاده از ماژول DS1307 کافیست مراحل زیر را دنبال کنید.

لوازمی که به آن احتیاج دارید

قطعات مورد نیاز

برد آردوینو Uno × 1
ماژول DS1307 × 1
سیم جامپر نری به مادگی × 1

نرم افزارهای مورد نیاز

Arduino IDE

سیم بندی

کد

برای استفاده از ماژول DS1307 با آردوینو از کتابخانه RTClib استفاده کنید. حال کد زیر را روی بورد خود آپلود کرده و نتیجه را در Serial Monitor مشاهده کنید.

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

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

void setup () {
  while (!Serial); // for Leonardo/Micro/Zero

  Serial.begin(57600);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}

void loop () {
  DateTime now = rtc.now();

  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(" (");
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(") ");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();

  Serial.print(" since midnight 1/1/1970 = ");
  Serial.print(now.unixtime());
  Serial.print("s = ");
  Serial.print(now.unixtime() / 86400L);
  Serial.println("d");

  // calculate a date which is 7 days and 30 seconds into the future
  DateTime future (now + TimeSpan(7, 12, 30, 6));

  Serial.print(" now + 7d + 30s: ");
  Serial.print(future.year(), DEC);
  Serial.print('/');
  Serial.print(future.month(), DEC);
  Serial.print('/');
  Serial.print(future.day(), DEC);
  Serial.print(' ');
  Serial.print(future.hour(), DEC);
  Serial.print(':');
  Serial.print(future.minute(), DEC);
  Serial.print(':');
  Serial.print(future.second(), DEC);
  Serial.println();

  Serial.println();
  delay(3000);
}
برای تنظیم ساعت و تاریخ دو روش وجود دارد، روش اول تنظیم ساعت و تاریخ از روی کامپیوتر می باشد . برای این کار از کد زیر استفاده کنید:
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
روش دوم تنظیم دستی تاریخ و ساعت می باشد . برای این منظور از کد زیر استفاده کنید:
rtc.adjust(DateTime(YEAR, MONTH, DAY, HOUR , MINUTE, SECOND));
نکته
برای پروژه خود تنها یکبار نیاز به تنظیم ساعت و تاریخ دارید و پس از  آن باید کد مربوط به تنظیم تاریخ و ساعت را از برنامه خود حذف کنید درغیراینصورت هربار که سیستم خود را روشن می کنید ساعت و تاریخ مجددا تنظیم می شود که این باعث بروز اشتباه می گردد.
نکته
آپلود شدن کد روی آردوینو چند ثانیه زمان می برد که ممکن است باعث بروز اختلاف چندثانیه ای ساعت شما با ساعت واقعی باشید، پس بهتر است زمان را چند ثانیه جلوتر تنظیم نموده و سپس کد را آپلود کنید.

با DS1307 یک یادآور هوشمند بسازید

با استفاده از ماژول DS1307 می توانید یک یادآور ساده ولی مفید درست کنید.

قطعات مورد نیاز

Arduino Uno R3 × 1
DS1307 Module × 1
LCD Keypad Shield × 1
Passive Buzzer × 1
Jumper wire × 1

نرم افزارهای مورد نیاز

Arduino IDE

سیم بندی

کد

حال با آپلود کردن کد زیر روی آردوینو خود یادآور شما آماده است.
/*

Arduino Reminder

modified on 13 March 2019
by Saeed Hosseini @ Electropeak
Home
*/ #include <LiquidCrystal.h> #include <Wire.h> #include "RTClib.h" #define NOTE_C4 262 #define NOTE_D4 294 #define NOTE_E4 330 #define NOTE_F4 349 #define NOTE_G4 392 #define NOTE_A4 440 #define NOTE_B4 494 #define NOTE_C5 523 #define NOTE_D5 587 #define NOTE_E5 659 #define NOTE_F5 698 #define NOTE_G5 784 #define NOTE_A5 880 #define NOTE_B5 988 //LCD Pin to Arduino const int pin_RS = 8; const int pin_EN = 9; const int pin_d4 = 4; const int pin_d5 = 5; const int pin_d6 = 6; const int pin_d7 = 7; const int pin_BL = 10; //BUZZER Pin to Arduino const int buzzer = 2; LiquidCrystal lcd( pin_RS, pin_EN, pin_d4, pin_d5, pin_d6, pin_d7); RTC_DS1307 rtc; byte smiley[8] = { B00000, B10001, B00000, B00000, B10001, B01110, B00000, }; String menuItems[] = {"1-Medicin", "2-Wake up", "3-Go out"}; int songspeed = 1.5; int flag = 0; int menuPage = 0; int maxMenuPages = round(((sizeof(menuItems) / sizeof(String)) / 2) + .5); int cursorPosition = 0; int btn; int h = 0, m = 0; int duration[] = { //duration of each note (in ms) Quarter Note is set to 250 ms 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 375, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 375, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 125, 250, 125, 125, 125, 250, 125, 125, 250, 125, 250, 125, 125, 125, 250, 125, 125, 125, 125, 375, 375, 250, 125, //Rpeat of First Part 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 375, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 375, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 250, 125, 125, 125, 125, 125, 250, 125, 125, 125, 250, 125, 125, 250, 125, 250, 125, 125, 125, 250, 125, 125, 125, 125, 375, 375, //End of Repeat 250, 125, 375, 250, 125, 375, 125, 125, 125, 125, 125, 125, 125, 125, 375, 250, 125, 375, 250, 125, 375, 125, 125, 125, 125, 125, 500, 250, 125, 375, 250, 125, 375, 125, 125, 125, 125, 125, 125, 125, 125, 375, 250, 125, 375, 250, 125, 375, 125, 125, 125, 125, 125, 500 }; int notes[] = { //Note of the song, 0 is a rest/pulse NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0, NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0, NOTE_A4, NOTE_G4, NOTE_A4, 0, NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0, NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0, NOTE_A4, NOTE_G4, NOTE_A4, 0, NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0, NOTE_A4, NOTE_C5, NOTE_D5, NOTE_D5, 0, NOTE_D5, NOTE_E5, NOTE_F5, NOTE_F5, 0, NOTE_E5, NOTE_D5, NOTE_E5, NOTE_A4, 0, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0, NOTE_D5, NOTE_E5, NOTE_A4, 0, NOTE_A4, NOTE_C5, NOTE_B4, NOTE_B4, 0, NOTE_C5, NOTE_A4, NOTE_B4, 0, NOTE_A4, NOTE_A4, //Repeat of first part NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0, NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0, NOTE_A4, NOTE_G4, NOTE_A4, 0, NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0, NOTE_C5, NOTE_D5, NOTE_B4, NOTE_B4, 0, NOTE_A4, NOTE_G4, NOTE_A4, 0, NOTE_E4, NOTE_G4, NOTE_A4, NOTE_A4, 0, NOTE_A4, NOTE_C5, NOTE_D5, NOTE_D5, 0, NOTE_D5, NOTE_E5, NOTE_F5, NOTE_F5, 0, NOTE_E5, NOTE_D5, NOTE_E5, NOTE_A4, 0, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_C5, 0, NOTE_D5, NOTE_E5, NOTE_A4, 0, NOTE_A4, NOTE_C5, NOTE_B4, NOTE_B4, 0, NOTE_C5, NOTE_A4, NOTE_B4, 0, //End of Repeat NOTE_E5, 0, 0, NOTE_F5, 0, 0, NOTE_E5, NOTE_E5, 0, NOTE_G5, 0, NOTE_E5, NOTE_D5, 0, 0, NOTE_D5, 0, 0, NOTE_C5, 0, 0, NOTE_B4, NOTE_C5, 0, NOTE_B4, 0, NOTE_A4, NOTE_E5, 0, 0, NOTE_F5, 0, 0, NOTE_E5, NOTE_E5, 0, NOTE_G5, 0, NOTE_E5, NOTE_D5, 0, 0, NOTE_D5, 0, 0, NOTE_C5, 0, 0, NOTE_B4, NOTE_C5, 0, NOTE_B4, 0, NOTE_A4 }; void show_time() { lcd.clear(); DateTime now = rtc.now(); lcd.setCursor(0, 0); lcd.print("* Electropeak *"); lcd.setCursor(5, 0); lcd.print(now.hour(), DEC); lcd.print(":"); lcd.print(now.minute(), DEC); if (now.hour() == h && now.minute() == m) { lcd.clear(); lcd.setCursor(0 , 0); switch (flag) { case 1: lcd.print("** ءedicine Time **"); break; case 2: lcd.print("You'r late!!"); lcd.setCursor(0, 1); lcd.print("Come onnnnnnn"); break; case 3: lcd.print("Befor you go:"); lcd.setCursor(0, 1); lcd.print("Wallet,Keys,..."); break; } for (int i = 0; i < 203; i++) { //203 is the total number of music notes in the song int wait = duration[i] * songspeed; tone(buzzer, notes[i], wait); //tone(pin,frequency,duration) delay(wait); } } delay(2000); } void welcome_menu(int show_delay) { lcd.setCursor(0, 0); lcd.print("Arduino reminder"); lcd.createChar(1, smiley); lcd.setCursor(7, 1); lcd.write(1); delay(show_delay); lcd.clear(); } int detect_button() { int readkey = 0; int result = 0; int activeButton = 0; while (activeButton == 0) { readkey = analogRead(0); if (readkey < 790) { delay(100); readkey = analogRead(0); if (readkey < 60) { result = 1; // right } else if (readkey < 200) { result = 2; // up } else if (readkey < 400) { result = 3; // down } else if (readkey < 600) { result = 4; // down } else if (readkey < 800) { result = 5; } return result; } } activeButton = 1; } int choose_menu() { lcd.clear(); lcd.print("Remmeber what?"); while (btn != 5) { btn = detect_button(); if (btn == 1) { if (menuPage > maxMenuPages) menuPage = 0; lcd.clear(); lcd.print("Remmeber what?"); lcd.setCursor(0, 1); lcd.print(menuItems[menuPage]); menuPage = menuPage + 1; } } return menuPage; } void set_alarm() { int sit = 0; lcd.clear(); lcd.setCursor(1, 0); lcd.print("**Set Alarm**"); lcd.setCursor(5, 1); lcd.print("00:00"); while (sit != 1) { sit = detect_button(); if (sit == 2) { lcd.clear(); lcd.setCursor(1, 0); lcd.print("**Set Alarm**"); h++; if (h > 23) { h = 0; } lcd.setCursor(5, 1); lcd.print(h); lcd.print(":00"); } else if (sit == 3) { lcd.clear(); lcd.setCursor(1, 0); lcd.print("**Set Alarm**"); h--; if (h < 0) { h = 23; } lcd.setCursor(5, 1); lcd.print(h); lcd.print(":00"); } } while (sit != 5) { sit = detect_button(); if (sit == 2) { lcd.clear(); lcd.setCursor(1, 0); lcd.print("**Set Alarm**"); m++; if (m > 59) { m = 0; } lcd.setCursor(5, 1); lcd.print(h); lcd.print(":"); lcd.print(m); } else if (sit == 3) { lcd.clear(); lcd.setCursor(1, 0); lcd.print("**Set Alarm**"); m--; if (m < 0) { m = 59; } lcd.setCursor(5, 1); lcd.print(h); lcd.print(":"); lcd.print(m); } } lcd.clear(); lcd.setCursor(0, 0); lcd.print("Alarm set"); lcd.setCursor(0, 1); lcd.print("I'll be on time"); delay(1500); } void setup() { lcd.begin(16, 2); rtc.begin(); pinMode(buzzer, OUTPUT); welcome_menu(1000); flag = choose_menu(); set_alarm(); } void loop() { show_time(); }

اگر به اطلاعات بیشتری درباره شیلد نمایشگر آردوینو نیاز دارید به “استفاده از شیلد نمایشگر 1602 آردوینو[همراه با پروژه های عملی]” مراجعه کنید.

با روشن شدن دستگاه، روی LCD منو ظاهر می شود، نوع یادآوری خود را انتخاب کنید (با انتخاب کلید Right بین گزینه ها حرکت  کنید با فشردن Select مورد مدنظر خود را انتخاب کنید) سپس زمان اعلام هشدار را تنظیم کنید (ایتدا ساعت را با Up و Down تنظیم کنید سپس با انتخاب کلید Right به دقیقه بروید و آنرا تنظیم کنید) و با انتخاب   Select تنظیمات را ذخیره کنید، حالا با خیال راحت بدون نگرانی به کارهای روزمره خود برسید.

یک گام جلوتر

  • سعی کنید یک آلارم بیدارباش بسازید.
  • سنسور دمای قابل نصب روی ماژول ds1307 را نصب کنید و سعی کنید با استفاده از TFT LCD 2.4” یک ساعت رومیزی گرافیکی و زیبا با قابلیت نمایش دمای محیط بسازید.

آموزش های مشابه

Comments (11)

  • مجتبی Reply

    با سلام
    نرم افزار آردویینو در هنگام کامپایل کدها ، در سه خط مانده به آخر خطا میدهد ، لطفا بررسی بفرمایید
    با تشکر

    آوریل 2, 2020 at 8:28 ب.ظ
    • Amir Mogoei Reply

      کتابخانه rtclib رو دانلود کنید

      آوریل 18, 2020 at 1:55 ب.ظ
  • محمد رضا Reply

    سلام خسته نباشین.
    میخواستم بدونم این برنامه ی بالا برای اتصال ماژول ds1307 به پایه های سخت افزاری twi هم امکانش هست یا خیر؟
    تشکر

    جولای 21, 2020 at 3:50 ب.ظ
    • مهران ملکی Reply

      با سلام
      امیدوارم که به خوبی متوجه منظورتان شده باشم. بله میشه. پایه های twi و i2c در آردوینو مشترکن.

      دسامبر 1, 2020 at 2:40 ب.ظ
  • امیر Reply

    سلام وقت بخیر اقا من هرچی کامپایل میکنم این خطا رو میده
    Arduino: 1.8.4 (Windows 10), Board: “Arduino/Genuino Uno”

    C:\Users\hadia\AppData\Local\Temp\arduino_modified_sketch_719976\sketch_nov27a.ino: In function ‘int detect_button()’:

    sketch_nov27a:258: error: a function-definition is not allowed here before ‘{‘ token

    void set_alarm() {

    ^

    sketch_nov27a:344: error: expected ‘}’ at end of input

    }

    ^

    exit status 1
    a function-definition is not allowed here before ‘{‘ token

    This report would have more information with
    “Show verbose output during compilation”
    option enabled in File -> Preferences.

    ممنون میشم کمکم کنین خیلی ضروریه

    نوامبر 27, 2020 at 5:51 ب.ظ
    • مهران ملکی Reply

      ممنون از نظرتان
      کد اصلاح شد.

      دسامبر 1, 2020 at 10:19 ق.ظ
  • وصال Reply

    ببخشید قسمت اتصال ماژول به آردوینو همون آموزش ساخت ساعت هم حساب میشه؟

    دسامبر 28, 2020 at 6:54 ب.ظ
    • مهران ملکی Reply

      سلام.
      بله از نحوه اتصال ماژول به آردوینو میتونید برای ساخت ساعت هم استفاده کنید.

      دسامبر 29, 2020 at 11:45 ق.ظ
  • مصطفی Reply

    سلام لینک دانلود کتابخانه مشکل داره

    ژوئن 9, 2023 at 7:39 ب.ظ
    • محمد دمیرچی Reply

      با سلام
      در تلاش برای رفع مشکل هستیم. میتوانید از این لینک برای دانلود کتابخانه استفاده کنید
      DS1307

      ژوئن 13, 2023 at 5:09 ب.ظ
  • حسام Reply

    سلام و تشکر از سایت خوبتون.
    برای استفاده از اولد1306 چه تغییری باید توی کد ایجاد کنم؟

    نوامبر 22, 2023 at 3:31 ب.ظ

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد.