آموزش دریافت زمان از سرور NTP با برد ESP8266

دریافت زمان از سرور NTP با برد ESP8266

ممکن است تا به حال به پروژه‌ای فکر کرده باشید که در آن دسترسی به زمان برایتان اهمیت داشته باشد. برای مثال، یک رله را تصور کنید که باید در زمان مشخصی فعال شود یا یک دیتالاگر که در فاصله‌های زمانی دقیقی اطلاعات را ذخیره کند. استفاده از یک تراشه Real Time Clock یا RTC اولین چیزی است که به ذهن می‌رسد. اما این تراشه‌­ها کاملا دقیق نیستند و بنابراین نیاز است به طور مرتب تنظیم و همگام‌سازی شوند. اینجاست که دریافت زمان از سرور NTP با برد ESP8266 کمک بسیار زیادی می‌تواند به شما بکند.

بهترین راه‌حل، استفاده از پروتکل زمان شبکه (Network Time Protocol یا NTP) است. اگر در پروژه شما میکروکنترلر ESP8266 به اینترنت دسترسی دارد، شما می‌توانید زمان و تاریخ را (با دقت چند میلی‌ثانیه نسبت به UTC) به طور رایگان و بدون نیاز به سخت‌افزار دیگری در اختیار داشته باشید.

NTP چیست؟

قبل از شروع به دریافت زمان از سرور NTP با برد ESP8266 بهتر است با NTP و کارکرد آن آشنا شویم.

NTP مخفف عبارت Network Time Protocol و یک IP استاندارد برای تنظیم کردن ساعت کامپیوترها با یک مرجع واحد بر بستر اینترنت است.

این پروتکل تمام دستگاه‌های متصل به شبکه را با زمان جهانی (Coordinated Universal Time یا UTC) همگام می‌کند. تاخیر این همگام سازی حدود 50 میلی‌ثانیه از طریق اینترنت عمومی و کمتر از 5 میلی‌ثانیه برای ارتباط LAN است.

UTC یک استاندارد جهانی برای زمان است که ارتباط تنگاتنگی با ساعت جهانی گرینویچ (GMT) دارد. UTC در همه نقاط کره زمین ثابت است.

NTP ساعت همه کامپیوترها را روی UTC تنظیم می‌کند و زمان‌های محلی یا جلو کشیدن ساعت تابستانی توسط خود دستگاه انجام می‌شود. این راه باعث می‌شود دستگاه‌ها و سرورها فارغ از تفاوت‌های مناطق زمانی و موقعیت جغرافیایی با هم همگام شوند.

معماری NTP

NTP از ساختار سلسله مراتبی استفاده می‌کند. در این ساختار هر سطح یک لایه (stratum) نامیده می‌شود.

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

ساعت سرورهای لایه یک به خاطر ارتباط مستقیم با ساعت‌های لایه صفر، دقیق‌ است.

هر لایه در این نمودار با لایه بالایی سنکرون است و به عنوان سرور لایه پایینی خود عمل می‌کند.

در ادامه مقاله به نحوه کارکرد سرور NTP می‌پردازیم.

ارتباط لایه‌های مختلف ntp با یکدیگر

NTP چگونه کار می‌کند؟

