مقدمه
دانستن ساعت و تاریخ همیشه امری مهم بوده و در بسیاری از پروژه های الکترونیکی نیز لازم است براساس ساعت و یا تاریخ عملیاتی صورت گیرد و حتی محاسبه ساعت و تاریخ با خاموش شدن سیستم نیز متوقف نگردد. برای این منظور از ماژول های ساعت زمان واقعی یا Real Time Clock استفاده می شود. در این آموزش نحوه استفاده از ماژول DS1307 با بورد آردوینو را خواهید آموخت.
آنچه در این آموزش یاد میگیرید
- RTC چیست؟
- معرفی ماژول DS1307
- نحوه استفاده از ماژول ds1307 و آردوینو
- چگونگی ساخت یک یادآور هوشمند
ساعت زمان واقعی (RTC) چیست؟
ساعت زمان واقعی (Real Time Clock) که به اختصار RTC گفته می شود همانطور که از نامش پیداست سیستمی است که ساعت دقیق را نگاه می دارد و در همه سیستم هایی که نیاز به استفاده از ساعت دقیق دارند کاربرد دارد.
نگه داشتن زمان دقیق بدون استفاده از سیستم های RTC نیز میسر است ولی استفاده از RTCها نسبت به سایر روش ها مزایایی دارد. از جمله این مزایا می توان به موارد زیر اشاره کرد:
- مصرف بسیار پایین توان
- آزاد سازی وقت سیستم از مسئولیت محاسبه زمان(این ویژگی بسیار مهم است زیرا در بسیاری از مواقع پردازنده درحال انجام امور حساسی مانند دریافت اطلاعات سنسورها و … می باشد و درصورت عدم استفاده از RTC وظیفه سخت و زمانبر نگاه داشتن زمان نیز برعهده پردازنده مرکزی خواهد بود که در این حال ممکن است وظایف اصلی پردازنده مختل شود)
- دقت بالا
معرفی ماژول DS1307
ماژول DS1307 از جمله ارزان ترین و رایج ترین ماژول های RTC است که زمان را به ساعت، دقیقه و ثانیه و تاریخ را به روز، ماه و سال نگاه می دارد.
از مهمترین ویژگی های DS1307 می توانیم به موارد زیر اشاره کنیم:
- قابلیت تولید موج مربعی قابل برنامه ریزی
- مصرف کمتر از 500nA در مد باتری بکاپ
- قابلیت تنظیم تاریخ تا سال 2100
- دارای ارتباط I2C
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 کافیست مراحل زیر را دنبال کنید.
لوازمی که به آن احتیاج دارید
قطعات مورد نیاز
نرم افزارهای مورد نیاز
سیم بندی
کد
برای استفاده از ماژول DS1307 با آردوینو از کتابخانه RTClib استفاده کنید. حال کد زیر را روی بورد خود آپلود کرده و نتیجه را در Serial Monitor مشاهده کنید.
RTC Library
1 file(s) 16.03 KB
// 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 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)
با سلام
نرم افزار آردویینو در هنگام کامپایل کدها ، در سه خط مانده به آخر خطا میدهد ، لطفا بررسی بفرمایید
با تشکر
کتابخانه rtclib رو دانلود کنید
سلام خسته نباشین.
میخواستم بدونم این برنامه ی بالا برای اتصال ماژول ds1307 به پایه های سخت افزاری twi هم امکانش هست یا خیر؟
تشکر
با سلام
امیدوارم که به خوبی متوجه منظورتان شده باشم. بله میشه. پایه های twi و i2c در آردوینو مشترکن.
سلام وقت بخیر اقا من هرچی کامپایل میکنم این خطا رو میده
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.
ممنون میشم کمکم کنین خیلی ضروریه
ممنون از نظرتان
کد اصلاح شد.
ببخشید قسمت اتصال ماژول به آردوینو همون آموزش ساخت ساعت هم حساب میشه؟
سلام.
بله از نحوه اتصال ماژول به آردوینو میتونید برای ساخت ساعت هم استفاده کنید.
سلام لینک دانلود کتابخانه مشکل داره
با سلام
در تلاش برای رفع مشکل هستیم. میتوانید از این لینک برای دانلود کتابخانه استفاده کنید
DS1307
سلام و تشکر از سایت خوبتون.
برای استفاده از اولد1306 چه تغییری باید توی کد ایجاد کنم؟