arduino-esp32 icon indicating copy to clipboard operation
arduino-esp32 copied to clipboard

SNTP configuration takes long and sometimes fails with 2.0.x

Open lptr opened this issue 3 years ago • 13 comments

Board

Reproduced on LilyGo T18 V3.0 and LilyGo T8 ESP32-S2 V1.1

Device Description

Just the plain dev modules.

Hardware Configuration

Nothing connected.

Version

latest master (checkout manually)

IDE Name

PlatformIO

Operating System

macOS 12.3.1

Flash frequency

40

PSRAM enabled

no

Upload speed

1500000

Description

SNTP configuration takes randomly longer with Arduino-ESP 2.0.x than with 1.0.6. With 2.0.x it sometimes does not finish at all, while with 1.0.6 it is always successful.

Using Arduino 1.0.6, WIFI connection takes longer (each . is 100 ms), but after that time.google.com always returns practically immediately:

$ pio run --target upload --target monitor --environment arduino1
...
Start time is 0
Connecting................................. connected.
Current time is 3
NTP updated system clock to 1652133442
Current time is 1652133443
Current time is 1652133444

Using Arduino 2.0.x the WIFI connection is almost immediate, but then it takes several seconds to configure NTP, altogether slower than with Arduino 1:

$ pio run --target upload --target monitor --environment arduino2
...
Start time is 0
Connecting.......... connected.
Current time is 0
Current time is 1
Current time is 2
Current time is 3
Current time is 4
NTP updated system clock to 1652133475
Current time is 1652133475
Current time is 1652133476

Sketch

Reproducer sketch here: https://github.com/lptr/arduino2-sntp-problem

#include <Arduino.h>
#include <WiFi.h>
#include <esp_sntp.h>

void ntpUpdated(struct timeval* tv) {
    Serial.printf("NTP updated system clock to %ld\n", tv->tv_sec);
}

void setup() {

    Serial.begin(115200);

    Serial.printf("Start time is %ld\n", time(nullptr));

    WiFi.begin("...", "...");
    Serial.print("Connecting...");
    while (!WiFi.isConnected()) {
        delay(100);
        Serial.print(".");
    }
    Serial.println(" connected.");

    sntp_set_time_sync_notification_cb(ntpUpdated);
    configTime(0, 0, "time.google.com");
}

void loop() {
    Serial.printf("Current time is %ld\n", time(nullptr));
    delay(1000);
}

Other Steps to Reproduce

I tried with 2.0.3 and with the latest master (709029996fb98c269130aa0b614546e8aa43f011), and the problem exists with both.

I have checked existing issues, online documentation and the Troubleshooting Guide

  • [X] I confirm I have checked existing issues, online documentation and Troubleshooting guide.

lptr avatar May 09 '22 22:05 lptr

You must be using an outdated core in some of the configurations. Here is my log from ESP32-S2 for 3 consecutive connects, IDE 1.8.16 and Arduino 2.0.3

Start time is 0
Connecting.................. connected.
Current time is 3
NTP updated system clock to 1652135991
Current time is 1652135992
Current time is 1652135993
Current time is 1652135994
// Reset
ESP-ROM:esp32s2-rc4-20191025
Build:Oct 25 2019
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3ffe6100,len:0x524
load:0x4004c000,len:0xa50
load:0x40050000,len:0x28cc
entry 0x4004c18c
Start time is 0
Connecting.... connected.
Current time is 0
NTP updated system clock to 1652135996
Current time is 1652135996
Current time is 1652135997
// Reset
ESP-ROM:esp32s2-rc4-20191025
Build:Oct 25 2019
rst:0x1 (POWERON),boot:0xa (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3ffe6100,len:0x524
load:0x4004c000,len:0xa50
load:0x40050000,len:0x28cc
entry 0x4004c18c
Start time is 0
Connecting..... connected.
Current time is 0
Current time is 1
NTP updated system clock to 1652136000
Current time is 1652136000
Current time is 1652136001
// Reset + Boot
ESP-ROM:esp32s2-rc4-20191025
Build:Oct 25 2019
rst:0x1 (POWERON),boot:0x0 (DOWNLOAD(USB/UART0/1/SPI))
waiting for download

me-no-dev avatar May 09 '22 22:05 me-no-dev

ESP32 is much the same:

ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13516
load:0x40080400,len:3604
entry 0x400805f0
Start time is 0
Connecting.... connected.
Current time is 0
Current time is 1
Current time is 2
Current time is 3
NTP updated system clock to 1652136481
Current time is 1652136481
Current time is 1652136482
// Reset
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13516
load:0x40080400,len:3604
entry 0x400805f0
Start time is 0
Connecting.... connected.
Current time is 0
Current time is 1
NTP updated system clock to 1652136486
Current time is 1652136486
Current time is 1652136487
Current time is 1652136488
// Reset
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13516
load:0x40080400,len:3604
entry 0x400805f0
Start time is 0
Connecting.... connected.
Current time is 0
Current time is 1
NTP updated system clock to 1652136491
Current time is 1652136491
Current time is 1652136492
// Reset + Boot
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x3 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2))
waiting for download

