IoT NTP problem

I'm using a NodeMCU Board with the Arduino Cloud IoT.
Everything is working as it should, I get the readings in the dashboard, I can control everything.

BUT, I see around 20 request per seconds to the NTP server 34.73.181.129 on my network.
I consider this FLOODING !

Why does the Arduino IoT Cloud framework make so many NTP request ?
I can use my own RTC DS1307 and my own NTP calls.

Is there a way to reduce the NTP request to like maybe once a day or to disable it completly ? I will manage my time myself.

Someone put the NTP request inside the while loop without any consideration...

At least it is connecting to Arduino's NTP server and they don't seem to block IPs. Their NTP server is probably overloaded by request if everyone using ArduinoIoTCloud is sending that many request.

I'm trying to find where the call to ntp server is done but there is so much code.
If someone can point in what file it is, I can maybe add a couple lines to give the time from my RTC module or to reduce the frequency it send request.

I'm lazy. Is there a link?

I found it !

Now I need to find a way to return my own epoch to the function NTPUtils::getTime(UDP & udp)

@scimmia24 , your topic has been moved to a more suitable location on the forum. Installation and Troubleshooting is not for problems with (nor for advise on) your project :wink: See About the Installation & Troubleshooting category.

Below a short demo code (adjust to your needs); would this also spam the NTP server?

/*
  Based on NTP example and OLED example
  History
  0.1 initial version
  0.2 remove delay and use millis() to update between NTP requests
      added statemachine for NTP requests
  0.3 add serial print of MAC
*/

#define DEBUG

#ifdef DEBUG
#define DEBUG_PRINTLN(x) Serial.println(x)
#define DEBUG_PRINT(x) Serial.print(x)
#else
#define DEBUG_PRINTLN(x)
#define DEBUG_PRINT(x)
#endif



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

const int timeOffset = 7200;
uint32_t ntpTime;

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// SCL GPIO5
// SDA GPIO4
#define OLED_RESET 0  // GPIO0
Adafruit_SSD1306 display(OLED_RESET);

#ifndef STASSID
#include "credentials.h"
#endif

#include "constants.h"

const char * ssid = STASSID; // your network SSID (name)
const char * pass = STAPSK;  // your network password

unsigned int localPort = 2390;      // local port to listen for UDP packets

/* Don't hardwire the IP address or we won't get the benefits of the pool.
    Lookup the IP address for the host name instead */
//IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
IPAddress timeServerIP; // time.nist.gov NTP server address
const char* ntpServerName = "time.nist.gov";

const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message

byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

// A UDP instance to let us send and receive packets over UDP
WiFiUDP udp;

void setup()
{
  // setup serial
  Serial.begin(57600);

  // this seems to be needed befor printing
  delay(500);

  DEBUG_PRINTLN();
  DEBUG_PRINTLN();

  DEBUG_PRINT("MAC: ");
  DEBUG_PRINTLN(WiFi.macAddress());

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 64x48)
  // init done

  // get rid of logo
  display.clearDisplay();
  display.display();

  display.setTextColor(WHITE, BLACK); // this disables transparent mode; we can now overwrite existing text instead of clearing the display; see https://forum.arduino.cc/index.php?topic=383909.0
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.print("Connecting");
  display.display();

  // We start by connecting to a WiFi network
  DEBUG_PRINT("Connecting to ");
  DEBUG_PRINTLN(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    DEBUG_PRINT(".");
  }
  DEBUG_PRINTLN();

  display.clearDisplay();
  display.setCursor(0, 0);
  display.print("Connected");
  display.display();

  DEBUG_PRINTLN("WiFi connected");
  DEBUG_PRINT("IP address: ");
  DEBUG_PRINTLN(WiFi.localIP());

  DEBUG_PRINTLN("Starting UDP");
  udp.begin(localPort);
  DEBUG_PRINT("Local port: ");
  DEBUG_PRINTLN(udp.localPort());
}



void loop()
{
  //get a random server from the pool
  WiFi.hostByName(ntpServerName, timeServerIP);

  getTime();
  printTime();
}

enum NTPSTATES
{
  REQUEST,
  PROCESS,
};


