Sinkronisasi Waktu Dengan Network Time Protocol (NTP) pada Mikrokontroler ESP32

NTP (Network Time Protocol) adalah protokol komunikasi di jaringan komputer untuk sinkronisasi waktu melalui jaringan komputer. Sinkronisasi waktu ini penting pada aplikasi-aplikasi yang berbasis pewaktuan yang tepat, misalnya pencatatan ataupun untuk koordinasi aktivitas di suatu sistem berbasis IoT (Internet of Things).

ESP32 adalah mikrokontroler yang memiliki fitur Wi-Fi yang memungkinkan untuk tersambung ke jaringan komputer, termasuk ke suatu server NTP. ESP32 dapat menggunakan protokol NTP untuk sinkronisasi waktu dengan server NTP. Proses ini menyederhanakan kalibrasi waktu di ESP32. Alternatif lainnya adalah menggunakan RTC (real time clock) yaitu jam digital yang dibackup dengan baterai, ataupun dengan setting waktu secara manual. Teknik RTC perlu komponen tambahan, sedangkan setting manual memerlukan waktu dan tenaga. Selain itu sumber waktu di ESP32 juga tidak sepresisi sumber waktu di server NTP, sehingga setelah beberapa waktu maka jam di ESP32 akan bergeser dari setting awal.

Untuk mengakses NTP dari ESP32 dapat menggunakan library yang sudah ada, jadi tidak perlu lagi koding protokol secara dari nol. Library yang umum dipakai ada 2 macam yaitu:

  • Arduino Library NTPClient untuk Arduino. Library ini dapat dipakai di semua mikrokontroler Arduino.
  • Arduino ESP32 NTP untuk ESP32. Library ini hanya dapat dipakai untuk ESP32.

Persiapan

Sebelum menjalankan program NTP ini, ada beberapa hal yang perlu diperhatikan:

  • Arduino IDE sudah diinstal di desktop/laptop, dan libraray Arduino-ESP32 sudah diaktifkan
  • Konfigurasi ESP32 sudah diujicoba dengan program sederhana, misalnya lampu kedip (Blink)
  • Wi-Fi akses point dapat mengakses internet tersedia, dan juga sudah disiapkan nama akses point dan passwordnya.
  • Pahami zona waktu tempat anda. NTP memberikan waktu dengan standar GMT+0, jadi perlu disesuaikan jika anda memerlukan waktu lokal.

Arduino NTPClient

Cara pertama adalah menggunakan library NTPClient Arduino. Library ini dicantumkan di laman NTPClient di situs Arduino, namun tidak ada penjelasan sama sekali di situs tersebut. Untuk cara penggunaannya kita perlu melihat repository NTPClient di github. Contoh penggunaan ada di direktori /examples di repository tersebut.

Contoh kode juga dapat diakses dari Arduino IDE, dari menu File -> Examples -> NTPClient. Namun sedikit repot, karena daftar Examples cukup banyak dan urutannya tidak tepat abjad. Berikut ini tampilan menunya di Arduino IDE. (klik untuk gambar yang lebih besar).

Kode yang mudah dipakai adalah yang ‘Basic’ , namun kode ini perlu diubah sedikit seperti pada listing kode berikut ini.

#include <NTPClient.h>
// change next line to use with another board/shield
//#include <ESP8266WiFi.h>
#include <WiFi.h> // for WiFi shield
//#include <WiFi101.h> // for WiFi 101 shield or MKR1000
#include <WiFiUdp.h>

const char *ssid = "AP_NAME";
const char *password = "AP_PASSWORD";

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);

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.println(timeClient.getFormattedTime());
  delay(1000);
}

Perubahan yang dilakukan adalah sebagai berikut:

  • Kode ini awalnya untuk ESP8266. Untuk dipakai di ESP32 maka header file mesti diganti, dari “ESP8266WiFi.h” menjadi “WiFi.h”
  • Sesuaikan nama SSID untuk akses point
  • Sesuaikan password untuk mengakses akses point. Perhatikan bahwa program NTP ini hanya dapat berfungsi jika ESP32 tersambung ke internet. Jadi pastikan Wi-Fi access point tersambung ke internet atau bisa juga menggunakan tethering ke smartphone

Berikut ini tampilan output ESP32 di serial monitor Arduino. Waktu adalah GMT+0, sedangkan di Indonesia adalah GMT+7, sehingga jam yang ditampilkan berbeda 7 jam.

Program di atas menampilkan waktu dalam UTC atau GMT+0. Untuk menampilkan dalam waktu lokal seperti WIB (Waktu Indonesia bagian Barat), gunakan fungsi setTimeOffset() untuk menambah/mengurangi waktu yang ditampilkan. Untuk WIB, waktu yang ditambah dalam detik adalah 7 x 60 x 60. Programnya menjadi sebagai berikut:

#include <NTPClient.h>
// change next line to use with another board/shield
//#include <ESP8266WiFi.h>
#include <WiFi.h> // for WiFi shield
//#include <WiFi101.h> // for WiFi 101 shield or MKR1000
#include <WiFiUdp.h>

const char *ssid = "AP_NAME";
const char *password = "AP_PASSWORD";

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);

