3257 views|2 replies

247

Posts

4

Resources
The OP
 

[2022 Digi-Key Innovation Design Competition] Internet clock based on NTP service on ESP32 [Copy link]

 

Many times, when we use ESP32 without the assistance of RTC clock chip, we need an external clock source to provide accurate time for synchronization.

After some understanding, you can use the NTP server to synchronize time.

The actual code that was finally completed is as follows:

/* Internet clock based on NTP server

*/

#include <Arduino.h>

#include <stdlib.h>

// Time library

#include <TimeLib.h>

// WiFi library

#include <WiFi.h>

#include <WiFiMulti.h>

#include <WiFiUdp.h>

#include <Wire.h>

//OLED library

#include <Adafruit_SSD1306.h>

#include <U8g2_for_Adafruit_GFX.h>

//OLED definition

//Screen size definition

#define SCREEN_WIDTH 128 // width

#define SCREEN_HEIGHT 64 // Height

//OLED I2C definition

#define OLED_RESET -1 // RESET

#define SCREEN_ADDRESS 0x3C // I2C address

// Adafruit_SSD1306 display object

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// U8G2_FOR_ADAFRUIT_GFX display object

U8G2_FOR_ADAFRUIT_GFX u8g2_for_adafruit_gfx;

//WiFi definition

#define WIFI_SSID "OpenBSD"

#define WIFI_PASS "13581882013"

WiFiMulti WiFiMulti;

//NTP definition

static const char ntpServerName[] = "ntp.aliyun.com";

const int timeZone = 8; // time zone

//Communication data packet definition

const int NTP_PACKET_SIZE = 48;

byte packetBuffer[NTP_PACKET_SIZE];

// UDP definition

WiFiUDP Udp;

unsigned int localPort = 8888;

// NTP method and object definition

time_t getNtpTime();

// Time display status

time_t prevDisplay = 0;

/**

* showtime display time

**/

void showtime() {

int Hour = hour();

int Min = minute();

int Sec = second();

int HourHigh, HourLow, MinHigh, MinLow, SecHigh, SecLow;

char buff[50];

sprintf(buff, "%02d:%02d:%02d", Hour, Min, Sec);

u8g2_for_adafruit_gfx.setFont(u8g2_font_fur20_tn); // Chinese font

u8g2_for_adafruit_gfx.setCursor(8, 52); // start writing at this position

u8g2_for_adafruit_gfx.print(buff);

}

/**

* getNtpTime NTP time synchronization

**/

time_t getNtpTime() {

IPAddress ntpServerIP; //NTP server address

while (Udp.parsePacket() > 0)

; // Discard any previously received packets

// Initiate NTP request

Serial.println("Transmit NTP Request");

WiFi.hostByName(ntpServerName, ntpServerIP); // Get IP

Serial.print(ntpServerName);

Serial.print(": ");

Serial.println(ntpServerIP);

sendNTPpacket(ntpServerIP); // Send data packet

uint32_t beginWait = millis();

while (millis() - beginWait < 1500) {

int size = Udp.parsePacket();

if (size >= NTP_PACKET_SIZE) {

Serial.println("Receive NTP Response");

Udp.read(packetBuffer, NTP_PACKET_SIZE); // Read data packet

unsigned long secsSince1900;

// Convert data

secsSince1900 = (unsigned long)packetBuffer[40] << 24;

secsSince1900 |= (unsigned long)packetBuffer[41] << 16;

secsSince1900 |= (unsigned long)packetBuffer[42] << 8;

secsSince1900 |= (unsigned long)packetBuffer[43];

// Return data

return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;

}

}

Serial.println("No NTP Response :-(");

return 0;

}

/**

* sendNTPpacket sends NTP data packets

**/

