در پروژه ساخت ساعت دیجیتالی با آردوینو قصد داریم با استفاده از یک آردوینو و ماژول ساعت DS1307 علاوهبر ساعت و تقویم، با محاسبه اوقات شرعی برای شهر موردنظر خود، آن را بر روی یک صفحه ال سی دی مانند ماژول نمایشگر نوکیا 5110 نمایش دهیم تا درک بهتری از این موضوع داشته باشیم.
سختافزار مورد نیاز
ساخت ساعت با آردوینو نیازمند تهیه قطعات سختافزاری از جمله موارد زیر میباشد که البته میتوانید در صورت نیاز، جزئیات آنها را تنها با یک کلیک، مشاهده و خریداری کنید ؛
نرمافزار موردنیاز
- Arduino IDE
معرفی سختافزار برای ساخت ساعت دیجیتال
هماکنون که با موضوع پروژه آشنا شده و تجهیزات موردنیاز برای اینکار را فراهم آوردهاید بهتراست با ویژگیهای فنی و تکنولوژی هر یک نیز آشنا شده و سپس برای ساخت ساعت دیجیتال با آردوینو اقدام نماییم؛
ماژول آردوینو UNO
برای ساخت و کنترل پروژه ساعت و تاریخ با آردوینو میتوانیم از مدل برد UNO آن که یک برد میکروکنترلر اپنسورس مبتنیبر میکروکنترلر ATmega328P است، استفاده نماییم. این برد شامل تعدادی ورودی – خروجی آنالوگ و دیجیتال (GPIOs) است که می توانند به سنسورهای مختلف، محرک ها، بردهای توسعه و مدارهای دیگر متصل شوند. ازجمله ویژگیهای مهم آردوینو UNO میتوان به موارد زیر اشاره کرد:
- 14 پین ورودی – خروجی دیجیتال (که 6 پین آن میتواند به عنوان خروجی PWM استفاده شود)
- 6 ورودی آنالوگ
- رزوناتور سرامیکی 16 مگاهرتز
- 32 کیلوبایت حافظه فلش (0.5 کیلوبایت مورد استفاده بوت لودر)
- 2 کیلوبایت حافظه SRAM
- 1 کیلوبایت حافظه EEPROM
- دارای جک آداپتور مادگی و کانکتور USB
ساخت ساعت با ماژول DS1307
ما در این پروژه برای ساخت ساعت دیجیتالی با آردوینو از ماژول ساعت DS1307 با حافظه EEPROM که یک ساعت – تقویم کم مصرف با کدهای BCD کامل (تبدیل اعداد دسیمال به معادل باینری) میباشد، استفاده میکنیم. جالب است بدانید این ماژول اطلاعات ثانیه، دقیقه، ساعت، روز، ماه، و سال را در حافظه خود نگه میدارد. تاریخ آخر ماه برای ماههایی که کمتر از 31 روز دارند و سالهای کبیسه به طور خودکار تنظیم میشود و ساعت در دو فرمت 24 و 12 ساعته با نشانگر AM/PM قابل نمایش است. همچنین دارای مدار حسگر برق داخلی است که در مواقع قطع تغذیه برای حفظ اطلاعات ساعت و تاریخ به طور خودکار به منبع باتری سکهای 3 ولت CR1225 سوئیچ میکند.
برد رزبریپای فاقد ماژول داخلی محاسبه تاریخ و زمان است. با اتصال ماژول Pi RTC (مبتنی بر تراشه ساعت DS1307) به رزبریپای میتوانید ساعت های زمان واقعی را از طریق ارتباط I2C محاسبه کنید.
چنانچه علاقمند به یادگیری کامل کار با این ماژول هستید، میتوانید برای دریافت اطلاعات بیشتر مقالهی آموزش راه اندازی ماژول ساعت DS1307 با آردوینو را مطالعه نمایید.
پینهای ماژول ساعت DS1307
پس از بررسی کلی مشخصات و اجزای نصب شده روی این ماژول، لازم به شناخت عملکرد هر پین در آن است، که ما در این قسمت به توضیح هریک پرداختهایم:
VCC : پایهی تغذیه ماژول است و ولتاژ کاری آن 5 ولت میباشد.
GND : پایهی تغذیه ماژول است و ولتاژ کاری آن 5 ولت میباشد.
SCL : پایه ورودی کلاک برای واسط I2C است و از آن برای سنکرون کردن انتقال داده بر روی واسط سریال استفاده میشود.
SDA : پایه ورودی – خروجی برای واسط سریال I2C است و به یک مقاومت pull-up خارجی نیاز دارد.
SQW/OUT (موج مربعی/ درایور خروجی): با فعالسازی این پین فعال ، تنظیم بیت SQWE به مقدار 1، پین SQW/OUT یک موج مربعی با یکی از فرکانسهای 1 هرتز، 4 کیلوهرتز، 8 کیلوهرتز، 32 کیلوهرتز را به عنوان خروجی ارائه میدهد و به یک مقاومت pull-up خارجی نیاز دارد.
X1, X2: مدار نوسانساز داخلی برای کار با کریستالی با ظرفیت بار 12.5 پیکو فاراد، طراحی شدهاست. از این دو پایه میتوان برای کریستال کوارتز استاندارد 32.768 کیلوهرتز استفاده کرد.
ماژول نمایشگر نوکیا 5110
در پروژه ساعت دیجیتال با آردوینو ما نیاز به یک نمایشگر برای نشان دادن تاریخ یا زمان شرعی داریم و ال سی دی نوکیا 5110 یک صفحه نمایش تک رنگ 48*84 پیکسل است که دارای نور پس زمینه میباشد و میتوان از آن برای نمایش متن یا تصاویر استفاده کرد. در این ال سی دی از کنترلر PCD8544 استفاده شدهاست (همانطورکه در ال سی دی نوکیا 3310 نیز به کاررفته است). این کنترلر از طریق یک رابط باس سریال مشابه SPI با میکروکنترلرها ارتباط برقرار میکند. برای آشنایی بیشتر با راه اندازی این LCD می توانید مقاله “آموزش راه اندازی ماژول نمایشگر Nokia 5110” را مطالعه نمایید.
پینهای ال سی دی نوکیا 5110
VCC , GND : پایههای تغذیه ال سی دی هستند و ولتاژ کاری آن 3 تا 5 ولت میباشد.
RST : با این پین میتوان نمایشگر را ریست کرد که به صورت فعال صفر (active low) است. همچنین میتوان با اتصال این پین به پین ریست آردوینو، صفحه نمایش را به صورت خودکار ریست کرد.
CE : یک پین به صورت فعال صفر (active low) است و با آن میتوانید دستگاه مورد نظر را از میان دستگاههایی که به یک باس SPI مشترک متصل هستند، انتخاب نمایید.
D/C : پین داده و فرمان است که مشخص میکند نمایشگر در حال دریافت داده یا نمایش داده است. سیگنال HIGH برای داده و سیگنال LOW برای فرمان است.
DIN : پین داده سریال برای رابط SPI است و دادهها را از میکروکنترلر به السیدی ارسال میکند.
CLK (ساعت): با توجه به ارتباط SPI، میکروکنترلر و ال سی دی به یک کلاک مشترک نیاز دارند و این پین به ساخت آن کمک میکند.
BL : نور پسزمینه نمایشگر توسط این پین کنترل میکند. بدینمنظور روشنایی ال سی دی را میتوانید با افزودن یک پتانسیومتر تنظیم کنید یا این پین را به یکی از پینهای PWM آردوینو متصل کنید.
شماتیک مدار ماژول ساعت و آردوینو
مشابه تصویر زیر ابتدا برای ساخت ساعت با ماژول DS1307 و نمایشگر ال سی دی نوکیا 5110 اتصالات لازم را برقرار میکنیم.
مثال: کد آردوینو برای نمایش اوقات شرعی
ابتدا کد زیر را در محیط IDE سیستم خود کپی میکنیم و سپس برای محاسبه زمانهای شرعی به ادامه آموزش میپردازیم:
#include "Wire.h"
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);
int xegg, yegg;
#define DS1307_I2C_ADDRESS 0x68 // This is the I2C address
long previousMillis = 0; // will store last time time was updated
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
long interval = 200;
int displayx, displayy, displayradius, x2, y2, x3, y3;
int zero = 0;
char *Day[] = {"", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
double fajr, sunRise, zuhr, asr, maghrib, isha;
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val / 10 * 16) + (val % 10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val / 16 * 10) + (val % 16) );
}
// Gets the date and time from the ds1307 and prints result
void getDateDs1307()
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
//Wire.write(0x00);
Wire.write(zero);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
second = bcdToDec(Wire.read() & 0x7f);
minute = bcdToDec(Wire.read());
hour = bcdToDec(Wire.read() & 0x3f);
dayOfWeek = bcdToDec(Wire.read());
dayOfMonth = bcdToDec(Wire.read());
month = bcdToDec(Wire.read());
year = bcdToDec(Wire.read());
}
void setDateDs1307()
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(zero);
Wire.write(decToBcd(second)); // 0 to bit 7 starts the clock
Wire.write(decToBcd(minute));
Wire.write(decToBcd(hour)); // for 12 hour am/pm, need to set bit 6 (also need to change readDateDs1307)
Wire.write(decToBcd(dayOfWeek));
Wire.write(decToBcd(dayOfMonth));
Wire.write(decToBcd(month));
Wire.write(decToBcd(year));
Wire.endTransmission();
}
void printTime()
{
int hours, minutes;
char s[12];
display.clearDisplay();
display.setCursor(0, 16);
display.print(Day[dayOfWeek]);
display.print(":");
display.print(char(dayOfMonth / 10 + 0x30));
display.print(char(dayOfMonth % 10 + 0x30));
display.print("/");
display.print(char(month / 10 + 0x30));
display.print(char(month % 10 + 0x30));
display.print("/");
display.print("20");
display.print(char(year / 10 + 0x30));
display.print(char(year % 10 + 0x30));
display.setCursor(18, 26);
display.print( char( hour / 10 + 0x30) );
display.print( char( hour % 10 + 0x30) );
display.print(":");
display.print( char(minute / 10 + 0x30));
display.print( char(minute % 10 + 0x30));
display.print(":");
display.print(char (second / 10 + 0x30));
display.print(char (second % 10 + 0x30));
display.display();
delay(1000);
doubleToHrMin(fajr, hours, minutes);
display.clearDisplay();
display.setCursor(1, 1);
display.print("Fajr ");
display.print(hours);
display.print(":");
display.print(minutes);
display.display();
doubleToHrMin(zuhr, hours, minutes);
display.setCursor(1, 10);
display.print("Zuhr ");
display.print(hours);
display.print(":");
display.print(minutes);
display.display();
doubleToHrMin(asr, hours, minutes);
display.setCursor(1, 20);
display.print("Asr ");
display.print(hours);
display.print(":");
display.print(minutes);
display.display();
doubleToHrMin(maghrib, hours, minutes);
display.setCursor(1, 30);
display.print("Maghrib ");
display.print(hours);
display.print(":");
display.print(minutes);
display.display();
doubleToHrMin(isha, hours, minutes);
display.setCursor(1, 40);
display.print("Isha ");
display.print(hours);
display.print(":");
display.print(minutes);
display.display();
delay(5000);
}
void setup() {
Wire.begin();
display.begin();
display.clearDisplay();
display.setContrast(25);
xegg = (display.width()) / 2;
yegg = (display.height()) / 2;
display.setTextColor(BLACK);
display.setTextSize(1);
display.setCursor(22, 18);
display.print("Hatem");
display.display();
delay(500);
display.setCursor(24, 28);
display.print("ZEHIR");
display.display();
delay(500);
getDateDs1307() ;
}
void loop() {
getDateDs1307() ;
calcPrayerTimes(year, month, dayOfMonth, 52.16, 33, 3.5, -18, -17, fajr, fajr, sunRise, zuhr, asr, maghrib, isha); // year , month, day, Longitude, Latitude, Time Zone, Fajr Twilight, Esha Twilight
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
//getDateDs1307() ;
printTime();
}
}
/*-------------------------------------------------------------------------------------*/
// PRAYER TIME (by Mahmoud Adly Ezzat, Cairo)
//convert Degree to Radian
double degToRad(double degree)
{
return ((3.1415926 / 180) * degree);
}
//convert Radian to Degree
double radToDeg(double radian)
{
return (radian * (180 / 3.1415926));
}
//make sure a value is between 0 and 360
double moreLess360(double value)
{
while (value > 360 || value < 0)
{
if (value > 360)
value -= 360;
else if (value < 0)
value += 360;
}
return value;
}
//make sure a value is between 0 and 24
double moreLess24(double value)
{
while (value > 24 || value < 0)
{
if (value > 24)
value -= 24;
else if (value < 0)
value += 24;
}
return value;
}
//convert the double number to Hours and Minutes
void doubleToHrMin(double number, int &hours, int &minutes)
{
hours = floor(moreLess24(number));
minutes = floor(moreLess24(number - hours) * 60);
}
void calcPrayerTimes(int year, int month, int day,
double longitude, double latitude, int timeZone,
double fajrTwilight, double ishaTwilight,
double &fajrTime, double &sunRiseTime, double &zuhrTime,
double &asrTime, double &maghribTime, double &ishaTime)
{
double D = (367 * year) - ((year + (int)((month + 9) / 12)) * 7 / 4) + (((int)(275 * month / 9)) + day - 730531.5);
double L = 280.461 + 0.9856474 * D;
L = moreLess360(L);
double M = 357.528 + (0.9856003) * D;
M = moreLess360(M);
double Lambda = L + 1.915 * sin(degToRad(M)) + 0.02 * sin(degToRad(2 * M));
Lambda = moreLess360(Lambda);
double Obliquity = 23.439 - 0.0000004 * D;
double Alpha = radToDeg(atan((cos(degToRad(Obliquity)) * tan(degToRad(Lambda)))));
Alpha = moreLess360(Alpha);
Alpha = Alpha - (360 * (int)(Alpha / 360));
Alpha = Alpha + 90 * (floor(Lambda / 90) - floor(Alpha / 90));
double ST = 100.46 + 0.985647352 * D;
double Dec = radToDeg(asin(sin(degToRad(Obliquity)) * sin(degToRad(Lambda))));
double Durinal_Arc = radToDeg(acos((sin(degToRad(-0.8333)) - sin(degToRad(Dec)) * sin(degToRad(latitude))) / (cos(degToRad(Dec)) * cos(degToRad(latitude)))));
double Noon = Alpha - ST;
Noon = moreLess360(Noon);
double UT_Noon = Noon - longitude;
////////////////////////////////////////////
// Calculating Prayer Times Arcs & Times //
//////////////////////////////////////////
// 2) Zuhr Time [Local noon]
zuhrTime = UT_Noon / 15 + timeZone;
// Asr Hanafi
//double Asr_Alt =radToDeg(atan(2+tan(degToRad(latitude - Dec))));
double Asr_Alt = radToDeg(atan(1.7 + tan(degToRad(latitude - Dec))));
// Asr Shafii
//double Asr_Alt = radToDeg(atan(1 + tan(degToRad(latitude - Dec))));
double Asr_Arc = radToDeg(acos((sin(degToRad(90 - Asr_Alt)) - sin(degToRad(Dec)) * sin(degToRad(latitude))) / (cos(degToRad(Dec)) * cos(degToRad(latitude)))));
Asr_Arc = Asr_Arc / 15;
// 3) Asr Time
asrTime = zuhrTime + Asr_Arc;
// 1) Shorouq Time
sunRiseTime = zuhrTime - (Durinal_Arc / 15);
// 4) Maghrib Time
maghribTime = zuhrTime + (Durinal_Arc / 15);
double Esha_Arc = radToDeg(acos((sin(degToRad(ishaTwilight)) - sin(degToRad(Dec)) * sin(degToRad(latitude))) / (cos(degToRad(Dec)) * cos(degToRad(latitude)))));
// 5) Isha Time
ishaTime = zuhrTime + (Esha_Arc / 15);
// 0) Fajr Time
double Fajr_Arc = radToDeg(acos((sin(degToRad(fajrTwilight)) - sin(degToRad(Dec)) * sin(degToRad(latitude))) / (cos(degToRad(Dec)) * cos(degToRad(latitude)))));
fajrTime = zuhrTime - (Fajr_Arc / 15);
return;
}
تکه کد تنظیم اوقات شرعی چگونه کار می کند؟
تابع ()calcPrayerTimes دادههای سال، ماه، روز، طول جغرافیایی، عرض جغرافیایی، منطقه زمانی، طلوع فجر و عشا را به همراه 6 مرجع متغیرهای طلوع فجر، طلوع آفتاب، ظهر، عصر، مغرب و عشا به عنوان ورودی دریافت میکند. همچنین توابعی برای کمک به تبدیل برخی اعداد وجود دارد (به عنوان مثال، رادیان به درجه و بالعکس).
به عنوان مثال برای شهر اصفهان مقادیر زیر را داریم:
- طول جغرافیایی: 52.16
- عرض جغرافیایی: 33
- منطقه زمانی: +3:30
- طلوع فجر: 18–
- عشاء: 17–
بدین ترتیب مقادیر تابع ()calcPrayerTimes در خط ۱۶۱ کد را متناسب با مکان مورد نظر به شکل زیر ویرایش میکنیم:
calcPrayerTimes(year, month, dayOfMonth, 52.16, 33, 3.5, -18, -17, fajr, fajr, sunRise, zuhr, asr, maghrib, isha); // year , month, day, Longitude, Latitude, Time Zone, Fajr Twilight, Esha Twilight
توجه داشته باشید متغیرهای اوقات شرعی از نوع “double” تعریف شدهاند و با استفاده از تابع doubleToHrMin به دو متغیر از نوع int که معادل ساعت و دقیقه هستند، تبدیل میشوند. متناسب با مکان موردنظر نیاز است تا خط 161 کد را ویرایش نمایید:
calcPrayerTimes(year, month, dayOfMonth, 41.3, 20.6, 3, -18.5, -19, fajr, sunRise, zuhr, asr, maghrib, isha);
نحوه محاسبه اوقات شرعی و مختصات جغرافیایی
همانطور که اشاره شد پارامترهای مورد نیاز عبارتند از:
- طول جغرافیایی / عرض جغرافیایی / منطقه زمانی مکان مورد نظر.
- زمان طلوع و غروب خورشید که برای هر کشور متفاوت است.
مختصات جغرافیایی شهر خود مانند طول و عرض جغرافیایی که برنامه برای محاسبه اوقات نماز به آن نیاز دارد را میتوانید با مراجعه به وب سایت IslamFinder و سپس جستجوی شهر خود دریافت کنید. همانطور که در تصویر زیر مشاهده میکنید، پس از جستجوی شهر اصفهان، اوقات نماز و سایر اطلاعات نمایش داده میشود. آنچه که در ساخت ساعت اوقات شرعی با آردوینو برای ما اهمیت دارد طول و عرض جغرافیایی و زاویههای مربوط به فجر و عشا است. این اعداد را در برنامه متناسب با شهر موردنظر خود تغییر دهید.
اگر بر روی گزینهی Calculation Method کلیک کنید پنجرهای مشابه جدول زیر باز خواهد شد که زاویهی خورشید در زمانهای فجر و عشا را به ازای کشورهای مختلف نمایش میدهد که در این بخش برای شهر اصفهان این اوقات شرعی قابل نمایش هستند.
Calculation Method
Organization | Angle of the sun under the horizon (Fajr) | Angle of the sun under the horizon (Isha) | Region |
---|---|---|---|
Muslim World League | 18 degrees | 17 degrees | Europe, The Far East, Parts of the USA |
Egyptian General Authority of Survey | 19.5 degrees | 17.5 degrees | Africa, Syria, Iraq, Lebanon, Malaysia, Parts of the USA |
University Of Islamic Sciences, Karachi | 18 degrees | 18 degrees | Pakistan, Bangladesh, India, Afghanistan, Parts of Europe |
Umm Al-Qura | 18.5 Degrees (19 degrees before 1430 hijri) | 90 minutes after the Sunset Prayer. 120 minutes (in Ramadan only) | The Arabian Peninsula |
Islamic Society of North America | 15 degrees | 15 degrees | Parts of the USA, Canada, Parts of the UK |
Union des Organisations Islamiques de France | 12 degrees | 12 degrees | France region |
Majlis Ugama Islam Singapura | 20 degrees | 18 degrees | Singapore region |
نتیجه گیری
در این آموزش پروژه محور دانستیم که برای راه اندازی و ساخت ساعت دیجیتالی با آردوینو و ماژول DS1307 نیاز به چه قطعات با مشخصاتی داریم و نحوه اتصال آنها به یگدیگر را توسط شماتیک موجود در مقاله انجام دادیم و سپس در محیط کدنویسی آردوینو تکه کد آماده شده مربوط به نمایش اوقات شرعی را قرار داده و با بدست آوردن مختصات و زمان شرعی آنها را جایگزین دادهها در این تکه کد کردیم و در آخر به نتیجه دلخواه خود رسیدیم یعنی نمایش ساعت و زمان نماز روی یک نمایشگر.
امیدواریم شما نیز با ساخت این ساعت به نتیجهای عالی دست یابید و بتوانید کاربرد این آموزش را بسط داده و در برخی پروژههای دیگر نیز از آن استفاده کنید. چنانچه برای انجام و یا مطالعه این مقاله دچار مشکل یا سوالی شدهاید، آن را در بخش دیدگاه همین صفحه با کارشناسان فنی روبوایکیو درمیان گذاشته و پاسخ خود را در اسرع وقت از ما دریافت نمایید.
۸ دیدگاه. Leave new
عالی خیلی خوب توضیح دادید
درود فراوان
متشکریم از شما جواد عزیز 🙂
سلام
ببخشید منطقه زمانی اصفهان مگر +۳.۳۰ نیست؟
ضمنا اوقات شرعی رو متاسفانه هر جور امتحان کردم درست محاسبه نمیکنه
درود برشما مجتبی عزیز
حق با شما بود مقاله اصلاح شد، میتونید دوباره کدبرنامه رو امتحان کنید.
بابت توجهتون متشکریم
سلام.
اگر بخواهیم بجای ماژول DS1307 از ماژول DS3231 استفاده کنیم چه تغییراتی در برنامه نیاز است.
ممنون
درود برشما دوست عزیز
برای DS3231 هم از کد مقاله میتونید استفاده کنید.
موفق باشید
سلام خسته نباشید امید وارم همیشه موفق و پیروز باشید لطفا
راهنمایی کنید چطور میتونم اوقات شرعی را رو max7219 نمایش بدهم ممنون میشوم
سلام دوست عزیز
آموزش استفاده از ماژول max7219 در مقاله زیر توضیح داده شده است می توانید از آن استفاده کنید:
آموزش راه اندازی ماژول دات ماتریس MAX7219 با آردوینو