RTC 또는 Real Time Clock은 전자 및 임베디드 장치에서 시간을 추적하기 위해 가장 일반적으로 사용되는 모듈입니다. 그러나 RTC의 문제는 컴퓨터의 마이크로 칩이 그다지 정확하지 않고 로컬 장치의 시간 만 제공 할 수 있다는 것입니다. 반면에 인터넷을 사용하여 NTP 서버에서 시간을 가져 오는 것이 더 정확하고 전 세계 모든 지리적 영역의 시간을 제공 할 수 있기 때문에 시간을 얻는 데 더 나은 솔루션입니다. NTP 서버를 사용하여 전 세계 모든 위치의 시간을 얻으려면 Wi-Fi 모듈과 인터넷 액세스 만 있으면됩니다. 이 튜토리얼에서는 ESP8266 NodeMCU를 사용하여 NTP 서버에서 현재 시간과 날짜를 가져와 OLED 디스플레이에 표시 합니다.
NTP (Network Time Protocol)
NTP는 컴퓨터 네트워크간에 시계를 동기화하기위한 가장 오래된 네트워킹 IP (인터넷 프로토콜) 중 하나입니다. 이 프로토콜은 1981 년 델라웨어 대학의 David L. Mills에 의해 설계되었습니다.이 프로토콜은 몇 밀리 초 내에 많은 네트워크를 UTC (Coordinated Universal Time) 에 동기화하는 데 사용할 수 있습니다. UTC는 세계가 시계와 시간을 규제하는 기본 시간 표준입니다. UTC는 변경되지 않으며 지리적 위치에 따라 다릅니다. NTP는 UTC를 시간 참조로 사용하며 인터넷을 통해 정확하고 동기화 된 시간을 제공합니다.
NTP는 계층 적 클라이언트-서버 모델에서 작동합니다. 최상위 모델에는 위성으로부터 시간을 수신하는 원자 시계, 전파, GPS, GSM과 같은 "stratum0" 이라는 참조 시계가 있습니다. stratum0에서 시간을받는 서버를 "stratum1" 이라고하고 stratum1 에서 시간을받는 서버를 "stratum2" 라고 합니다. 이것은 계속되고 시간의 정확성은 각 단계 후에 감소합니다. NTP는 동기화 할 몇 가지 사용 가능한 시간 원본 중에서 가장 좋은 것을 자동으로 선택하여 내결함성 프로토콜을 만듭니다.
이 프로젝트에서는 ESP8266 NodeMCU를 사용하여 NTP 서버에서 시간을 가져와 OLED 디스플레이에 표시 합니다. 이 같은 종류의 인터넷 시계는 이전 튜토리얼에서 ESP32를 사용하여 구축되었습니다.
ESP8266은 정확한 시간을 얻기 위해 인터넷을 사용하여 NTP 서버에 액세스 할 수 있습니다. 여기서 NTP는 클라이언트-서버 모드에서 작동하고 ESP8266은 클라이언트 장치로 작동하며 UDP (사용자 데이터 그램 프로토콜)를 사용하여 NTP 서버 와 연결됩니다. 클라이언트는 요청 패킷을 NTP 서버로 전송하고 그 대가로 NTP는 정확도, 시간대, UNIX 타임 스탬프 등과 같은 정보로 구성된 타임 스탬프 패킷을 보냅니다. 그런 다음 클라이언트는 요구 사항에 따라 응용 프로그램에서 추가로 사용할 수있는 날짜 및 시간 세부 정보를 분리합니다.
필요한 구성 요소
- 흑백 7 핀 SSD1306 0.96 인치 OLED 디스플레이
- ESP8266 NodeMCU
- 마이크로 USB 케이블
- 브레드 보드
- 수-수 점퍼 와이어
회로도 및 연결
이 7 핀 OLED 디스플레이는 SPI 프로토콜을 사용하여 ESP8266 모듈과 통신합니다. 아래는 OLED SPI 핀을 NodeMCU와 연결하여 인터넷 시간을 표시하는 회로도 및 연결 테이블 입니다.
아니. |
OLED 디스플레이 |
NodeMCU |
1 |
GND |
GND |
2 |
VDD |
3.3V |
삼 |
SCK |
D5 |
4 |
MOSI (SPI) 또는 SDA (I2C) |
D7 |
5 |
초기화 |
D3 |
6 |
DC |
D2 |
7 |
CS |
D8 |
이 흑백 7 핀 OLED 디스플레이 및 ESP8266 NodeMCU와의 인터페이스에 대해 자세히 알아 보려면 링크를 따르십시오.
코드 설명
먼저 ESP8266에 NTP 라이브러리를 다운로드하여 설치해야합니다. NTP 클라이언트에 사용할 수있는 많은 라이브러리가 있습니다. Arduino IDE에서 설치할 수 있습니다. 이 튜토리얼에서는 사용하기 쉽고 NTP 서버에서 날짜와 시간을 가져 오는 기능이 있기 때문에 Taranais의 NTPClient 라이브러리를 설치했습니다. ESP8266 NodeMCU는 Arduino IDE를 사용하여 쉽게 프로그래밍 할 수 있습니다.
NTP 라이브러리를 설치하려면 먼저 위 링크를 사용하여 라이브러리를 다운로드 한 다음 Arduino IDE를 사용하여 설치하십시오. 설치하려면 Sketch> Include Library> Add.ZIP Library 로 이동 한 다음 zip 폴더를 다운로드 한 위치로 이동하여 Zip 폴더를 열고 Arduino IDE를 다시 시작합니다.
NTPClient 라이브러리는 예제와 함께 제공됩니다. Arduino IDE 및 Goto 예제> NTPClient> 고급을 엽니 다. 이 스케치에 제공된 코드는 직렬 모니터에 NTP 서버의 시간을 표시합니다. 이 스케치를 사용하여 OLED 디스플레이에 현재 시간과 날짜를 표시합니다.
이 튜토리얼의 끝 부분에서 완전한 코드를 사용할 수 있습니다. 여기서는 코드의 몇 가지 중요한 부분을 설명했습니다.
ESP8266WiFi 라이브러리 는 ESP8266 특정 Wi-Fi 루틴을 제공하여 네트워크에 연결합니다. WiFiUDP.h 는 UDP 패키지의 송수신을 처리합니다. SPI 프로토콜을 사용하여 OLED를 NodeMCU와 인터페이스하므로 "SPI.h"라이브러리를 가져옵니다. OLED 디스플레이에는“Adafruit_GFX.h”와“Adafruit_SSD1306.h”가 사용됩니다.
#포함
우리의 OLED 크기는 128x64이므로 화면 너비와 높이를 각각 128과 64로 설정합니다. 따라서 SPI 통신을 위해 NodeMCU에 연결된 OLED 핀에 대한 변수를 정의하십시오.
#define SCREEN_WIDTH 128 // OLED 디스플레이 너비, 픽셀 단위 #define SCREEN_HEIGHT 64 // OLED 디스플레이 높이, 픽셀 단위 // 소프트웨어 SPI를 사용하여 연결된 SSD1306 디스플레이 선언 (기본 케이스): #define OLED_MOSI D7 #define OLED_CLK D5 #define OLED_DC D2 # OLED_CS 정의 D8 # OLED_RESET D3 정의
Adafruit_SSD1306 디스플레이 (SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
아래 코드 줄에서 "your_ssid"및 "your_password"를 Wi-Fi SSID 및 암호로 바꿉니다.
const char * ssid = "your_ssid"; const char * password = "your_password";
WiFi.begin 기능에 SSID와 비밀번호를 부여하여 WI-Fi 연결을 설정합니다. ESP8266의 연결은 NodeMCU에 연결되기까지 약간의 시간이 걸리므로 연결될 때까지 기다려야합니다.
WiFi.begin (ssid, password); while (WiFi.status ()! = WL_CONNECTED) { 지연 (500); Serial.print ("."); }
날짜 및 시간을 요청하려면 NTP 서버 주소로 시간 클라이언트를 초기화합니다. 정확도를 높이려면 지리적 영역에 가까운 NTP 서버의 주소를 선택하십시오. 여기에서는 전 세계의 서버를 제공 하는 " pool.ntp.org "를 사용합니다. 아시아에서 서버를 선택하려면“ asia.pool.ntp.org ”를 사용할 수 있습니다. timeClient 는 또한 시간대의 밀리 초 단위로 UTC 시간 오프셋을 취합니다. 예를 들어 인도의 UTC 오프셋은 +5: 30이므로이 오프셋은 5 * 60 * 60 + 30 * 60 = 19800과 같은 밀리 초 단위로 변환됩니다.
지역 |
UTC 시간 오프셋 (시간 및 분) |
UTC 시간 오프셋 (초) |
인도 |
+5: 30 |
19800 |
런던 |
0:00 |
0 |
뉴욕 |
-5: 00 |
-18000 |
WiFiUDP ntpUDP; NTPClient timeClient (ntpUDP, "pool.ntp.org", 19800,60000);
SSD1306_SWITCHCAPVCC 는 디스플레이를 초기화하기 위해 내부적으로 3.3V를 생성하도록 제공됩니다. OLED가 시작되면 " WELCOME TO CIRCUIT DIGEST "가 텍스트 크기 2와 파란색으로 3 초 동안 표시됩니다.
if (! display.begin (SSD1306_SWITCHCAPVCC)) { Serial.println (F ("SSD1306 할당 실패")); 에 대한(;;); // 계속하지 말고 영원히 반복 } display.clearDisplay (); display.setTextSize (2); // 2X 스케일 텍스트 그리기 display.setTextColor (BLUE); display.setCursor (5, 2); display.println ("WELCOME TO"); display.println ("CIRCUIT"); display.println ("DIGEST"); display.display (); 지연 (3000);
NTP 클라이언트는 begin () 함수를 사용하여 초기화 되어 NTP 서버에서 날짜와 시간을 설정합니다.
timeClient.begin ();
Update () 함수는 NTP 서버에 요청할 때마다 날짜와 시간을 수신하는 데 사용됩니다.
timeClient.update ();
115200의 Baud rate는 시리얼 모니터에 시간을 출력하도록 설정되어 있습니다.
Serial.begin (115200); Serial.println (timeClient.getFormattedTime ());
getHours (), getMinutes (), getSeconds (), getDay 는 라이브러리 함수이며 NTP 서버에서 현재시, 분, 초 및 요일을 제공합니다. 아래 코드는 오전과 오후를 구분하는 데 사용됩니다. getHours ()를 사용하여 얻은 시간 이 12보다 크면 해당 시간을 PM으로 설정하고 AM으로 설정합니다.
int hh = timeClient.getHours (); int mm = timeClient.getMinutes (); int ss = timeClient.getSeconds (); int day = timeClient.getDay (); if (hh> 12) { hh = hh-12; display.print (hh); display.print (":"); display.print (mm); display.print (":"); display.print (ss); display.println ("PM"); } else { display.print (hh); display.print (":"); display.print (mm); display.print (":"); display.print (ss); display.println ("AM"); } int day = timeClient.getDay (); display.println (" '"+ arr_days + "'");
getFormattedDate () 는 NTP 서버 에서 "yyyy-mm-dd" 형식으로 날짜를 가져 오는 데 사용됩니다. 이 함수는 "yyyy-mm-dd T hh: mm: ss 형식으로 날짜와 시간을 제공 합니다. 하지만 날짜 만 필요하므로 date_time 형식으로 저장된이 문자열을 substring () 함수에 의해 수행되는 "T"까지 분할 한 다음 "date" 변수에 날짜를 저장해야 합니다.
date_time = timeClient.getFormattedDate (); int index_date = date_time.indexOf ("T"); 문자열 날짜 = date_time.substring (0, index_date); Serial.println (날짜); display.println (날짜); display.display ();
이것이 OLED 인터넷 시간 시계 가 마침내 보이는 모습입니다.