چند نوع عملکرد برای NTP وجود دارد. معمول‌ترین نوع پیکربندی آن حالت کلاینت-سرور است که عملکرد ساده آن به این صورت است:

  1. دستگاه کلاینت (مانند ESP8266) با استفاده از پروتکل UDP (User Datagram Protocol) به سرور متصل می‌شود.
  2. UDP یک پروتکل ارتباطی است که برای کاربردهای حساس به زمان مانند VoD مورد استفاده قرار می­‌گیرند. در این پروتکل، بسته‌های داده بدون اصلاح خطا منتقل می‌شوند. در حقیقت برخلاف پروتکل TCP که گیرنده پس از دریافت هر بسته، پیغامی مبنی بر تایید دریافت بسته ارسال می‌کند و فرستنده پس از دریافت پیغام تایید، بسته بعدی را ارسال می‌کند، در پروتکل UDP سازوکار تاییدی وجود ندارد. از این رو این پروتکل سرعت بالاتر و امنیت پایین‌تری دارد.
  3. کلاینت یک بسته داده درخواست (request) به سرور NTP ارسال می‌کند.
  4. در پاسخ به این درخواست، سرور NTP یک بسته  داده time stamp ارسال می‌کند.
  5. بسته داده time stamp شامل اطلاعاتی از قبیل UNIX، دقت، تاخیر یا منطقه زمانی می‌شود.
  6. UNIX Timestamp در اصل تعداد ثانیه‌هایی است که از تاریخ 1 ژانویه 1970 گذشته است. این عدد هنگام نگارش این مقاله برابر 1654888102 است.
  7. سپس کلاینت تاریخ و ساعت را استخراج می‌کند.
ارتباط و انتقال دیتا بین برد esp8266 و سرور ntp

آماده‌سازی IDE آردوینو برای دریافت زمان از NTP با ESP8266

از بحث تئوری که بگذریم، نوبت انجام کار عملی است!

قبل از اینکه ادامه مطلب را دنبال کنید، مطمئن شوید که افزونه ESP8266 روی IDE آردوینو شما نصب شده است. اگر این افزونه را نصب ندارید آموزش زیر را دنبال کنید:



نصب کتابخانه کلاینت NTP

ساده‌ترین روش دریافت تاریخ و ساعت از یک سرور NTP استفاده از کتابخانه NTP Client from Arduino است. برای نصب این کتابخانه مراحل زیر را دنبال کنید.

برای نصب کتابخانه به مسیر Arduino IDE > Sketch > Include Library > Manage Libraries بروید. صبر کنید تا Library Manager لیست کتابخانه‌ها را دانلود کرده و لیست کتابخانه‌های نصب شده را آپدیت کند.

جستجوی خود را با نوشتن عبارت ‘ntpclient’ فیلتر کنید. از بین چند گزینه‌ای که می‌بینید، NTPClient از Fabrice Weinberg را پیدا کرده و آن را نصب کنید.

جستجو و نصب کتابخانه NTPClient

دریافت تاریخ و ساعت از سرور NTP با برد ESP8266

با استفاده از برنامه زیر، می‌توانید درک کاملی از نحوه دریافت اطلاعات از سرور NTP به‌­دست آورید.

مثل همیشه قبل از اینکه برنامه را آپلود کنید باید تغییری در آن اعمال کنید و آن تغییر دو متغیر زیر برحسب مشخصات شبکه خود است. با این کار ESP8266 می‌تواند به شبکه متصل شود.

const char* ssid       = "YOUR_SSID";
const char* password   = "YOUR_PASS";

همچنین باید اختلاف زمانی منطقه زمانی خود را با UTC برحسب میلی‌­ثانیه وارد کنید. برای اطلاع از اختلاف زمانی منطقه خود می‌توانید به لیست زمان‌های UTC مراجعه کنید. چند نمونه برای مناطق زمانی مختلف را در زیر آورده‌ایم، مورد اول را برای منطقه زمانی تهران (UTC +3:30) می‌توانید استفاده کنید:

  • برای UTC +3.5: 3.5*60*60: 12600
  • برای UTC -5.00: -5*60*60: -18000
  • برای UTC +1.00: 1*60*60: 3600
  • برای UTC +0.00: 0*60*60: 0
const long utcOffsetInSeconds = 3600;

پس از اعمال تغییرات، برنامه زیر را امتحان کنید:

#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char *ssid     = "YOUR_SSID";
const char *password = "YOUR_PASS";

const long utcOffsetInSeconds = 3600;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);

void setup(){
  Serial.begin(115200);

  WiFi.begin(ssid, password);

  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }

  timeClient.begin();
}

