lwIP dan ESP32 – SNTP

SNTP adalah protokol sinkronisasi untuk perangkat network. Transport layer yang digunakan adalah UDP. Client melakukan request universal time dari SNTP server yang digunakan untuk update internal time.

Pada modul ini kita akan membuat digital clock. ESP32 melakukan query ke SNTP server untuk mendapatkan universal time, setelah time infor diperoleh, akan ditampilkan ke OLED display denga format hour-minute-second.

Hardware yang digunakan adalah OLED display, SDA dan SCL akan dihubungkan ke GPIO21 dan GPIO22.

Buat project baru, lalu edit file platformio.ini

[env:az-delivery-devkit-v4]
platform = espressif32
board = az-delivery-devkit-v4
framework = espidf
monitor_speed = 115200
lib_extra_dirs =
../../common/components
../../common/esp-idf-lib/components
build_flags =
-DWIFI_SSID=${sysenv.WIFI_SSID}
-DWIFI_PASS=${sysenv.WIFI_PASS}

Gunakan wifi_library dari project sebelumnya.

Kemudian ubah nama main.c menjadi main.cpp agar dicompile oleh C++ compiler.

Code

Buka file main.cpp, tambahkan code berikut

#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include "esp_log.h"
#include "esp_sntp.h"
#include "ssd1306.h"
#include "wifi_connect.h"

#define TAG "sntp_ex"
#define OLED_CLK 22
#define OLED_SDA 21
extern "C" void app_main(void);

//main function
void app_main()
{
    init_hw();
    connect_wifi_params_t p = {
    .on_connected = wifi_conn_cb,
    .on_failed = wifi_failed_cb};
    connect_wifi(p);
}


//init hardware
static void init_hw(void)
{
    ssd1306_128x64_i2c_initEx(OLED_CLK, OLED_SDA, 0);
}

//wifi connect
void wifi_conn_cb(void)
{
    init_sntp();
    xTaskCreate(sync_time, "sync", 8192, NULL, 5, NULL);
}

//wifi failed
void wifi_failed_cb(void)
{
    ESP_LOGE(TAG, "wifi failed");
}

//init sntp
static void init_sntp(void)
{
    sntp_setservername(0, "pool.ntp.org");
    sntp_init();
}

//sync time
static void sync_time(void *arg)
{
    ssd1306_clearScreen();
    ssd1306_setFixedFont(ssd1306xled_font8x16);
    ssd1306_printFixed(0, 32, "Running sync...", STYLE_NORMAL);
    int retry = 0;
    const int retry_count = 10;
    while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET && ++retry < retry_count)
    {
        vTaskDelay(2000 / portTICK_PERIOD_MS);
    }
    if (retry == retry_count)
    {
        ssd1306_clearScreen();
        ssd1306_printFixed(0, 32, "Sync failed.", STYLE_NORMAL);
        vTaskDelete(NULL);
        return;
    }
    xTaskCreate(show_time, "show_time", 8192, NULL, 5, NULL);
    vTaskDelete(NULL);
}

//show time
static void show_time(void *arg)
{
    time_t now = 0;
    struct tm timeinfo;
    memset((void *)&timeinfo, 0, sizeof(timeinfo));
    char buf[64];
    ssd1306_clearScreen();
    ssd1306_setFixedFont(ssd1306xled_font8x16);
    while (1)
    {
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        time(&now);
        localtime_r(&now, &timeinfo);
        strftime(buf, sizeof(buf), "%a", &timeinfo);
        ssd1306_printFixed(0, 0, buf, STYLE_NORMAL);
        strftime(buf, sizeof(buf), "%H:%M:%S", &timeinfo);
        ssd1306_printFixed(0, 32, buf, STYLE_BOLD);
    }
}

Penjelasan Code

Bagian import library

Disini kita include header files yang diperlukan. Library time.h berisi standard C library time functions, seperti mendapatkan time information, converting berdasarkan time zones, dan formatting sebagai strings.

Header file, esp_sntp.h, menyediakan Fungsionalitas untuk SNTP connection dan communication.

Kita definisikan OLED I2C pins dan declare app_main sebagai extern “C”, agar C++ compiler tidak mempermasalahkan nama app_main.

Bagian main function

Pada app_main, kita inisialisasi hardware dengan memanggil init_hw dan connect ke local wifi. connect_wifi memerlukan parameter untuk sukses dan fail callback.

Bagian init hardware

init_hw hanya melakukan OLED initialization function.

