ESP32

ESP32 NTP Client-Server: Get Date and Time (Arduino IDE)

기하 2021. 8. 16. 21:55

Arduino IDE와 함께 ESP32를 사용하여

NTP 서버에서 날짜와 시간을 요청하는 방법을 알아봅니다. 

날짜와 시간을 가져오는 것은 데이터 로깅 프로젝트에서

판독값을 타임스탬프하는 데 유용합니다. 

NTP 서버에서 시간을 얻으려면 ESP32 가 인터넷에 연결되어 있어야 하며

추가 하드웨어(예: RTC 시계)가 필요하지 않습니다.

이 튜토리얼을 진행하기 전에 Arduino IDE에 ESP32 애드온이 설치되어 있어야 합니다.

 

권장 사항: ESP8266 NodeMCU NTP 클라이언트-서버로 날짜 및 시간 가져오기

  NTP(네트워크 시간 프로토콜)  

NTP는 Network Time Protocol의 약자로
컴퓨터 시스템 간의 시계 동기화를 위한 네트워킹 프로토콜입니다. 

즉, 네트워크에서 컴퓨터 시계 시간을 동기화하는 데 사용됩니다.

pool.ntp.org 와 같은 NTP 서버가 있어 누구나 클라이언트로 시간을 요청할 수 있습니다. 

이 경우 ESP32는 NTP 서버( pool.ntp.org ) 에서 시간을 요청하는 NTP 클라이언트입니다 .

 

 NTP 서버에서 날짜 및 시간 가져오기 

ESP32로 날짜와 시간을 얻으려면 라이브러리를 설치할 필요가 없습니다. 

당신의 코드에 time.h 라이브러리만 포함하면 됩니다.

다음 코드는 NTP 서버에서 날짜와 시간을 가져와 직렬 모니터에 결과를 인쇄합니다. 

ime.h 라이브러리 에서 제공한 예제를 기반으로 했습니다.

 

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-date-time-ntp-client-server-arduino/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

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

const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 0;
const int   daylightOffset_sec = 3600;

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

  // Connect to Wi-Fi
  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.");
  
  // Init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  printLocalTime();

  //disconnect WiFi as it's no longer needed
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
}

void loop(){
  delay(1000);
  printLocalTime();
}

void printLocalTime(){
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
  Serial.print("Day of week: ");
  Serial.println(&timeinfo, "%A");
  Serial.print("Month: ");
  Serial.println(&timeinfo, "%B");
  Serial.print("Day of Month: ");
  Serial.println(&timeinfo, "%d");
  Serial.print("Year: ");
  Serial.println(&timeinfo, "%Y");
  Serial.print("Hour: ");
  Serial.println(&timeinfo, "%H");
  Serial.print("Hour (12 hour format): ");
  Serial.println(&timeinfo, "%I");
  Serial.print("Minute: ");
  Serial.println(&timeinfo, "%M");
  Serial.print("Second: ");
  Serial.println(&timeinfo, "%S");

  Serial.println("Time variables");
  char timeHour[3];
  strftime(timeHour,3, "%H", &timeinfo);
  Serial.println(timeHour);
  char timeWeekDay[10];
  strftime(timeWeekDay,10, "%A", &timeinfo);
  Serial.println(timeWeekDay);
  Serial.println();
}

 코드 작동 방식 

코드가 어떻게 작동하는지 간단히 살펴보겠습니다. 

먼저 Wi-Fi에 연결하고 시간을 확보할 라이브러리를 포함합니다.

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

SSID 및 비밀번호 설정

ESP32가 인터넷 연결을 설정하고 NTP 서버에서 날짜와 시간을 가져올 수 있도록
다음 변수에 네트워크 자격 증명을 입력합니다.

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

NTP 서버 및 시간 설정

그런 다음 NTP 서버에서 시간을 구성하고 가져오려면 다음 변수를 정의해야 합니다. 

ntpServergmtOffset_sec , daylightOffset_sec.

 

NTP 서버

우리는  pool.ntp.org에게 시간을 요청해야합니다. 

모든사람이 시간을 요청하는 데 사용할 수있는 시간 서버의 클러스터입니다.

const char* ntpServer = "kr.pool.ntp.org";

GMT 오프셋

gmtOffset_sec변수는 시간대와 GMT 사이의 오프셋을 초 단위로 정의합니다. 

우리는 한국에 살고 있으므로 시간 오프셋은 GMT+9입니다. .

//3200초는 1시간, 우리나라는 GMT+9 이므로 3600초x9 = 32400 해 줌
const long  gmtOffset_sec = 32400;

Daylight Offset

daylightOffset_sec변수는 일광 절약 시간의 오프셋을 초 단위로 정의합니다. 

일반적으로 3600초에 해당하는 1시간입니다.

//섬머타임 적용 시 3600 (시간을 1시간 빠르게 함)
//우리나라는 시행 안하므로 0
const int   daylightOffset_sec = 0;

setup()

 

 

setup()함수에서 결과를 인쇄하기 위해 전송 속도 115200에서 직렬 통신을 초기화합니다.

Serial.begin(115200);

다음 줄은 ESP32를 라우터에 연결합니다.