/*
  get the time, either from NTP or by using a millis() based approach
*/
void getTime()
{
  // keep track when we want to do a NTP request
  static uint32_t nextNtpRefresh;
  // timeout start time for reply on request
  static uint32_t timeoutTimer;
  // state machine state
  static NTPSTATES ntpState;

  int cb;

  switch (ntpState)
  {
    case REQUEST:
      if (millis() >= nextNtpRefresh)
      {
        nextNtpRefresh += ntpRefreshInterval;
        DEBUG_PRINTLN(millis());
        sendNTPpacket(timeServerIP); // send an NTP packet to a time server
        timeoutTimer = millis();
        ntpState = PROCESS;
      }
      updateNtpTime();
      break;
    case PROCESS:
      cb = udp.parsePacket();
      if (!cb)
      {
        //DEBUG_PRINTLN("no packet yet");
        updateNtpTime();

        if (millis() - timeoutTimer > ntpRequestTimeout)
        {
          ntpState = REQUEST;
        }
      }
      else
      {
        DEBUG_PRINTLN(millis());
        DEBUG_PRINT("packet received, length=");
        DEBUG_PRINTLN(cb);
        processNtpPacket();
        ntpState = REQUEST;
      }
      break;
  }
}

/*
  send an NTP request to the time server at the given address
*/
void sendNTPpacket(IPAddress& address)
{
  DEBUG_PRINTLN("sending NTP packet...");
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  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;

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

/*
  update ntpTime if we don't do not send a request or or are wauting for a reply
*/
void updateNtpTime()
{
  static uint32_t nextUpdateTime;

  if (millis() >= nextUpdateTime)
  {
    nextUpdateTime += 1000;
    ntpTime += 1;
  }
}

/*
  process a received UDP packet
*/
void processNtpPacket()
{
  /*
    TODO: make sure that this is a reply to the NTP request
  */

  // We've received a packet, read the data from it
  udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer

  //the timestamp starts at byte 40 of the received packet and is four bytes,
  // or two words, long. First, esxtract the two words:

  unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
  unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
  // combine the four bytes (two words) into a long integer
  // this is NTP time (seconds since Jan 1 1900):
  unsigned long secsSince1900 = highWord << 16 | lowWord;
  DEBUG_PRINT("Seconds since Jan 1 1900 = ");
  DEBUG_PRINTLN(secsSince1900);

  // now convert NTP time into everyday time:
  DEBUG_PRINT("Unix time = ");
  // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
  const unsigned long seventyYears = 2208988800UL;
  // subtract seventy years and compensate for timezone
  unsigned long epoch = secsSince1900 - seventyYears + timeOffset;
  // print Unix time:
  DEBUG_PRINTLN(epoch);

  ntpTime = epoch;
}

void printTime()
{
  static int prevMinute;

  if (prevMinute != minute(ntpTime))
  {
    prevMinute = minute(ntpTime);
    DEBUG_PRINT("Year =  "); DEBUG_PRINTLN(year(ntpTime));
    DEBUG_PRINT("Month = "); DEBUG_PRINTLN(month(ntpTime));
    DEBUG_PRINT("Day =   "); DEBUG_PRINTLN(day(ntpTime));
    DEBUG_PRINT("Hour =  "); DEBUG_PRINTLN(hour(ntpTime));
    DEBUG_PRINT("Min =   "); DEBUG_PRINTLN(minute(ntpTime));
    DEBUG_PRINT("Sec =   "); DEBUG_PRINTLN(second(ntpTime));

    display.setTextSize(2);
    //display.clearDisplay();

    char buffer[10];
    sprintf(buffer, "%02d/%02d", month(ntpTime), day(ntpTime));
    display.setCursor(0, 0);
    display.print(buffer);
    display.display();

    sprintf(buffer, "%02d:%02d", hour(ntpTime), minute(ntpTime));
    display.setCursor(0, 20);
    display.print(buffer);
    display.display();
  }
}

Your ntp example does not help.
I said I already have all I need to manage my own NTP.

The problem is the ArduinoIoTCloud library that is bugged and sending NTP request as fast as it can.
I need to fix it, or someone that is programming that library need to fix it.

I was hoping that the code could be adjusted to make use of the specified NTP server (34.73.181.129).

The link that you provided does not call the getTime() method so does not mean anything. Something is calling that method and that is what you have to find.

getTime is called here :

I just need to insert my RTC there instead of the RTCZero and get the time from my RTC instead of fetching NTP with getTime.

I will try it tommorow.

The methods that use getTime() are called somewhere; possibly your code.

If I understand it correctly, you just want to use an (physical) RTC instead of NTP time. I have no experience with IoT so this might be to simplistic but if you replace the calls to the above methods in your code by something that you write yourself for an RTC, your problem should be solved.

getTime() is called/used in the related TimeService.cpp

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.