طرح مسئله؟
در بسیاری از پروژه ها نیاز به دانستن زمان برای نمایش به کاربر و یا انجام کارهای زمانبندی شده در ساعات خاص در طول روز داریم. به عنوان مثال فرض کنید می خواهیم با استفاده از برد آردوینو Arduino یک پروژه تعریف کنیم که در آن سیستم روشنایی یک مکان اداری را در روزهای غیر تعطیل از ساعت 18 الی 20 به مدت دو ساعت روشن کنیم و در خارج از این ساعات و روزهای تعطیل سیستم روشنایی به صورت اتوماتیک خاموش شود. برای انجام این پروژه نیاز به یک ساعت و تقویم بسیار دقیق داریم که حتی در زمان قطع برق شبکه نیز برای طولانی مدت، عملیات محاسبه زمان متوقف نشود و زمان به صورت دقیق محاسبه شود.
شاید برای ساخت ساعت اولین فکری که به ذهنتان برسد نوشتن یک برنامه ساده برای آردوینو باشد که توسط آن با استفاده از تعریف چند متغیر و یک دستور تاخیری یک ساعت و تقویم بسازید، اما به احتمال بسیار زیاد در پایان کار با مشکلات زیر روبرو خواهید شد:
:: ساعت ساخته شده دقیق نیست و در طول روز چند ثانیه عقب یا جلو می ماند.
:: با قطع تغذیه از برد آردوینو ساعت صفر می شود.
:: در صورت استفاده از باتری پشتیبان، به علت جریان مصرفی بالا برد آردوینو، احتمالا باتری نتواند بیشتر از چند ساعت مدار را پشتیبانی کند.
:: کدهای نوشته شده برای محاسبه ساعت و تقویم بیشتر حافظه میکروکنترلر برد آردوینو را اشغال کرده و فضای زیادی برای نوشتن سایر کدها برای شما باقی نمانده.
لیست قطعات مورد نیاز
برد آردوینو Arduino UNO R3 مدل DIP | 1 عدد |
LCD کاراکتری مدل 16×2 با Backlighting آبی | 1 عدد |
آی سی شمارش و نگهداری ساعت و تقویم DS1307 مدل DIP | 1 عدد |
تک سوئیچ 2 پایه DIP سایز 6x6x5 میلیمتر | 3 عدد |
مقاومت 10 کیلو اهم با توان 0.25 وات و تلرانس 1 درصد | 3 عدد |
کریستال ساعت 32.768KHz کیلوهرتز | 1 عدد |
جاباتری سکه ای DIP سایز CR2032 مدل ایستاده | 1 عدد |
برد بورد (پروجکت برد) مدل GL | 1 عدد |
سیم جامپر برد بوردی مدل دو سر نری (سری 40تایی) | 1 عدد |
آی سی ساعت DS1307
آی سی DS1307 در بازار به اسم آی سی ساعت مشهور است و دلیل این موضوع نیز این بوده که این آی سی به صورت اختصاصی با هدف محاسبه ساعت و تقویم طراحی شده است. آی سی DS1307 یک ساعت و تقویم BCD می باشد که توان مصرفی آن بسیار پایین می باشد به طوریکه می تواند با یک باتری ساعت 3 ولتی به مدت یکسال بدون وقفه به کار خود در مدار ادامه دهد. همچنین لازیم به ذکر است این تراشه دارای مدار داخلی تشخیص نقص تغذیه نیز می باشد و در صورت بروز قطع تغذیه، باطری پشتیبان را به طور خودکار در مدار قرار می دهد.
آی سی ساعت DS1307 را می توان به راحتی از طریق پروتکل ارتباطی I2C به برد آردوینو متصل کرد و به سادگی هر چه تمام فقط با ارسال یک خط دستور از ساعت و تقویم با خبر شد و یا مقدار آنرا تغییر داد. با استفاده از آی سی ساعت بسیار دقیق DS1307 می توان تمامی مشکلاتی که در قسمت قبلتر به آن اشاره گردید را حل نمود.
ویژگی های تراشه DS1307
:: توانایی شمارش ثانیه, دقیقه, ساعت, روز, ماه, سال, سال کبیسه تا سال 2100 میلادی
:: مصرف کمتر از 500nA در حالت استفاده از باتری پشتیبان
:: محدوده دمای صنعتی 40- تا 85+ درجه سانتی گراد
:: آشکار ساز خودکار نقص تغذیه و مدار کلید زنی باتری
:: 56 بایت حافظه NV RAM برای ذخیره اطلاعات
:: بسته بندی های 8 پایه PDIP و SOIC
:: سیگنال خروجی مربعی برنامه پذیر
:: ارتباط I2C
کتابخانه RTClib.h
کتابخانه RTClib.h یکی از کتابخانه های بسیار کامل و البته بهینه برای آردوینو جهت راه اندازی تراشه های سری DS1307 و DS3231 و PCF8523 می باشد. با استفاده از کتابخانه RTClib.h شما می توانید بدون اینکه خودتان را درگیر برنامه نویسی جهت برقراری ارتباط I2C با آی سی ساعت کنید به راحتی می توانید با نوشتن یک خط دستور مقدار ساعت و تقویم را بخوانید و یا مقدار آنرا تغییر دهید.
فراخوانی کتابخانه RTClib.h
برای استفاده از کتابخانه RTClib.h ابتدا باید آنرا از انتهای همین مطلب دانلود کنید و سپس کتابخانه را در قسمت libraries نزم افزار آردوینو خود اضافه کنید. برای این منظور می توانید مسیر زیر را از طریق منوی نوار ابزار در نرم افزار آردوینو طی کنید و سپس در پنجره نهایی فایل کتابخانه RTClib را که دانلود کرده اید، جهت افزودن انتخاب کنید.
Sketch > Include Library > Add .ZIP Library…
پس از افزودن کتابخانه RTClib.h به نرم افزار آردوینو، حال می توانید جهت استفاده از امکانات آن در برنامه خود از طریق کد دستوری زیر کتابخانه را در برنامه خود فراخوانی کنید.
1 |
#include "RTClib.h" |
تعریف آبجکت
پس از فراخوانی کتابخانه RTClib.h جهت ارتباط با آن و خواندن مقدار ساعت و تقویم نیاز به تعریف یک آبجکت با نام دلخواه داریم، تا در طول برنامه با آن نام آبجکت را فراخوانی کنیم. برای این منظور می توانیم از دستور زیر استفاده کنیم.
توجه : دستور زیر حتما باید قبل از زیر برنامه setup() نوشته شود.
1 |
RTC_DS1307 rtc; |
rtc : در صورت تمایل به جای این کلمه می توانید از نام دلخواه مورد نظر خود استفاده کنید.
فعال سازی ارتباط آردوینو با آی سی ساعت
با استفاده از دستور زیر می توانیم ارتباط بین برد آردوینو و تراشه ساعت را فعال کنیم.
1 |
rtc.begin(); |
برگرداندن مقدار ساعت و تاریخ
برای این منظور ابتدا توسط دستور زیر یک متغیر از جنس زمان و تاریخ تعریف می کنیم :
1 |
DateTime now; |
now : به جای این کلمه می توانید نام مورد نظر خود را جهت تعریف نام متغیر وارد کنید.
حال پس از تعریف متغیر توسط دستور زیر مقدار ساعت و تاریخ را خوانده و در متغیر تعریف شده از جنس زمان و تاریخ وارد می کنیم.
1 |
now = rtc.now(); |
در پایان می توانیم با بکارگیری دستورات زیر به مقدار ساعت و تاریخ به صورت مجزا دسترسی داشته باشیم.
1 2 3 4 5 6 |
now.hour; //ساعت now.minute; //دقیقه now.second; //ثانیه now.day; //روز now.month; //ماه now.year; //سال |
تنظیم ساعت و تاریخ
برای ویرایش ساعت و تاریخ می توانید از دستور زیر در برنامه خود استفاده کنید.
1 |
rtc.adjust(DateTime(year, month, day, hour, minute, second)); |
year : مقدار سال (سال باید به صورت میلادی وارد شود).
month : مقدار ماه (عددی در بازه 1 الی 12).
day : مقدار روز.
hour : مقدار ساعت (عددی در بازه 0 الی 23).
minute : مقدار دقیقه.
second : مقدار ثانیه.
پروژه: ساخت ساعت و تقویم دیجیتال با آردوینو و آی سی ساعت DS1307
در این پروژه آردوینو از مبحث آموزش آردوینو می خواهیم شما را با نحوه برنامه نویسی و ساخت یک ساعت و تقویم دیجیتال با آردوینو و آی سی ساعت DS1307 آشنا کنیم.
نقشه شماتیک پروژه ساخت ساعت و تقویم دیجیتال با آردوینو
برنامه آردوینو
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
#include "RTClib.h" #include <LiquidCrystal.h> //*********************************************Config RTC RTC_DS1307 rtc; //*********************************************Config Pin_Keypad const int PIN_SW_DOWN = 3; const int PIN_SW_SET = 4; const int PIN_SW_UP = 2; //*********************************************Setup LCD const int contrast_display = 80; const int backlight_display = 255; //*********************************************Config Pin_LCD const int LCD_Pin_contrast = 5; const int LCD_Pin_RS = 7; const int LCD_Pin_RW = 8; const int LCD_Pin_E = 9; const int LCD_Pin_D4 = 10; const int LCD_Pin_D5 = 11; const int LCD_Pin_D6 = 12; const int LCD_Pin_D7 = 13; const int LCD_Pin_backlight = 6; LiquidCrystal lcd(LCD_Pin_RS, LCD_Pin_RW, LCD_Pin_E, LCD_Pin_D4, LCD_Pin_D5, LCD_Pin_D6, LCD_Pin_D7); //*********************************************Config Value char daysOfTheWeek[7][12] = {"[Su]", "[Mo]", "[Tu]", "[We]", "[Th]", "[Fr]", "[Sa]"}; boolean key = 0; int _hour, _minute; int _year, _month, _day; boolean key_SET , key_DOWN, key_UP; //*********************************************Subprogram setup() void setup() { rtc.begin(); pinMode(PIN_SW_DOWN, INPUT_PULLUP); pinMode(PIN_SW_SET, INPUT_PULLUP); pinMode(PIN_SW_UP, INPUT_PULLUP); analogWrite(LCD_Pin_contrast, contrast_display); analogWrite(LCD_Pin_backlight, backlight_display); if (! rtc.isrunning()) { 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)); } lcd.begin(16, 2); lcd.clear(); lcd.setCursor(0, 0); lcd.print("*electronics 98*"); lcd.setCursor (0, 1); lcd.print(">Arduino Project"); delay(3000); lcd.clear(); } //*********************************************Subprogram loop() void loop() { DateTime now = rtc.now(); lcd.setCursor(0, 0); lcd.print(now.hour()); lcd.print(":"); lcd.print(now.minute()); lcd.print(":"); lcd.print(now.second()); lcd.print(" "); lcd.setCursor(12, 0); lcd.print(daysOfTheWeek[now.dayOfTheWeek()]); lcd.setCursor(0, 1); lcd.print(now.year()); lcd.print("/"); lcd.print(now.month()); lcd.print("/"); lcd.print(now.day()); lcd.print(" "); key_UP = digitalRead(PIN_SW_UP); key_SET = digitalRead(PIN_SW_SET); key_DOWN = digitalRead(PIN_SW_DOWN); if (key == 0 && key_SET == 0 && key_DOWN == 1 && key_UP == 1) { key = 1; _hour = now.hour(); _minute = now.minute(); _year = now.year(); _month = now.month(); _day = now.day(); SET_hour(); } if (key == 1 && key_SET == 1 && key_DOWN == 1 && key_UP == 1) { key = 0; } } //*********************************************Subprogram SET_hour() void SET_hour() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("> SET Hour"); lcd.setCursor (0, 1); lcd.print("Hour = "); while (1) { lcd.setCursor (7, 1); lcd.print(_hour); lcd.print(" "); key_UP = digitalRead(PIN_SW_UP); key_SET = digitalRead(PIN_SW_SET); key_DOWN = digitalRead(PIN_SW_DOWN); if (key == 0 && key_SET == 1 && key_DOWN == 0 && key_UP == 1) { key = 1; if (_hour == 0) { _hour = 23; } else { _hour--; } } if (key == 0 && key_SET == 1 && key_DOWN == 1 && key_UP == 0) { key = 1; if (_hour == 23) { _hour = 0; } else { _hour++; } } if (key == 0 && key_SET == 0 && key_DOWN == 1 && key_UP == 1) { key = 1; break; } if (key == 1 && key_SET == 1 && key_DOWN == 1 && key_UP == 1) { key = 0; } } SET_minute(); } //*********************************************Subprogram SET_minute() void SET_minute() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("> SET Minute"); lcd.setCursor (0, 1); lcd.print("Minute = "); while (1) { lcd.setCursor (9, 1); lcd.print(_minute); lcd.print(" "); key_UP = digitalRead(PIN_SW_UP); key_SET = digitalRead(PIN_SW_SET); key_DOWN = digitalRead(PIN_SW_DOWN); if (key == 0 && key_SET == 1 && key_DOWN == 0 && key_UP == 1) { key = 1; if (_minute == 0) { _minute = 59; } else { _minute--; } } if (key == 0 && key_SET == 1 && key_DOWN == 1 && key_UP == 0) { key = 1; if (_minute == 59) { _minute = 0; } else { _minute++; } } if (key == 0 && key_SET == 0 && key_DOWN == 1 && key_UP == 1) { key = 1; break; } if (key == 1 && key_SET == 1 && key_DOWN == 1 && key_UP == 1) { key = 0; } } SET_year(); } //*********************************************Subprogram SET_year() void SET_year() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("> SET Year"); lcd.setCursor (0, 1); lcd.print("Year = "); while (1) { lcd.setCursor (7, 1); lcd.print(_year); lcd.print(" "); key_UP = digitalRead(PIN_SW_UP); key_SET = digitalRead(PIN_SW_SET); key_DOWN = digitalRead(PIN_SW_DOWN); if (key == 0 && key_SET == 1 && key_DOWN == 0 && key_UP == 1) { key = 1; if (_year == 2014) { _year = 2030; } else { _year--; } } if (key == 0 && key_SET == 1 && key_DOWN == 1 && key_UP == 0) { key = 1; if (_year == 2030) { _year = 2014; } else { _year++; } } if (key == 0 && key_SET == 0 && key_DOWN == 1 && key_UP == 1) { key = 1; break; } if (key == 1 && key_SET == 1 && key_DOWN == 1 && key_UP == 1) { key = 0; } } SET_month(); } //*********************************************Subprogram SET_month() void SET_month() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("> SET Month"); lcd.setCursor (0, 1); lcd.print("Month = "); while (1) { lcd.setCursor (8, 1); lcd.print(_month); lcd.print(" "); key_UP = digitalRead(PIN_SW_UP); key_SET = digitalRead(PIN_SW_SET); key_DOWN = digitalRead(PIN_SW_DOWN); if (key == 0 && key_SET == 1 && key_DOWN == 0 && key_UP == 1) { key = 1; if (_month == 1) { _month = 12; } else { _month--; } } if (key == 0 && key_SET == 1 && key_DOWN == 1 && key_UP == 0) { key = 1; if (_month == 12) { _month = 1; } else { _month++; } } if (key == 0 && key_SET == 0 && key_DOWN == 1 && key_UP == 1) { key = 1; break; } if (key == 1 && key_SET == 1 && key_DOWN == 1 && key_UP == 1) { key = 0; } } SET_day(); } //*********************************************Subprogram SET_day() void SET_day() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("> SET Day"); lcd.setCursor (0, 1); lcd.print("Day = "); while (1) { lcd.setCursor (6, 1); lcd.print(_day); lcd.print(" "); key_UP = digitalRead(PIN_SW_UP); key_SET = digitalRead(PIN_SW_SET); key_DOWN = digitalRead(PIN_SW_DOWN); if (key == 0 && key_SET == 1 && key_DOWN == 0 && key_UP == 1) { key = 1; if (_day == 1) { _day = 31; } else { _day--; } } if (key == 0 && key_SET == 1 && key_DOWN == 1 && key_UP == 0) { key = 1; if (_day == 31) { _day = 1; } else { _day++; } } if (key == 0 && key_SET == 0 && key_DOWN == 1 && key_UP == 1) { key = 1; break; } if (key == 1 && key_SET == 1 && key_DOWN == 1 && key_UP == 1) { key = 0; } } Save(); } //*********************************************Subprogram Save() void Save() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("> Save... "); lcd.setCursor(0, 1); lcd.print("*electronics 98*"); rtc.adjust(DateTime(_year, _month, _day, _hour, _minute, 0)); delay(2000); lcd.clear(); } |
خدا خیرت بده
خیلی دنبال این مطلب بودم دستت درد نکنه
فقط یه سوال آیا اون led ای که گذاشتید تو شماتیک نقش چیه؟؟؟
سلام دوست عزیز
لامپ LED مذکور همان چراغ پس زمینه نمایشگر است. در حقیقت پایه متصل به لامپ LED در نقشه شماتیک به پایه شماره 15 نمایشگر متصل می شود و پایه شماره 16 نمایشگر به منفی منبع تغذیه متصل می گردد.
سلام ممنون از پروژه تون خیلی کاربردی و خوب بود
فقط ی سوال من میخوام هر ماه از اول ماه تا اخر ماه یک ال ای دی مربوط به همون ماه روشن بشه
خودم این برنامه رو نوشتم اگه درست میباشد در کجای برنامه قرارش باید بدم
سلام دوست عزیز
بله برنامه درست است فقط بجای متغیر _month از now.month() در شرط ها استفاده کنید و کدهای خود را در حلقه loop() بعد از خط 85 برنامه بنویسید.
سلام من همه ی کارها را در نقشه شما تیک انجام دادیم اما ال سی دی روشن نمیشه بعد میشه بگید پایه منفی ال سی دی را به کدام پایه اردینو وصل کنم
سلام دوست عزیز
باید اتصالات نمایشگر خود را بررسی کنید، همچنین پایه منفی نمایشگر به منفی منبع تغذیه و یا یکی از پایه های GND برد آردوینو متصل می شود و پایه مثبت نمایشگر به پایه +5v برد آردوینو متصل می شود.
سلام خدمت شما عزیز اگه من خواستم طبق ساعتی که با دستگاه ست کردن یک ال ای دی فعال کنه باید چکار کنم
ممنون میشم کمکم کنید
سلام دوست عزیز
باید در زیر برنامه loop() یک دستور شرطی تعریف کنید که متغیرهای now.hour (ساعت) و now.minute (دقیقه) و now.second (ثانیه) را با مقدار زمان دلخواه خود مقایسه کند و در صورتیکه هر دو مقادیر زمانی یکسان بودند یکی از خروجی های دیجیتال موجود بر روی برد آردوینو یک شود.
سلام و خستع نباشید
کتابخانه RTClib.h رو نوشتین انتها همین مطلب قرار دادیم ولی اخرین مطلب تون فیلم آموزشی آپارات هستش کتابخانه RTClib.h نبود و برای
آپلود کردن کد بر روی برد اردوینو برنامه اردوینو عرور میدع و کار نمیکنه
میشه راهنمایی کنید
با سلام و احترام
از تب “لینک دانلود” می توانید کتابخانه پروژه را دانلود کنید. برای کامپایل کردن برنامه در نرم افزار آردوینو حتما باید ابتدا کتابخانه را به نرم افزار آردوینو اضافه کنید.
سلام مرسی از مطالب خوبتان
این پروژه رو درست کردم اردینو نانو بعد ساعت روی نمایشگر ثابت هست داخل این
rtc.begin();
باید چی بنویسم
با سلام و احترام
نیازی به تغییر در برنامه نیست و دستور rtc.begin(); به همان شکل در برنامه استفاده می شود.
در صورتیکه مقدار ساعت به صورت ثابت است پیشنهاد می کنیم تمامی اتصالات تراشه DS1307 را با دقت و توسط یک مولتی متر بررسی کنید و مطمئن شوید کریستال ساعت به درستی به تراشه متصل شده باشد و همچنین اتصالات تراشه DS1307 به برد آردوینو صحیح و سالم باشد.
C:\Users\User\Documents\Arduino\libraries\RTClib-master\src/RTClib.h:25:10: fatal error: Adafruit_I2CDevice.h: No such file or directory
#include
ببخشید این ارور برای چیه چطوری رفع میشه
ممنون میشم
با سلام و احترام
با توجه به متن خطا احتمال می رود شما کتابخانه RTClib.h را به مخزن کتابخانه نرم افزار آردوینو خود اضافه نکرده اید.
درود مهندس گرامی . چطور میتوان در یک لحظه دلخواه با یک شستی یا با یک فرمان ، نمایش ساعت روی نمایشگر را بعدا برای بررسی یک اتفاق سیو کرد ؟ سپاس