Arduino/ESP8266 ESP32

ESP32에서 NTP(Network Time Protocol) 로부터 시간 가져오기

황기하 2022. 12. 10.

https://arsviator.blogspot.com/2018/11/esp32-ntpnetwork-time-protocol.html

 

ESP32에서 NTP(Network Time Protocol) 서버로부터 시간 가져오기

인터넷에서 정확한 시간을 알기 위해 사용하는 프로토콜로 NTP(Network Time Protocol)이 있다. 곳곳에 운영중인 NTP서버에 접속해 정확한 현재 날짜와 시간을 가져 올 수 있다. ESP32에서도 NTP를 사용할

arsviator.blogspot.com

 

인터넷에서 정확한 시간을 알기 위해 사용하는

프로토콜로 NTP(Network Time Protocol)이 있다.

곳곳에 운영중인 NTP서버에 접속해 정확한 현재 날짜와 시간을 가져 올 수 있다

 


ESP32에서도 NTP를 사용할 수 있게 이미 NTP client 라이브러리가 공개되어 있다.

Download NTP Client Library

위의 링크를 클릭하면 라이브러리를 다운받아 설치해주면 된다.

코드 구조는 다음과 같다.

1. WiFi.h, WiFiUdp.h, NTPClient.h 를 include 해 줘야 한다.

 

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

2. 인터넷 연결을 위해 공유기 설정을 해 준다.

      const char* ssid  = "XXXXX";
      const char* password = "YYYYY"; 
     위에서 XXXXX 대신 사용할 공유기의 이름(SSID)로, YYYYY 대신 공유기의 암호로 바꿔줘야 한다.

3. 이제 NTP client를 만들어 준다.

     WiFiUdp ntpUDP;
     NTPClient timeClient(ntpUdp);

4. 공유기에 접속한 후 NTP client를 시작한다.
    ....
    timeClient.begin();

5. 자신의 timezone에 맞게 시간을 조정하기 위해

    setTimeOffset() 메소드를 사용할 수 있는데
   이때 offset은 초 단위로 지정해 줘야 한다.
   즉 1시간은 3600초이므로
   한국의 경우 GMT+9 이니까 3600*9 = 32400이 된다.


     timeClient.setTimeOffset(32400);

6. NTP 서버에 요청해 시간을 가져온다.
     while (!timeClient.update()) {
      timeClient.forceUpdate();
      }

7. NTP 서버에게서 읽어온 값을 사람이 볼 수 있는 형태로 변환해준다.

formattedDate = timeClient.getFormattedDate();
getFormattedDate()가 리턴한 값은 다음과 같은 포맷이다.

2018-11-09T07:34:21z

T 앞쪽이 날짜가 되고 T에서 z까지가 시간이므로 각각을 기준으로 원하는 내용을 추출해서 출력해주면 된다.
실행 가능한 전체 코드는 다음과 같다.

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

const char* ssid     = "XXXXX";  // XXXXX 를 접속할 공유기 SSID로 변경
const char* password = "YYYYY"   // YYYYY 를 접속할 공유기 암호로 변경

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);

// Variables to save date and time
String formattedDate;
String dayStamp;
String timeStamp;

void setup() {
  Serial.begin(115200);
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  timeClient.begin();    // NTP 클라이언트 초기화
  // 자신의 timezone에 맞게 초 단위로 time offset을 설정해준다. 예를 들어
  // GMT +1 = 3600
  // GMT +8 = 28800
  // GMT -1 = -3600
  // GMT 0 = 0
  timeClient.setTimeOffset(32400);  // 한국은 GMT+9이므로 9*3600=32400
}
void loop() {
  while(!timeClient.update()) {
    timeClient.forceUpdate();
  }
  // formattedDate 은 다음과 같은 형태임
  // 2018-11-12T16:00:13Z
  formattedDate = timeClient.getFormattedDate();
  Serial.println(formattedDate);

  // 날짜 추출
  int splitT = formattedDate.indexOf("T");
  dayStamp = formattedDate.substring(0, splitT);
  Serial.print("DATE: ");
  Serial.println(dayStamp);
  // 시간 추출
  timeStamp = formattedDate.substring(splitT+1, formattedDate.length()-1);
  Serial.print("HOUR: ");
  Serial.println(timeStamp);
  delay(1000);
}


코드의 실행 결과이다.

Connecting to XXXXX
.......
WiFi connected.
IP address:
172.20.10.13
2018-11-09T08:53:26Z
DATE: 2018-11-09
HOUR: 08:53:26
2018-11-09T08:53:27Z
DATE: 2018-11-09
HOUR: 08:53:27
2018-11-09T08:53:28Z
DATE: 2018-11-09
HOUR: 08:53:28


댓글