void sendNTPpacket(IPAddress &address) {

//Clear buff

memset(packetBuffer, 0, NTP_PACKET_SIZE);

// Generate request data

packetBuffer[0] = 0b11100011; // LI, Version, Mode

packetBuffer[1] = 0; // Stratum, or type of clock

packetBuffer[2] = 6; // Polling Interval

packetBuffer[3] = 0xEC; // Peer Clock Precision

// 8 bytes of zero for Root Delay & Root Dispersion

packetBuffer[12] = 49;

packetBuffer[13] = 0x4E;

packetBuffer[14] = 49;

packetBuffer[15] = 52;

// Send NTP data packet

Udp.beginPacket(address, 123);

Udp.write(packetBuffer, NTP_PACKET_SIZE);

Udp.endPacket();

}

void setup() {

//Serial port initialization

Serial.begin(115200);

// Communication initialization

Wire.begin();

// OLED initialization

Serial.println(F("SSD1306 init:"));

if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {

Serial.println(F("SSD1306 allocation failed"));

for (;;)

; // loop

} else {

Serial.println(F("SSD1306 allocation ok"));

}

// Display the default Adafruit splash screen

display.display();

delay(1000);

// Associate u8g8 to Adafruit GFX

u8g2_for_adafruit_gfx.begin(display);

//WiFi connection processing

WiFiMulti.addAP(WIFI_SSID, WIFI_PASS);

while (WiFiMulti.run() != WL_CONNECTED) {

Serial.print(".");

delay(500);

}


// Open UDP

Serial.println("Starting UDP");

Udp.begin(localPort);

Serial.print("Local port: ");

Serial.println(localPort);

Serial.println("waiting for sync");

// Set NTP time synchronization

setSyncProvider(getNtpTime);

setSyncInterval(300);

// Delay

delay(500);

}

void loop() {

// Display time

if (timeStatus() != timeNotSet) { // Check and update the latest time

if (now() != prevDisplay) {

prevDisplay = now();

// Clear the display cache

display.clearDisplay();

// Picture frame

display.drawRoundRect(0, 0, display.width() - 1, 16, 1, SSD1306_WHITE); // Status bar

display.drawRoundRect(0, 16, display.width() - 1, display.height() - 16, 1, SSD1306_WHITE); // Content area

u8g2_for_adafruit_gfx.setFontDirection(0); // Display direction: from left to right (default)

u8g2_for_adafruit_gfx.setForegroundColor(WHITE); // Apply Adafruit GFX color

u8g2_for_adafruit_gfx.setFont(u8g2_font_unifont_t_chinese2); // Chinese font

u8g2_for_adafruit_gfx.setCursor(25, 12); // Display coordinates

u8g2_for_adafruit_gfx.print("Net Clock");

showtime(); // Display time

// show

display.display();

}

}

// Delay

delay(50);

}

The above code is developed in Arduino;

In the above code:

  • The Time module is used to set and read time.
  • Used WiFi module for networking
  • Adafruit_SSD1306 module is used to control OLED (SSD1306)
  • The U8g2_for_Adafruit_GFX module is used to couple the U8g2 and Adafruit_SSD1306

In the setup() initialization phase:

  • Initialize the OLED display
  • Initialize WiFi connection
  • Initialize NTP time synchronization

In the loop() main loop phase:

  • Check the current time
  • If the time is different from the previously remembered time, display the time on the screen and base it on the current time

In addition, several main functions:

  • showtime() function, used to display time
  • getNtpTime() function, used for NTP time synchronization

  • sendNTPpacket() function is used to send NTP data packets

In the actual test verification, an ESP32-E development board and an SSD 1306 128x64 OLED were used. The specific results are as follows:

The video effect is as follows:

359_1667375440

This post is from DigiKey Technology Zone

Latest reply

detailed   Details Published on 2022-11-2 23:23
 
 

156

Posts

1

Resources
2
 

Leader Qiao is niubility

This post is from DigiKey Technology Zone
 
 
 

85

Posts

0

Resources
3
 

detailed

This post is from DigiKey Technology Zone
 
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews

Room 1530, Zhongguancun MOOC Times Building, Block B, 18 Zhongguancun Street, Haidian District, Beijing 100190, China Tel:(010)82350740 Postcode:100190

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list