void loop() {
  timeClient.update();

  Serial.print(daysOfTheWeek[timeClient.getDay()]);
  Serial.print(", ");
  Serial.print(timeClient.getHours());
  Serial.print(":");
  Serial.print(timeClient.getMinutes());
  Serial.print(":");
  Serial.println(timeClient.getSeconds());
  //Serial.println(timeClient.getFormattedTime());

  delay(1000);
}

پس از آپلود برنامه، دکمه RST روی برد NodeMCU خود را فشار دهید، حال باید هر ثانیه روز و تاریخ را در سریال مانیتور به صورت زیر مشاهده کنید:

مشاهده ساعت و تاریخ دریافت شده از NTP در سریال مانیتور

توضیح کد

بیایید نگاهی سریع به کد داشته باشید تا ببینیم پروژه دریافت زمان از سرور NTP با برد ESP8266 چگونه کار می‌کند.

ابتدا کتابخانه‌های لازم برای پروژه را اضافه کرده‌ایم:

  • NTPClient.h: این کتابخانه، سنکرون‌­سازی زمان با سرور NTP را انجام می‌دهد.
  • ESP8266WiFi.h: این کتابخانه شامل توابعی است که برای اتصال ESP8266 به شبکه استفاده می‌شوند.
  • WiFiUdp.h: این کتابخانه ارتباط UDP را مدیریت می‌کند. باز کردن پورت UDP، ارسال و دریافت بسته‌های داده UDP و.. از جمله کاربردهای آن است.
#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

سپس ثوابتی مثل SSID، پسورد WiFi و اختلاف زمانی UTC که در موردشان صحبت شد را تعریف کرده‌ایم. همچنین یک آرایه دو بعدی کاراکتری به نام daysofTheWeek تعریف کرده و نام روز‌های هفته را در آن نوشته‌ایم.

حال قبل از شروع به کار شی کلاینت NTP ، باید آدرس سرور NTP که می‌خواهیم از آن استفاده کنیم را مشخص کنیم. یکی از پروژه‌های NTP مناسب، pool.ntp.org است که از آن استفاده خواهیم کرد.

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);

Pool.ntp.org به طور خودکار سرورهای نزدیک به شما از نظر جغرافیایی را انتخاب می‌کند. ولی همانطور که در جدول زیر ذکر شده، می‌توان با استفاده از نواحی زیرمجموعه pool.ntp.org، یک منطقه مشخص را انتخاب کرد.

نام هاستمنطقه
pool.ntp.orgجهانی
asia.pool.ntp.orgآسیا
europe.pool.ntp.orgاروپا
north-america.pool.ntp.orgآمریکای شمالی
oceania.pool.ntp.orgاقیانوسیه
south-america.pool.ntp.org  آمریکای جنوبی

در تابع Setup، ابتدا ارتباط سریال را با کامپیوتر راه‌اندازی کرده و سپس با دستور WiFi.begin() به شبکه WiFi متصل می‌شویم.

Serial.begin(115200);

WiFi.begin(ssid, password);

while ( WiFi.status() != WL_CONNECTED ) {
  delay ( 500 );
  Serial.print ( "." );
}

پس از اینکه ESP8266 به شبکه متصل شد، شی کتابخانه کلاینت NTP را با تابع ()begin راه‌اندازی می‌کنیم.

timeClient.begin();

حال هر زمان که بخواهیم به روز و ساعت دسترسی پیدا کنیم، کافیست به سادگی تابع ()update را فراخوانی کنیم. این تابع یک درخواست با پروتکل UDP به سرور NTP ارسال کرده و time stamp دریافتی را به یک فرمت قابل خواندن تفسیر می­‌کند.

timeClient.update();

در نهایت با استفاده از توابع NTP Client، می­توان اطلاعات روز و زمان را دریافت کرد.

Serial.print(daysOfTheWeek[timeClient.getDay()]);
Serial.print(", ");
Serial.print(timeClient.getHours());
Serial.print(":");
Serial.print(timeClient.getMinutes());
Serial.print(":");
Serial.println(timeClient.getSeconds());

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

مقالات مشابه

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

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

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

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