آموزش ساخت ساعت دیجیتالی با آردوینو

ساخت و راه‌انداز ی ساعت و اوقات شرعی با آردوینو

در پروژه ساخت ساعت دیجیتالی با آردوینو قصد داریم با استفاده از یک آردوینو و ماژول ساعت 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 سوئیچ می‌کند.

اجزای نصب شده روی ماژول ساعت DS1307
مکان نصب باتری سکه‌ای روی ماژول ساعت DS1307

برد رزبری‌پای فاقد ماژول داخلی محاسبه تاریخ و زمان است. با اتصال ماژول Pi RTC (مبتنی بر تراشه ساعت DS1307) به رزبری‌پای می‌توانید ساعت های زمان واقعی را از طریق ارتباط I2C محاسبه کنید.

چنانچه علاقمند به یادگیری کامل کار با این ماژول هستید، می‌توانید برای دریافت اطلاعات بیشتر مقاله‌ی آموزش راه اندازی ماژول ساعت DS1307 با آردوینو را مطالعه نمایید.

پین‌های ماژول ساعت 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 برای نمایش زمان در پروژه ساخت ساعت با آردوینو

پین‌های ال‌ سی‌ دی نوکیا 5110

معرفی پین‌های ماژول نمایشگر ال سی دی نوکیا 5110 برای نمایش و ساخت ساعت با ماژول DS1307

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

OrganizationAngle of the sun under the horizon (Fajr)Angle of the sun under the horizon (Isha)Region
Muslim World League18 degrees17 degreesEurope, The Far East, Parts of the USA
Egyptian General Authority of Survey19.5 degrees17.5 degreesAfrica, Syria, Iraq, Lebanon, Malaysia, Parts of the USA
University Of Islamic Sciences, Karachi18 degrees18 degreesPakistan, Bangladesh, India, Afghanistan, Parts of Europe
Umm Al-Qura18.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 America15 degrees15 degreesParts of the USA, Canada, Parts of the UK
Union des Organisations Islamiques de France12 degrees12 degreesFrance region
Majlis Ugama Islam Singapura20 degrees18 degreesSingapore region

نتیجه گیری

در این آموزش پروژه محور دانستیم که برای راه اندازی و ساخت ساعت دیجیتالی با آردوینو و ماژول DS1307 نیاز به چه قطعات با مشخصاتی داریم و نحوه اتصال آن‌ها به یگدیگر را توسط شماتیک موجود در مقاله انجام دادیم و سپس در محیط کدنویسی آردوینو تکه کد آماده شده مربوط به نمایش اوقات شرعی را قرار داده و با بدست آوردن مختصات و زمان شرعی آن‌ها را جایگزین داده‌ها در این تکه کد کردیم و در آخر به نتیجه دلخواه خود رسیدیم یعنی نمایش ساعت و زمان نماز روی یک نمایشگر.

امیدواریم شما نیز با ساخت این ساعت به نتیجه‌ای عالی دست یابید و بتوانید کاربرد این آموزش را بسط داده و در برخی پروژه‌های دیگر نیز از آن استفاده کنید. چنانچه برای انجام و یا مطالعه این مقاله دچار مشکل یا سوالی شده‌اید، آن را در بخش دیدگاه همین صفحه با کارشناسان فنی روبوایکیو درمیان گذاشته و پاسخ خود را در اسرع وقت از ما دریافت نمایید.

مقالات مشابه

۶ دیدگاه. Leave new

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

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

Fill out this field
Fill out this field
لطفاً یک نشانی ایمیل معتبر بنویسید.
You need to agree with the terms to proceed

پر بازدید ترین مقالات