طرح مسئله؟
در بسیاری از پروژه ها نیاز به دانستن زمان برای نمایش به کاربر و یا انجام کارهای زمانبندی شده در ساعات خاص در طول روز داریم. به عنوان مثال فرض کنید می خواهیم با استفاده از برد آردوینو 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(); } |
با سلام و احترام
برای این موضوع می توانید سه متغیر به صورت EEPROM در برنامه تعریف کنید و سپس با تعریف یک دستور شرطی ساده در حلقه Do…Loop که در صورت 1 یا 0 شدن یکی از ورودی های میکروکنترلر مقدار متغیرهای زمان در متغیرهای تعریف شده در حافظه ثبت شود.
سلام ممنون از پروژه خوبتون ولی یه سوال
اگه بخایم به این برنامه دماسنج ds18b20 رو وصل کنیم باید چی کنیم میتونید کمک کنید ؟
با سلام و احترام
ممنون از لطف و محبت شما
می توانید با استفاده از کتابخانه های آماده که برای سنسور دما DS18B20 نوشته شده است بدون نیاز به کد نویسی، این سنسور را به برد آردوینو متصل نمایید.
با سلام ببخشید چه جوری و با چه دستوری نام روزهای هفته را بدست بیارم و در کنار تاریخ نام روز مثل شنبه یا یکشنبه هم نمایش داده شود
با سلام و احترام
توسط دستور زیر نام روز در هفته به صورت یک رشته برگردانده می شود:
سلام خسته نبا شید لطفا یه کمکی میکنید
من کتاب خانه این پروژه که نصب میکنم و بعدش میخوام او کی کنم خطا میده که فایل نادرست یا خالی است باید چی کار کنم خیلی ممنون کمک کنید