Arduino ESP8266 获取网络时间方法

[复制链接]
 楼主| gaoyang9992006 发表于 2024-7-4 19:05 | 显示全部楼层 |阅读模式

  1. #include <ESP8266WiFiMulti.h>
  2. #include <WiFiUdp.h>
  3. #include"rtctime.h"

  4. #include <time.h>      // time() ctime()


  5. ESP8266WiFiMulti WiFiMulti;

  6. unsigned int localPort = 2390;  // local port to listen for UDP packets
  7. IPAddress timeServerIP;  // time.nist.gov NTP server address
  8. const char* ntpServerName = "time.nist.gov";
  9. const int NTP_PACKET_SIZE = 48;  // NTP time stamp is in the first 48 bytes of the message
  10. byte packetBuffer[NTP_PACKET_SIZE];  // buffer to hold incoming and outgoing packets
  11. // A UDP instance to let us send and receive packets over UDP
  12. WiFiUDP udp;
  13. struct rtc_tm rtcdate;

  14. // NTP 服务器地址
  15. const char* ntpServer = "pool.ntp.org";

  16. // 时区和夏令时设置(例如:GMT+8)
  17. const long gmtOffset_sec = 8 * 3600;
  18. const int daylightOffset_sec = 0;


  19. void setup() {
  20.   // put your setup code here, to run once:
  21.   Serial.begin(115200);
  22.   delay(100);
  23.   WiFi.mode(WIFI_STA);
  24.   WiFiMulti.addAP("XGY-NJY", "njy123456");

  25.   Serial.println('\n');
  26.   while(WiFiMulti.run() != WL_CONNECTED)
  27.   {
  28.     Serial.print("-.-");
  29.     delay(250);
  30.   }
  31.   Serial.println('\n');
  32.   
  33.   Serial.print("Connected to :");
  34.   Serial.println(WiFi.SSID());
  35.   Serial.print("IP=");
  36.   Serial.println(WiFi.localIP());

  37.   Serial.println("Starting UDP");
  38.   udp.begin(localPort);
  39.   Serial.print("Local port: ");
  40.   Serial.println(udp.localPort());

  41.   // 配置时间
  42.   configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  43.   // 等待并获取时间
  44.   struct tm timeinfo;
  45.   if (!getLocalTime(&timeinfo)) {
  46.     Serial.println("Failed to obtain time");
  47.     return;
  48.   }
  49. char timeStringBuff[50]; // 缓冲区大小根据需要调整
  50.    sprintf(timeStringBuff, "Current time: %04d-%02d-%02d %02d:%02d:%02d",
  51.           timeinfo.tm_year + 1900,
  52.           timeinfo.tm_mon + 1,
  53.           timeinfo.tm_mday,
  54.           timeinfo.tm_hour,
  55.           timeinfo.tm_min,
  56.           timeinfo.tm_sec);
  57.   // 输出当前时间
  58.   Serial.println(timeStringBuff);
  59.   
  60. }

  61. void loop() {
  62.   // put your main code here, to run repeatedly:
  63.   // get a random server from the pool
  64.   WiFi.hostByName(ntpServerName, timeServerIP);
  65.   sendNTPpacket(timeServerIP);  // send an NTP packet to a time server
  66.   // wait to see if a reply is available
  67.   delay(1000);

  68.   int cb = udp.parsePacket();
  69.   if (!cb)
  70.   {
  71.     Serial.println("no packet yet");
  72.   } else
  73.   {
  74.     Serial.print("packet received, length=");
  75.     Serial.println(cb);
  76.     // We've received a packet, read the data from it
  77.     udp.read(packetBuffer, NTP_PACKET_SIZE);  // read the packet into the buffer
  78.     // the timestamp starts at byte 40 of the received packet and is four bytes,
  79.     //  or two words, long. First, esxtract the two words:

  80.     unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
  81.     unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
  82.     // combine the four bytes (two words) into a long integer
  83.     // this is NTP time (seconds since Jan 1 1900):
  84.     unsigned long secsSince1900 = highWord << 16 | lowWord;
  85.     Serial.print("Seconds since Jan 1 1900 = ");
  86.     Serial.println(secsSince1900);

  87.     // now convert NTP time into everyday time:
  88.     Serial.print("Unix time = ");
  89.     // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
  90.     const unsigned long seventyYears = 2208988800UL;
  91.     // subtract seventy years:
  92.     unsigned long epoch = secsSince1900 - seventyYears;
  93.     // print Unix time:
  94.     Serial.println(epoch);

  95.     rtctime_gmtime(epoch,&rtcdate);
  96.     Serial.println("The Beijing time is :");
  97.   //下面变量要多定义一个,这样最后一个空闲作为结束标志
  98.     char date_temp[11];
  99.     char time_temp[9];
  100.     sprintf(date_temp,"%04d-%02d-%02d",1900+rtcdate.tm_year,1+rtcdate.tm_mon,rtcdate.tm_mday);
  101.     sprintf(time_temp,"%02d-%02d-%02d",8+rtcdate.tm_hour,rtcdate.tm_min,rtcdate.tm_sec);
  102.     Serial.println(date_temp);
  103.     Serial.println(time_temp);

  104. /*
  105.     // print the hour, minute and second:
  106.     Serial.print("The UTC time is ");       // UTC is the time at Greenwich Meridian (GMT)
  107.     Serial.print((epoch % 86400L) / 3600);  // print the hour (86400 equals secs per day)
  108.     Serial.print(':');
  109.     if (((epoch % 3600) / 60) < 10)
  110.     {
  111.       // In the first 10 minutes of each hour, we'll want a leading '0'
  112.       Serial.print('0');
  113.     }
  114.     Serial.print((epoch % 3600) / 60);  // print the minute (3600 equals secs per minute)
  115.     Serial.print(':');
  116.     if ((epoch % 60) < 10)
  117.     {
  118.       // In the first 10 seconds of each minute, we'll want a leading '0'
  119.       Serial.print('0');
  120.     }
  121.     Serial.println(epoch % 60);  // print the second
  122.     */
  123.   }
  124.   // wait ten seconds before asking for the time again
  125.   delay(10000);
  126. }


  127. // send an NTP request to the time server at the given address
  128. void sendNTPpacket(IPAddress& address) {
  129.   Serial.println("sending NTP packet...");
  130.   // set all bytes in the buffer to 0
  131.   memset(packetBuffer, 0, NTP_PACKET_SIZE);
  132.   // Initialize values needed to form NTP request
  133.   // (see URL above for details on the packets)
  134.   packetBuffer[0] = 0b11100011;  // LI, Version, Mode
  135.   packetBuffer[1] = 0;           // Stratum, or type of clock
  136.   packetBuffer[2] = 6;           // Polling Interval
  137.   packetBuffer[3] = 0xEC;        // Peer Clock Precision
  138.   // 8 bytes of zero for Root Delay & Root Dispersion
  139.   packetBuffer[12] = 49;
  140.   packetBuffer[13] = 0x4E;
  141.   packetBuffer[14] = 49;
  142.   packetBuffer[15] = 52;

  143.   // all NTP fields have been given values, now
  144.   // you can send a packet requesting a timestamp:
  145.   udp.beginPacket(address, 123);  // NTP requests are to port 123
  146.   udp.write(packetBuffer, NTP_PACKET_SIZE);
  147.   udp.endPacket();
  148. }


 楼主| gaoyang9992006 发表于 2024-7-4 20:19 | 显示全部楼层

  1. /* seconds per day */
  2. #define SPD 24*60*60
  3. struct rtc_tm{
  4.   int tm_sec;   /* Seconds.     [0-60] (1 leap second) */
  5.   int tm_min;   /* Minutes.     [0-59] */
  6.   int tm_hour;  /* Hours.       [0-23] */
  7.   int tm_mday;  /* Day.         [1-31] */
  8.   int tm_mon;   /* Month.       [0-11] */
  9.   int tm_year;  /* Year - 1900. */
  10.   int tm_wday;  /* Day of week. [0-6] */
  11.   int tm_yday;  /* Days in year.[0-365]        */
  12. };
  13. /* days per month -- nonleap! */
  14. static const short __spm[13] =
  15.   { 0,
  16.     (31),
  17.     (31+28),
  18.     (31+28+31),
  19.     (31+28+31+30),
  20.     (31+28+31+30+31),
  21.     (31+28+31+30+31+30),
  22.     (31+28+31+30+31+30+31),
  23.     (31+28+31+30+31+30+31+31),
  24.     (31+28+31+30+31+30+31+31+30),
  25.     (31+28+31+30+31+30+31+31+30+31),
  26.     (31+28+31+30+31+30+31+31+30+31+30),
  27.     (31+28+31+30+31+30+31+31+30+31+30+31),
  28.   };

  29. static int __isleap (int year) {
  30.   /* every fourth year is a leap year except for century years that are
  31.    * not divisible by 400. */
  32.   /*  return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */
  33.   return (!(year % 4) && ((year % 100) || !(year % 400)));
  34. }

  35. void rtctime_gmtime (const int32 stamp, struct rtc_tm *r)
  36. {
  37.   int32_t i;
  38.   int32_t work = stamp % (SPD);
  39.   r->tm_sec = work % 60; work /= 60;
  40.   r->tm_min = work % 60; r->tm_hour = work / 60;
  41.   work = stamp / (SPD);
  42.   r->tm_wday = (4 + work) % 7;
  43.   for (i = 1970; ; ++i) {
  44.     int32_t k = __isleap (i) ? 366 : 365;
  45.     if (work >= k) {
  46.       work -= k;
  47.     } else {
  48.       break;
  49.     }
  50.   }
  51.   r->tm_year = i - 1900;
  52.   r->tm_yday = work;

  53.   r->tm_mday = 1;
  54.   if (__isleap (i) && (work > 58)) {
  55.     if (work == 59) r->tm_mday = 2; /* 29.2. */
  56.     work -= 1;
  57.   }

  58.   for (i = 11; i && (__spm[i] > work); --i) ;
  59.   r->tm_mon = i;
  60.   r->tm_mday += work - __spm[i];
  61. }
个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

2045

主题

16350

帖子

222

粉丝
快速回复 在线客服 返回列表 返回顶部