实用经验帖 ESP8266 NODEMCU 获取互联网上面时间服务器的标准...-Arduino中文社区 - Powered by Discuz! Archiver

ws9528 发表于 2019-8-21 13:46

实用经验帖 ESP8266 NODEMCU 获取互联网上面时间服务器的标准...

实用经验帖 ESP8266 NODEMCU 获取互联网上面时间服务器的标准时间

能少用原件尽量少用,所以就不用时间模块,直接用NODEMCU获取标准时间。

硬件:NODEMCU 一块
软件:arduino IDE (配好8266开发板)
所需库:NTPclient   直接在库管理里面用这个关键字,第一个就是。


发代码,不一同发库文件的都是耍流氓

时间会打印到串口。安装好库,复制此代码,仅需要修改WIFI密码和WIFI名称即可
文中变量名,基本都是拼音。我英文考试一直保持15-26分的成绩。

#include <TimeLib.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char Wifi_MingCheng[] = "HuiKeDianNaoFuWu";//your network Wifi_MingCheng (name)
const char Wifi_MiMa[] = "13488214252";       // your network Wifi_MiMaword

//const char Wifi_MingCheng[] = "DanDan";//your network Wifi_MingCheng (name)
//const char Wifi_MiMa[] = "13488214252";       // your network Wifi_MiMaword

// NTP服务器:
static const char NTP_Server_Name[] = "us.pool.ntp.org";
//static const char NTP_Server_Name[] = "time.nist.gov";
//static const char NTP_Server_Name[] = "time-a.timefreq.bldrdoc.gov";
//static const char NTP_Server_Name[] = "time-b.timefreq.bldrdoc.gov";
//static const char NTP_Server_Name[] = "time-c.timefreq.bldrdoc.gov";

const int ShiQu = +8;   //时区 北京时间

WiFiUDP Udp;
unsigned int localPort = 8888;// 用于侦听UDP数据包的本地端口

time_t HuoQu_NTP_ShiJian();// 获取NTP时间
void XianShiShiJian();      //显示时间
void GeShiHuaShuZi(int ShuZi);//格式化数字
void FaSong_NTP_Bao(IPAddress &address);//发送NTP包

void setup() {
Serial.begin(9600);
delay(250);

while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
}

Udp.begin(localPort);

setSyncProvider(HuoQu_NTP_ShiJian);//设置同步提供程序
setSyncInterval(300);            //设置同步间隔
}


time_t ShangYiGeXianShi = 0; // 显示数字时钟时

void loop() {

if (timeStatus() != timeNotSet) {//如果 时间状态 不等于 时间未设置 那么
    if (now() != ShangYiGeXianShi) { //如果 当前时间 不等于 上一个时间 那么    仅当时间改变时更新显示
      ShangYiGeXianShi = now();      //上一个时间 等于 当前时间
      XianShiShiJian();            //显示时间
    }
}
}
















void XianShiShiJian() { // 数字时钟显示时间

Serial.print(year());
Serial.print("-");
GeShiHuaShuZi(month());
Serial.print("-");
GeShiHuaShuZi(day());

Serial.print(" ");

GeShiHuaShuZi(hour());
Serial.print(":");
GeShiHuaShuZi(minute());
Serial.print(":");
GeShiHuaShuZi(second());

Serial.println();
}

void GeShiHuaShuZi(int ShuZi) { // 格式化数字如果输入数字小于10则在前面加0打印出来   注意:下面语句不能加{}否则时间出不来
if (ShuZi < 10)
    Serial.print("0");
Serial.print(ShuZi);

}







/*-------- NTP code ----------*/

const int NTP_Bao_DaXiao = 48;   //NTP包大小      NTP时间在消息的前48个字节中
byte ShuJuBaoHuanChongQu; //数据包缓冲区      用于保存传入和传出数据包的缓冲区

time_t HuoQu_NTP_ShiJian() { //获取NTP时间

IPAddress NTP_Server_IP; // NTP服务器的IP地址

while (Udp.parsePacket() > 0) ; //丢弃以前接收的任何数据包

Serial.println("传输NTP请求");
// 从池中获取随机服务器
WiFi.hostByName(NTP_Server_Name, NTP_Server_IP);
Serial.print(NTP_Server_Name);
Serial.print(": ");
Serial.println(NTP_Server_IP);

FaSong_NTP_Bao(NTP_Server_IP);

uint32_t ShangCiShiJian = millis();          //开始等待
while (millis() - ShangCiShiJian < 1500) {//如果小于这个时间则

    int size = Udp.parsePacket();             //分析数据包
    if (size >= NTP_Bao_DaXiao) {             //如果 获取到的包 大于或等于 NTP包大小
      Serial.println("接收NTP响应");
      Udp.read(ShuJuBaoHuanChongQu, NTP_Bao_DaXiao);// 将数据包读取到缓冲区

      unsigned long secsSince1900;   //从1900年到现在的秒
      // 将从位置40开始的四个字节转换为长整数
      secsSince1900 =(unsigned long)ShuJuBaoHuanChongQu << 24;
      secsSince1900 |= (unsigned long)ShuJuBaoHuanChongQu << 16;
      secsSince1900 |= (unsigned long)ShuJuBaoHuanChongQu << 8;
      secsSince1900 |= (unsigned long)ShuJuBaoHuanChongQu;
      return secsSince1900 - 2208988800UL + ShiQu * SECS_PER_HOUR;
    }
}


Serial.println("无NTP响应");
return 0; // 如果无法获得时间,则返回0
}

// 向给定地址的时间服务器发送NTP请求
void FaSong_NTP_Bao(IPAddress &address) {

// 将缓冲区中的所有字节设置为0
memset(ShuJuBaoHuanChongQu, 0, NTP_Bao_DaXiao);//清零
//初始化形成NTP请求所需的值
//(有关数据包的详细信息,请参阅上面的URL)
ShuJuBaoHuanChongQu = 0b11100011;   // li,版本,模式
ShuJuBaoHuanChongQu = 0;   // 时钟的层次或类型
ShuJuBaoHuanChongQu = 6;   // 轮询间隔
ShuJuBaoHuanChongQu = 0xEC;// 对等时钟精度
//根延迟和根分散为8字节零
ShuJuBaoHuanChongQu = 49;
ShuJuBaoHuanChongQu = 0x4E;
ShuJuBaoHuanChongQu = 49;
ShuJuBaoHuanChongQu = 52;
//所有ntp字段现在都有值
//可以发送请求时间戳的数据包:
Udp.beginPacket(address, 123); //NTP请求到端口123
Udp.write(ShuJuBaoHuanChongQu, NTP_Bao_DaXiao);
Udp.endPacket();
}

ws9528 发表于 2019-8-21 14:49

请大神指点,如何比较获取时间和设定时间的差?

或者说,我设定2019年9月1日 12点32分11秒打开LED灯。   如何判断获取的时间已经到达我设定的时间。在网上找了N久都没找到怎么弄

Arduino 也没有个时间变量。这怎么搞?

amenider 发表于 2019-10-13 20:25

谢谢分享

完完全全 发表于 2019-10-18 15:26

NTPClient库也可实现:)

从入门到放弃· 发表于 2020-5-13 11:04

本帖最后由 从入门到放弃· 于 2020-5-13 11:16 编辑

有人实现过吗?看不懂时间显示和格式化数字函数是怎么实现的。

Dragons 发表于 2020-5-18 22:24

太感谢了
页: [1]
查看完整版本: 实用经验帖 ESP8266 NODEMCU 获取互联网上面时间服务器的标准...