NTP code is blocking 1500ms in while-loop. change!

Moderators: grovkillen, Stuntteam, TD-er

Post Reply
Message
Author
tozett
Normal user
Posts: 734
Joined: 22 Dec 2015, 15:46
Location: Germany

NTP code is blocking 1500ms in while-loop. change!

#1 Post by tozett » 13 Sep 2016, 21:19

hi, all the (one) devs out there,

(i am no professional coder, ....but:)

i checked the ntp-source of espeasy and found it for the NTP-part its the all-web-standard.
if i understood it correct, it has a while loop which could block all the loop for max 1500ms, if no packet received.
:oops:

you can check it here on espeasy:
https://github.com/ESP8266nu/ESPEasy/bl ... .ino#L1793

i recognised this, as i also used this sketch-code, but my animations stood still on my esp's for the time of the while-loop receive!
:oops:

i searched found two other sketch sources on the web,
they are actually now running fine since this evening on my esp in my test with some other animation code.

the first has smaller code, the second one has a timer/millis() check,
like on other places in ESPeasy code.

millis:
https://forum.arduino.cc/index.php?topic=206695.0

smaller code:
http://playground.arduino.cc/Code/NTPclient

may you like to make this (small) change to the esp-easy source?

i attach my running code as an example.
it is a beginners code...be graceful...

it can sure be much, much, much, more elegant.
you can do this, please.

but as it is, it is NON-BLOCKING for the receive of ntp-packet
(if i am not totally wrong ... one should do so: http://playground.arduino.cc/Code/AvoidDelay)

Code: Select all

void loop ()
{
#ifdef NTP5
if ( millis() > ntpStartTime)
   NTPget();               // if time is ours, do ntp-processing. else do something else here. but we dont want to block looping with delay!
#endif
}

Code: Select all

/*********************************************************************************************/
unsigned long NTPget()
  {
  if ( ntpState == 1 )   /* REQUEST */
    {
    IPAddress timeServerIP; 
    const char* ntpServerName = "de.pool.ntp.org";  //hard-coded here, but could be via gui

    WiFi.hostByName(ntpServerName, timeServerIP);   // get a random server from the pool
    Serial.println ("got ntp-hostname. name<->IP is: ");
    Serial.print(ntpServerName);
    Serial.print(": ");
    Serial.println(timeServerIP);


    static int udpInited = udp.begin(123);        // open socket on arbitrary port (or 123)
    if (! udpInited) { return 0; } /* Fail if WiFiUdp.begin() could not init a socket  */

    udp.flush();      /* Clear old received data  */  
  
    // Send an NTP request in one single if-line  // 123 is the NTP port
    const long ntpFirstFourBytes = 0xEC0600E3;    // NTP request header (short), // Only the first four bytes of an outgoing NTP packet need to be set appropriately, the rest can be whatever.
    
    if (! (udp.beginPacket(timeServerIP, 123) && udp.write((byte *)&ntpFirstFourBytes, 48) == 48 && udp.endPacket() ) )
      {
        return 0;       // sending request failed
      }
    
    udp.flush();        /* Clear old received data  */  

    ntpStartTime = millis() + 1000;     // set check-time
    ntpLoop = 0;                        // re-try counter to zero
    ntpState = 2;                       // set state; 2 = receive ntp-packet with time-data
    
    return 1;                           //go back from this function (successfull..)
  
  }//end-if-state-1


    
  if ( ntpState == 2 ) /* RECEIVE */
    {
    Serial.println("ntpstartime now: we try to get the packet"); 
    
    int datain = udp.parsePacket();   //take packet
    if (datain  != 48) { return 0; }  /* no correct packet received */
    
    if ( datain )
        {
        //if (datain  != 48) { return 0; }  /* no correct packet received */
        
        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;
        // now convert NTP time into Arduino Time format:
        // Time starts on Jan 1 1970. In seconds, that's 2208988800:
        const unsigned long seventyYears = 2208988800UL;
        // subtract seventy years:
        unsigned long epoch = secsSince1900 - seventyYears+3600; // +3600 too MEZ;
        
          
        Serial.println("ntp-data-in, Succes!");
        Serial.print("NTP-Get-Packet()-> Epoch is: ");
        Serial.println(epoch);

        ConvertUnixTimeStamp(epoch, &gDateTime);    //set global date-time variable from new received ntp-time
        Serial.print("Clock is now: ");
        Serial.print( String(gDateTime.hour) );
        Serial.print(" : ");
        Serial.print( String(gDateTime.minute) );
        Serial.print(" hrs");
        Serial.println( );

        ntpLoop = 0;                        // set re-try-counter back to start-default  
        ntpState=1;                         // change next state; 1 = request a ntp packet from ntp-server
        ntpStartTime = millis() + 360000;   // set next-check-Time 
          
        return epoch;       //exit from this function here with the: unsigned long epoch, unix-time
     
    }//end-if datain
    

    /* No data in Start-time,, we have no yet a Packet received. We try again for x times...*/
    if (ntpLoop <= 10 ) { ntpLoop++; ntpStartTime = millis() + 300; }     /* we take some short timed re-tries to get the ntp-packet */
    if (ntpLoop >  10 )    
      {
        /* we tried to often without success, we wait sometime until we try again */
        ntpLoop = 0;                        // set re-try-counter back to start-default
        ntpState=1;                         // change next state; 1 = request a ntp packet from ntp-server
        ntpStartTime = millis() + 6000;     // next-check-Time, 6000ms=1sek
        Serial.println("no ntp until now, going again in 6000ms to request a new ntp-packet");
        
        return 0;                           // exit from this function and ntpState2 + new activation-time
      
      }//end-if-to-much-tries
  
  /* Exit meanwhile and do another things in main */
  }//end-if state2
  
  /* it was not our time, we have done nothing and return from here to do another things in main (no delay here means non-block) */
  
}//end-function
Attachments
ntp1.png
ntp1.png (59.33 KiB) Viewed 3615 times
ntp2.png
ntp2.png (98.13 KiB) Viewed 3615 times

Post Reply

Who is online

Users browsing this forum: Amazon [Bot], Bing [Bot] and 51 guests