乐鑫技术交流
直播中

梅利号

8年用户 1470经验值
擅长:可编程逻辑
私信 关注
[问答]

ESP收不到NTP包的原因?

我试图在不使用库的情况下获得 NTP 时间,因为我有一些我想要的特定功能。但是,ESP 似乎没有收到 NTP 数据包。发送到我的 PC(但是不同的端口)有效(使用 Packet Sender 测试),并且手动将数据包从我的 PC 发送到 ESP(再次使用 Packet Sender)有效。将完全相同的数据包从我的 PC 发送到 NTP 服务器也可以,但 ESP 将数据包发送到服务器似乎没有收到回复。
硬件:ESP-01,改装4M闪存。
IDE:带有 PlatformIO
代码的 VSCode:
通过串行端口发送字符 @ 115200 波特进行测试。空格发送到指定的 IP,任何其他字符发送到第一个 NTP 服务器以解析到 IP 地址。
代码:全选#include
#include
#include

#define NTP_PACKET_SIZE 48
#define NTP_tiMEOUT 10000  // retry if no reply in 10 seconds
#define MAX_NTP_RETRYS 5   // only retry 5 times
// NTP
byte NTPBuffer[NTP_PACKET_SIZE];
IPAddress ntpServerAddress;
WiFiUDP UDP;
const String ntpServerHostnames[] = {\"au.pool.ntp.org\" /* AU NTP pool*/, \"time.google.com\", \"time.windows.com\", \"time.nist.gov\" /* US servers */};
byte ntpRequestCount = 0;
void setup() {
    delay(50);  // probably a good idea to have this. Let things \"settle\"
    Serial.begin(115200);
    while (!Serial)
        ;
    Serial.println(\"\\n\\nBeginning setup\");
    delay(10);
    WiFi.begin(\"ssid\", \"pass\");
    WiFi.mode(WIFI_STA);
    delay(5000);
    Serial.println(WiFi.status() == WL_CONNECTED ? \"WiFi connected\" : \"WiFi not connected, rebooting\");
    bool udp = UDP.begin(123);
    Serial.println(udp ? \"UDP setup\" : \"UDP fail\");
    if (WiFi.status() != WL_CONNECTED || !udp) ESP.restart();
}

void requestNtpTime();
uint32_t parseNtpTime();
void sendNTPpacket(IPAddress& address);

void loop() {
    while (!Serial.available()) ;
    delay(100);
    bool local = false;
    if (Serial.peek() == \' \') local = true;
    while (Serial.available()) Serial.read();
    IPAddress pc = IPAddress(10, 0, 0, 1); // PC address here
    if (!local)
        requestNtpTime();
    else
        sendNTPpacket(pc);
    delay(100);
    Serial.println(UDP.parsePacket());
    Serial.println(UDP.available());
    Serial.println(parseNtpTime(), HEX);
}

void requestNtpTime() {
    bool addrResolved = false;
    for (byte i = 0; i < 4 && !addrResolved; i++)
        if (WiFi.hostByName(ntpServerHostnames.c_str(), ntpServerAddress)) addrResolved = true;
    if (!addrResolved) WiFi.hostByName(\"pool.ntp.org\", ntpServerAddress);
    Serial.println(\"Requesting time\");
    sendNTPpacket(ntpServerAddress);
}
uint32_t parseNtpTime() {
    if (UDP.parsePacket() == 0) {  // If there\'s no response (yet)
        return 0;
    }
    Serial.printf(\"Got time from %s:%d\\n\", UDP.remoteIP().toString().c_str(), UDP.remotePort());
    UDP.read(NTPBuffer, NTP_PACKET_SIZE);  // read the packet into the buffer
    // Combine the 4 timestamp bytes into one 32-bit number
    uint32_t NTPTime = (NTPBuffer[40] << 24) | (NTPBuffer[41] << 16) | (NTPBuffer[42] << 8) | NTPBuffer[43];  //NTP Timestamp
    // Convert NTP time to a UNIX timestamp:
    // Unix time starts on Jan 1 1970. That\'s 2208988800 seconds in NTP time:
    Serial.println(NTPTime, HEX);
    const uint32_t seventyYears = 2208988800UL;
    // subtract seventy years:
    uint32_t UNIXTime = NTPTime - seventyYears;
    return UNIXTime;
}
void sendNTPpacket(IPAddress& address) {
    memset(NTPBuffer, 0, NTP_PACKET_SIZE);  // set all bytes in the buffer to 0
    // Initialize values needed to form NTP request
    NTPBuffer[0] = 0b11011011;  // LI (3 - unsynchronised, 2 bits), Version (3, 3 bits), Mode(3 - client, 3 bits)
    NTPBuffer[1] = 0;           //Clock stratum
    // send a packet requesting a timestamp:
    bool begun = UDP.beginPacket(address, 123);  // NTP requests are to port 123
    UDP.write(NTPBuffer, NTP_PACKET_SIZE);
    bool end = UDP.endPacket();
    Serial.printf(\"Sending packet: %s, %s, to %s\\n\", begun ? \"true\" : \"false\", end ? \"true\" : \"false\", address.toString().c_str());
}




更多回帖

×
20
完善资料,
赚取积分