void setup() {
  Serial.begin(115200); 
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  timeClient.begin();
  timeClient.setTimeOffset(7*60*60);
}
void loop() {
  timeClient.update();
  Serial.println(timeClient.getFormattedTime());
  delay(1000);
}

Beberapa hal yang dapat diambil/diubah dengan member function di di class NTPClient :

  • SetPoolServerName() : mengubah NTP server dari default pool.ntp.org
  • isTimeSet() : apakah berhasil mengambil waktu dari NTP server
  • getDay() : ambil hari dalam minggu (0 = minggu)
  • getHours() : ambil waktu jam
  • getMinutes() : ambil waktu menit
  • getSeconds() : ambil waktu detik
  • setTimeOffset() : menambah/mengurangi offset waktu yang ditampilkan dalam detik
  • getFormattedTime() : waktu terformat dalam bentuk string
  • getEpochTime() : jumlah detik sejak 1 Januari 1970

Arduino ESP32 NTP Library

Library ini adalah bagian dari Arduino ESP32, jadi hanya dapat dipakai di ESP32.

Fungsi-fungsi penting adalah:

  • getLocalTime() untuk mendapatkan waktu
  • configTime() untuk setting NTP
  • configTzTime() untuk set timezone

Contoh kode diambil dari contoh program SimpleTime.ino di repository arduino-esp32 .

Daftar timezone yang dapat dipakai dapat dilihat di https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h

Berikut ini adalah kode yang sudah dimodifikasi:

// sumber: libraries/ESP32/examples/Time/SimpleTime/SimpleTime.ino
// URL: https://github.com/espressif/arduino-esp32/blob/496b8411773243e1ad88a68652d6982ba2366d6b/libraries/ESP32/examples/Time/SimpleTime/SimpleTime.ino
// dimodifikasi untuk WIB (GMT+7)

#include <WiFi.h>
#include "time.h"
#include "esp_sntp.h"

const char *ssid = "AP_NAME";
const char *password = "AP_PASSWORD";

const char *ntpServer1 = "pool.ntp.org";
const char *ntpServer2 = "time.nist.gov";
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;

//const char *time_zone = "CET-1CEST,M3.5.0,M10.5.0/3";  // TimeZone rule for Europe/Rome including daylight adjustment rules (optional)
const char *time_zone = "WIB-7";  // Indonesia WIB

void printLocalTime() {
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("No time available (yet)");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

// Callback function (gets called when time adjusts via NTP)
void timeavailable(struct timeval *t) {
  Serial.println("Got time adjustment from NTP!");
  printLocalTime();
}

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

  // First step is to configure WiFi STA and connect in order to get the current time and date.
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);

  /**
   * NTP server address could be acquired via DHCP,
   *
   * NOTE: This call should be made BEFORE esp32 acquires IP address via DHCP,
   * otherwise SNTP option 42 would be rejected by default.
   * NOTE: configTime() function call if made AFTER DHCP-client run
   * will OVERRIDE acquired NTP server address
   */
  esp_sntp_servermode_dhcp(1);  // (optional)

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

  // set notification call-back function
  sntp_set_time_sync_notification_cb(timeavailable);

  /**
   * This will set configured ntp servers and constant TimeZone/daylightOffset
   * should be OK if your time zone does not need to adjust daylightOffset twice a year,
   * in such a case time adjustment won't be handled automagically.
   */
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);

  /**
   * A more convenient approach to handle TimeZones with daylightOffset
   * would be to specify a environment variable with TimeZone definition including daylight adjustmnet rules.
   * A list of rules for your zone could be obtained from https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h
   */
  configTzTime(time_zone, ntpServer1, ntpServer2);
}

void loop() {
  delay(5000);
  printLocalTime();  // it will take some time to sync time :)
}

Penyesuaian yang dilakukan adalah sebagai berikut:

  • Timezone diganti menjadi Waktu Indonesia bagian Barat (WIB-7)

Berikut ini output program di serial terminal

Kedua library tersebut fungsinya mirip-mirip. Library ESP32 memiliki fitur lebih banyak dan lebih cocok untuk dijalankan di ESP32.

Saran & Penyempurnaan

Contoh program NTP yang disajikan adalah program yang sangat minimalis untuk menunjukkan konsep NTP. Pada kondisi sesungguhnya, sistem mikrokontroler IoT ini akan menghadapi berbagai masalah, sehingga perlu ditambahkan penanganan beberapa kasus berikut:

  • Koneksi ESP32 ke server NTP tidak stabil, baik di local network maupun di internetnya.
  • Pada program perlu ditambahkan error handling jika terjadi koneksi internet putus ataupun koneksi Wi-Fi putus. Jika koneksi Wi-Fi putus, maka perlu ada prosedur untuk melakukan rekoneksi ulang ke akses point Wi-Fi. Jadi tidak perlu reset manual.
  • Pengubahan konfigurasi nama akses point dan password akses point secara software dengan interface tertentu. Pada contoh ini nama dan password dikodekan langsung di source code sehingga tidak dapat diubah. Pada kondisi nyata seharusnya dapat diubah oleh pemakai tanpa perlu mengubah source code.

Literatur

Tinggalkan Balasan

Situs ini menggunakan Akismet untuk mengurangi spam. Pelajari bagaimana data komentar Anda diproses.

Scroll to Top