// Connect to Wi-Fi
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.");

이전에 정의한 설정으로 시간을 구성합니다.

configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

printLocalTime()

 

시간을 설정한 후시리얼 모니터에서 시간을 출력하기 위해 printLocalTime() 를 호출합니다.

해당 함수에서 timeinfo 라 불리는 타임 구조체(struct tm)를 만듦니다.

여기에는 시간에 관한 세부 정보들이 포함 됩니다(분, 초, 시간 등)

struct tm timeinfo;

 

tm 구조체는 구성 요소로 분류된 달날짜 및 시간이 포함됩니다.

  • tm_sec       분 후 초
  • tm_min      시간 후 분;
  • tm_hour     자정 이후 시간;
  • tm_mday:     그 달의 일;
  • tm_year     1900년 이후 몇 년;
  • tm_wday    일요일 이후의 일;
  • tm_yday     1월 1일 이후의 일;
  • tm_isdst     일광 절약 시간 플래그;
  • tm 구조 문서 .

날짜와 시간에 대한 모든 세부 정보를 timeinfo변수에 저장합니다. 

if(!getLocalTime(&timeinfo)){
  Serial.println("Failed to obtain time");
  return;
}

그런 다음 직렬 모니터에서 시간에 대한 모든 세부 정보를 인쇄합니다.

Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
Serial.print("Day of week: ");
Serial.println(&timeinfo, "%A");
Serial.print("Month: ");
Serial.println(&timeinfo, "%B");
Serial.print("Day of Month: ");
Serial.println(&timeinfo, "%d");
Serial.print("Year: ");
Serial.println(&timeinfo, "%Y");
Serial.print("Hour: ");
Serial.println(&timeinfo, "%H");
Serial.print("Hour (12 hour format): ");
Serial.println(&timeinfo, "%I");
Serial.print("Minute: ");
Serial.println(&timeinfo, "%M");
Serial.print("Second: ");
Serial.println(&timeinfo, "%S");

 

날짜 및 시간 구조의 멤버에 액세스하려면 다음 지정자를 사용할 수 있습니다.

%A 전체 요일 이름
%B 전체 월 이름
%d 달의 날
%Y 년도
%H 24시간 형식의 시간
%l 12시간 형식의 시간
%M
%S

다른 형식으로 정보를 가져오는 데 사용할 수 있는 다른 지정자가 있습니다.

예: 축약된 월 이름(%b), 축약된 요일 이름(%a),

첫 번째 일요일이 첫 번째 주의 첫 번째 날인 주 번호(%U) 및 기타( 더 읽기 ).

 

또한 시간에 대한 정보를 변수에 저장하려는 경우 예를 보여줍니다. 

예를 들어 시간을 timeHour 변수에 저장하려는 경우, 길이가 3자인 char 변수를 만듭니다

(시간 문자와 종료 문자를 저장해야 함). 

그런 다음 에 있는 time변수에 있는 시간에 대한 정보를 strftime() 함수를 사용하여

timeHour변수에 복사합니다

Serial.println("Time variables");
char timeHour[3];
strftime(timeHour,3, "%H", &timeinfo);
Serial.println(timeHour);

 

다른 변수를 얻으려면 유사한 프로세스를 사용하십시오. 

예를 들어, 요일의 경우 한 주의 가장 긴 요일이 9자(토요일)를 포함하기 때문에

길이가 10자인 char 변수를 생성해야 합니다.

char timeWeekDay[10];
strftime(timeWeekDay,10, "%A", &timeinfo);
Serial.println(timeWeekDay);
Serial.println();

데모

네트워크 자격 증명을 삽입하고 변수를 수정하여 시간대 및 일광 절약 시간제를 변경한 후

예제를 테스트할 수 있습니다.

ESP32 보드에 코드를 업로드하십시오. 올바른 보드와 COM 포트를 선택했는지 확인하십시오. 

코드를 업로드한 후 ESP32 "Enable" 버튼을 누르면 다음 그림과 같이 1초마다 날짜와 시간이 표시됩니다.

 

마무리

이 튜토리얼에서는 Arduino IDE로 프로그래밍된 ESP32를 사용하여

NTP 서버에서 날짜와 시간을 가져오는 방법을 배웠습니다. 

이제 여기에서 배운 내용을 사용하여 자신의 프로젝트에서

센서 판독값을 타임스탬프로 지정할 수 있습니다.

 

이 방법은 ESP32가 인터넷에 연결된 경우에만 작동합니다. 

프로젝트에서 인터넷에 액세스할 수 없는 경우 다른 방법을 사용해야 합니다. 

DS1307과 같은 RTC 모듈을 사용할 수 있습니다 .

ESP32에 대해 자세히 알아보려면 리소스를 확인하세요.

 

[출처번역인용] https://randomnerdtutorials.com/esp32-date-time-ntp-client-server-arduino/

 

ESP32 NTP Client-Server: Get Date and Time (Arduino IDE) | Random Nerd Tutorials

Request date and time from an NTP Server using the ESP32 with Arduino IDE. With an Internet connection, you can make data logging projects with timestamps.

randomnerdtutorials.com