me-no-dev avatar May 09 '22 22:05 me-no-dev

Thanks for the quick response. Do you mean outdated PlatformIO Core? I'm using 5.2.5, which is the latest to the best of my knowledge.

lptr avatar May 09 '22 23:05 lptr

Outdated ESP32-Arduino core. @Jason2866 could help more :)

me-no-dev avatar May 09 '22 23:05 me-no-dev

Sorry, being a n00b here. :) Is that the same as arduino-esp32? From that I believe I'm using 2.0.3 here: https://github.com/lptr/arduino2-sntp-problem/blob/main/platformio.ini#L23-L27

lptr avatar May 09 '22 23:05 lptr

I tested with all chips, but posted what you mentioned. In 2.0.3 we made connection much faster. First connect in some time takes longer, but from then it happens fast (visible in my S2 log). Usually most time is taken by the DHCP. You can check by enabling debug to level "Verbose" -DCORE_DEBUG_LEVEL=5 in your project flags

me-no-dev avatar May 09 '22 23:05 me-no-dev

Looking at the setup it should use Arduino core 2.0.3 You could try this two setups. First Tasmota Arduino core 2.0.3 (Some changes in sdkconfig) and the second with orig. espressif Arduino core 2.0.3. Both setup are based on a Platformio Framework fork which is more actual then the official one.

platform = https://github.com/tasmota/platform-espressif32/releases/download/v.2.0.3/platform-espressif32-v.2.0.3.zip
platform = https://github.com/tasmota/platform-espressif32/releases/download/v.2.0.3/platform-espressif32-v.2.0.3.zip
platform_packages  = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32/releases/download/2.0.3/esp32-2.0.3.zip

Will try later the day your sketch, to see the results i get.

Jason2866 avatar May 10 '22 08:05 Jason2866

Confirmed. core 1.0.6. gets NTP earlier but did not fail for me with core 2.0.3

Jason2866 avatar May 10 '22 10:05 Jason2866

Can I consider this as solved @lptr?

VojtechBartoska avatar Jul 26 '22 13:07 VojtechBartoska

I still can reproduce the behavior where my application fails to connect to NTP when upgrading to 2.0.x, so for me it's not solved. I can try to come up with a better minimal reproducer that shows not just a slowdown but the inability to connect.

lptr avatar Jul 26 '22 15:07 lptr

OK, I think I made some progress. If I connect like this, it works for Arduino 2 as well, although somewhat slower than Arduino 1:

configTime(0, 0, "time.google.com");

However, if I do this, it does not connect using Arduino 2:

String timeServer = "time.google.com";
configTime(0, 0, timeServer.c_str());

Did something change around sntp_setservername()? Did it make a defensive copy of the server name before, and not anymore perhaps?

lptr avatar Jul 27 '22 09:07 lptr

I've updated the example here: https://github.com/lptr/arduino2-sntp-problem/blob/7b9adf9e21d1f1fdb06521e6a9a8796cd4e4a652/src/main.cpp#L28-L31

lptr avatar Jul 27 '22 09:07 lptr

I just came across this still open issue and wanted to share my findings after encountering the same problem some time ago.

Did something change around sntp_setservername()? Did it make a defensive copy of the server name before, and not anymore perhaps?

I never used 1.0.6, but I can say that 2.0.x definitely doesn’t make a copy of the passed server name string. Use sntp_getservername() to get the stored NTP server name and compare it with whatever you passed to configTime().

String timeServer = "time.google.com";
configTime(0, 0, timeServer.c_str());
printf("timeServer.c_str() at %p, sntp_getservername(0) returns %p\n", timeServer.c_str(), sntp_getservername(0));

That will print something like this:

timeServer.c_str() at 0x3ffb644c, sntp_getservername(0) returns 0x3ffb644c

The addresses are the same, so no copy is made.

If timeServer is a local String object, you will not be able to contact the server once the contained C string is overwritten. Fun fact: Short server names (< 12 chars) will live on the stack (due to SSO) and longer names will live on the heap, so you might get different results depending on the length of the server name.

MattiasTF avatar Apr 16 '24 17:04 MattiasTF