Bagian wifi conn dan failed

wifi_conn_cb dan wifi_failed_cb adalah callback functions untuk mengetahuui hasil dari Wi-Fi connection attempt. Jika connection fails, kita tampilkan error message pada serial console. Jika sukses, kita start SNTP operations.

Pertama kita perlu mengkonfigurasi SNTP API dan membuat task untuk melakukan time synchronize.

Bagian init sntp

Pada init_sntp, kita gunakan fungsi sntp_setservername untuk mengatur SNTP server menggunakan pool.ntp.org dan sntp_init untuk mulai melakukan proses synchronization.

Bagian sync time

sync_time adalah FreeRTOS task function yang dibuat ketika Wi-Fi sudah terhubung. Pertama kita informasikan status pada end user. Kemudian kita coba untuk synchronize time.

Dala while loop, kita poll status. sntp_get_sync_status mengembalikan SNTP_SYNC_
STATUS_COMPLETED jika proses berhasil. Jika synchronization gagal, kita informasikan end user dengan message dan keluar dari task.

Jika synchronization berhasil, kita mulai task baru, yaitu show_time, dimana kita akan menampilkan time pada OLED screen.

Bagian show time

Pertama kita deklarasi variables dan setup OLED display. Disini kita gunakan definitions dari standard C time library, time.h.

Dalam while loop kita akan update OLED display setiap detik.

Untuk update time ke display, pertama kita ambil time dalam seconds dengan memanggil time function.

locatltime_r akan mengkonversi variable now menjadi timeinfo, dimana format yang digunakan lebih dipahami, yaitu dalam year, month, day dan seterusnya.

Kita print 2 bits dari informasi pada display. Pada baris pertama nama hari akan diprint dengan short format (contoh: Mon, Tue dst). Kita gunakan fungsi strftime.

Pada baris kedua, kita print time of day dengan format %H:%M:%S.

Penjelasan strftime dapat lihat di https://man7.org/linux/man-pages/man3/strftime.3.html

Kesimpulan

Sampai disini kita sudah mempelajari penggunaan SNTP.

SNTP adalah solusi paling mudah jika Anda membutuhkan informasi date/time pada ESP32 project.

Setelah synchronization, ESP32 akan melakukan timekeeping dengan menggunakan timers. Timekeeping akan tetap available, bahkan ketika ESP32 dalam mode deep-sleep. Hal ini dilakukan oleh RTC timer.

RTC timer sudah enabled secara default dalam sdkconfig. Anda dapat lihat pada menu Component config/ESP32-specific/Timers used for gettimeofday function.

STA devices
can negotiate their access times to the network with the AP, so they can sleep for a long
period of time before any radio communication happens. This technology substantially
improves the battery life of IoT devices on a network. Espressif recently (in April 2021)
announced a new SoC, ESP32-C6, which supports Wi-Fi 6. Unlike the previous chip
variants with Xtensa CPUs, ESP32-C6 has a single-core, 32-bit RISC-V microcontroller
in it. There is a nice review of it on Hackaday here: https://hackaday.
com/2021/04/11/new-part-day-espressif-esp32-c6/.

Sebelum menutup modul ini, mari kita bahas sekilas tentang standar Wi-Fi baru, Wi-Fi 6
(IEEE 802.11ax).

Tujuan utama Wi-Fi 6 adalah untuk meningkatkan efisiensi dan meningkatkan
throughput jaringan. Teknologi modulasi di balik Wi-Fi 6 adalah Orthogonal
Frequency-Division Multiple Access (OFDMA), yang mirip komunikasi seluler.

Peningkatan penting lainnya adalah Target Wake Time (TWT), untuk mengurangi konsumsi energi. Perangkat STA dapat menegosiasikan waktu akses mereka ke jaringan dengan AP, sehingga mereka dapat tidur lebih lama sampai komunikasi radio terjadi.

Teknologi ini secara substansial meningkatkan masa pakai baterai perangkat IoT di jaringan.

Espressif baru-baru ini (pada April 2021) mengumumkan SoC baru, ESP32-C6, yang mendukung Wi-Fi 6. Berbeda dengan chip sebelumnya varian dengan CPU Xtensa, ESP32-C6 memiliki mikrokontroler RISC-V single-core 32-bit di dalamnya. Silakan lihat ulasannya di https://hackaday.com/2021/04/11/new-part-day-espressif-esp32-c6/

Sharing is caring:

Leave a Comment