Biasanya untuk menampilkan real time tanggal dan jam diperlukan module RTC (Real Time Clock) seperti DS1307 dan DS323. Namun jika kita memiliki koneksi internet, kita bisa memanfaatkan NTP (Network Time Protocol) untuk mendapatkan informasi tanggal dan jam secara real time. Caranya dengan mengkoneksikan modul wifi Wemos D1 R1 atau modul ESP8266 lainnya dengan NTP server.
Hardware yang kita perlukan untuk mempraktikan tutorial ini hanya board Wemos D1 R1 dan kabel data micro USB yang biasa kita pakai untuk mencharge handphone. Sebagai langkah persiapan, hubungkan board Wemos D1 R1 ke komputer melalui port USB dan pastikan port USB yang sudah terhubung dengan Wemos D1 R1 terbaca di device manager.
Dari gambar di atas terlihat board Wemos D1 R1 sudah terkoneksi dengan komputer melalui ports COM8 (USB-SERIAL CH340).
Langkah persiapan selanjutnya adalah setting board dan port dari perangkat Wemos D1 R1. Buka Arduino IDE, pilih board LOLIN(Wemos D1 R1) melalui Tools->Board.
Jika board LOLIN(Wemos D1 R1) tidak tersedia di Arduino IDE anda, maka anda harus menginstall add on board ESP8266 terlebih dahulu. Untuk cara menginstalnya bisa dibaca di Cara Install Board Wemos D1 R1 di Arduino IDE.
Setelah memilih board, kemudian pilih port melalui Tools->Port. Pilih port seperti yang tertera di Device Manager yaitu port USB-SERIAL CH340 (COM8).
Selesai sudah langkah persiapannya, selanjutnya kita ke inti pembahasan yaitu instalasi librari NTPClient, sedikit modifikasi library dan terakhir menampilkan real time tanggal dan jam dari NTP Client.
1. Instalasi NTP Client
- Buka Library Manager melalui Tools->Library Manager
- Ketikkan "ntpclient" pada text box pencarian
- Klik tombol Install
2. Modifikasi librari NTP Client
Setelah library NTPClient terinstall, kita buka folder NTPClient (folder hasil instalasi) di C:\Users\NamaPcAnda\Documents\Arduino\libraries\NTPClient (untuk OS Windows 10). Di dalam folder NTPClient ini terdapat beberapa file, dan yang akan kita modifikasi atau update adalah file NTPClient.cpp dan NTPClient.h
Tujuan kita memodifikasi NTPClient.cpp dan NTPClient.h adalah untuk menambahkan fungsi getYear(), getMonth() dan getDate(), karena ketiga fungsi tersebut tidak ada di file aslinya. Adapun ketiga fungsi tersebut kita perlukan untuk menampilkan tanggal, bulan dan hari di tutorial ini.
2.1 NTPClient.cpp
Buka file NTPCleint.cpp dengan text editor Notepad++
kemudian kita akan tambahkan snippet code berikut di baris ke 91:
uint32_t _days2k = (_currentEpoc - SEC20200101)/86400; // distance to today in days
if (_days2k > DAYSOF4YEARS) { // how many four-year packages + remaining days, from 2050 faster than subtraction on an esp8266 ;)
_year = _days2k / DAYSOF4YEARS;
_days2k = _days2k - _year * DAYSOF4YEARS;
_year *= 4;
}
if (_days2k > DAYSOFAYEAR + 1) { //2020 was a leap year, how many years + remaining days
_days2k--;
while (_days2k > DAYSOFAYEAR) { //three times at most
_days2k -= DAYSOFAYEAR;
_year++;
}
} else _isLeapYear = true;
_year += 20; // + 2020
if (_isLeapYear && _days2k > 60) _days2k--; // subtract the possible leap day when February passed
if (_days2k > 334) { _month = 12; _date = _days2k - 334; } //boring but quick
else if (_days2k > 304) { _month = 11; _date = _days2k - 304; }
else if (_days2k > 273) { _month = 10; _date = _days2k - 273; }
else if (_days2k > 243) { _month = 9; _date = _days2k - 243; }
else if (_days2k > 212) { _month = 8; _date = _days2k - 212; }
else if (_days2k > 181) { _month = 7; _date = _days2k - 181; }
else if (_days2k > 151) { _month = 6; _date = _days2k - 151; }
else if (_days2k > 120) { _month = 5; _date = _days2k - 120; }
else if (_days2k > 90) { _month = 4; _date = _days2k - 90; }
else if (_days2k > 59) { _month = 3; _date = _days2k - 59; }
else if (_days2k > 31) { _month = 2; _date = _days2k - 31; }
else { _month = 1; _date = _days2k; }
Sebelum dan sesudah penambahan snippet code di NTPClient.cpp baris ke 91:
Masih di file NTPClient.cpp, tambahkan snippet code berikut di akhir baris NTPClient.cpp:
bool NTPClient::isLeapYear() const {
return this->_isLeapYear;
}
int NTPClient::getYear() const {
return this->_year;
}
int NTPClient::getMonth() const {
return this->_month;
}
int NTPClient::getDate() const {
return this->_date;
}
Sebelum dan sesudah penambahan snippet code di akhir baris NTPClient.cpp:
2.2 NTPClient.h
Buka file NTPCleint.h dengan text editor Notepad++
- Copy kode berikut kemudian paste ke line 10 NTPClient.h
#define DAYSOF4YEARS 1461UL // 4*year plus leap day
#define DAYSOFAYEAR 365UL
#define SEC20200101 1577750400UL // 2020/01/01 - 1 day (86400s) because the result of the integer division is rounded off
- Copy kode berikut kemudian paste ke line 24 NTPClient.h
uint16_t _date = 0;
uint16_t _month = 0;
uint16_t _year = 0;
bool _isLeapYear = false;
- Copy kode berikut kemudian paste ke line 35 NTPClient.h
bool isLeapYear() const;
int getYear() const;
int getMonth() const;
int getDate() const;
Sebelum dan sesudah penambahan snippet code di NTPClient.h:
3. Menampilkan real time tanggal dan jam dari NTPClient
Sampai kita di pembahasan terakhir dari tutorial ini, yaitu menampilkan tanggal dan jam dari NTP Server secara real time melalui serial monitor Arduino IDE. Langsung saja kita buka kembali Arduino IDE nya kemudian copy paste kode di bawah ini:
#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
const char *ssid = "YOUR_WIFI_NETWORK_NAME";
const char *password = "YOUR_WIFI_PASSWORD";
const long utcOffsetInSeconds = 3600;
String daysOfTheWeek[7] = {"Ahad ", "Senin ", "Selasa", "Rabu ", "Kamis ", "Jumat ", "Sabtu "};
String months[12]={"Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Agu", "Sep", "Okt", "Nov", "Des"};
// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "id.pool.ntp.org", utcOffsetInSeconds);
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_OFF); //Prevents reconnection issue (taking too long to connect)
delay(1000);
WiFi.mode(WIFI_STA); //Only Station No AP, This line hides the viewing of ESP as wifi hotspot
WiFi.begin(ssid, password); //Connect to your WiFi router
Serial.println("");
Serial.print("Connecting");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
//If connection successful show IP address in serial monitor
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); //IP address assigned to your ESP
timeClient.begin();
timeClient.setTimeOffset(25200);
}
void loop() {
timeClient.update();
Serial.print(daysOfTheWeek[timeClient.getDay()]);
Serial.print(", ");
Serial.print(timeClient.getDate());
Serial.print(" ");
Serial.print(months[int(timeClient.getMonth()) - 1]);
Serial.print(" - ");
if (int(timeClient.getHours()) > 9) {
Serial.print(timeClient.getHours());
} else {
Serial.print("0");
Serial.print(timeClient.getHours());
}
Serial.print(":");
if (int(timeClient.getMinutes()) > 9) {
Serial.print(timeClient.getMinutes());
} else {
Serial.print("0");
Serial.print(timeClient.getMinutes());
}
Serial.print(":");
if (int(timeClient.getSeconds()) > 9) {
Serial.print(timeClient.getSeconds());
} else {
Serial.print("0");
Serial.print(timeClient.getSeconds());
}
Serial.println(" ");
delay(1000);
}
Klik Upload dan tunggu sampai Done Uploading.
Klik tombol Serial Monitor di Arduino IDE. Setting baud rate di serial monitor menjadi 115200. Tiap 1 detik NTP Client merequest paket time stamp ke NTP Server dan ditampilkan ke serial monitor.
Bagaimana NTP Bekerja?
NTP dapat beroperasi dalam beberapa cara. Konfigurasi yang paling umum adalah beroperasi dalam mode client-server. Prinsip kerja dasarnya adalah sebagai berikut:
- Perangkat klien seperti ESP8266 terhubung ke server menggunakan User Datagram Protocol (UDP) pada port 123.
- Klien kemudian mengirimkan paket permintaan ke server NTP.
- Menanggapi permintaan ini, server NTP mengirimkan paket timestamp.
- Paket time stamp ini berisi banyak informasi seperti UNIX time stamp, akurasi, delay atau zona waktu.
- Klien kemudian dapat menguraikan nilai tanggal & waktu saat ini.
Referensi: