Problem with calling function once every x minutes

[Setup: Arduino Uno IDE 1.8.0, Ethernet Shield 2 with PoE, time sync with router (which itself is on sync with an external time provider), included libraries Time.h and TimeLib.h]

Hi all,

I am currently trying to figure out how to have a function being called once every 5 minutes, but so far the result I have been able to achieve is a far cry from what I need.

The code I am tinkering with is as follows:

void loop()
{
 if (minute() - minute(t) >= 5)  //doesn't work: keeps running endlessly and
                                              //     not once every 5 minutes
{
 for(int i = 0; i < 1; i++)          //for should run only once when condition
			                     //within if is met
{
 syncedTime();			    // function I am currently testing with

/*Alternative testing code
 Serial.print(minute()); 	    // Returns current minute correctly
 Serial.println();
 Serial.print(minute(t)); 	    // Returns only zeroes, and hence not the
                                           // minute one expects from now();
Serial.println();
*/

}
time_t t = now();

}

}

With the call to function syncedTime() enabled, this is what I get as a result:

Waiting for sync with Fritz!Box...

Transmit NTP Request
Received NTP Response

Fritz!Box has set the system time!

[22:02:00 / 05-01-2017]

[22:02:00 / 05-01-2017]

[22:02:00 / 05-01-2017]

[22:02:00 / 05-01-2017]

[22:02:01 / 05-01-2017]

[22:02:01 / 05-01-2017]

[22:02:01 / 05-01-2017]

[22:02:01 / 05-01-2017]

Etc. Etc.

Instead of once every two minutes, as specified, I am seeing numerous timestamps per second. When the function call is commented out, and the Serial.print lines are activated, I am getting this:

Waiting for sync with Fritz!Box...

Transmit NTP Request
Received NTP Response

Fritz!Box has set the system time!

6
0
6
0
6
0
6

Etc. etc.

Where Serial.print(minute()) correctly returns the current minute, Serial.print(minute(t)) only returns zeroes. Obviously, the instruction time_t t = now(); doesn't do what I expected it to do. As I am completely stuck on this one, I would much appreciate any leads that would help me getting further.

Thanking you in advance for your time,

Simon

Can you share your minute() and now() functions?

You will have more success getting help if you attach your whole sketch.

.

Quite sure I don't understand everything going on there but...

5 minutes is 300,000 milliseconds

Maybe just do it blink without delay style with a interval value of 300,000?

claudiaa, LarryD,

For the complete sketch, please see below. Would I need to attach both Time.h and TimeLib.h as well? For your information: the function syncedTime() I am calling in the sketch is eventually to replaced by another one, but is used here for testing purposes.

Thanks for your attention,

Simon

#include <Ethernet2.h>
#include <EthernetUdp2.h>
#include <SPI.h>
#include <Time.h>
#include <TimeLib.h>

// MAC-adres Arduino
byte mac[] =
  {
  0x99, 0x99, 0x99, 0x99, 0x99, 0x99 // Dummy MAC address
  };

IPAddress timeServer(999, 999, 999, 9);   // Dummy IP-address of Fritz!Box acting as NTP-server

IPAddress ip(999, 999, 999, 99);          // Dummy IP-adres of Arduino

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

const int timeZone = 1;     // Central European Time == Greenwich Mean Time (GMT) + 1

int t;

// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

void syncedTime(void);

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

  Ethernet.begin(mac, ip);
  
  Udp.begin(localPort);

  Serial.println("Waiting for sync with Fritz!Box...\r\n");
  
  setSyncProvider(getNtpTime);
  if(timeStatus()!= timeSet) 
  Serial.println("Unable to sync with Fritz!Box\r\n");
  else
  Serial.println("Fritz!Box has set the system time!\r\n");
}

void loop()
{
if (minute() - minute(t) >= 2) // doesn't work: keeps running endlessly and not once every 2 minutes
{
for(int i = 0; i < 1; i++) // for should run only once
{
syncedTime();
/*
Serial.print(minute()); // Returns current minute correctly
Serial.println();
Serial.print(minute(t)); // Returns 0, and hence not the minute one expects from time_t t = now();
Serial.println();
*/
}

time_t t = now();
}

//  now();
}

//-------- NTP code ----------
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets

time_t getNtpTime()
{
  while (Udp.parsePacket() > 0) ; // discard any previously received packets
  Serial.println("Transmit NTP Request");
  sendNTPpacket(timeServer);  
  uint32_t beginWait = millis();
  while (millis() - beginWait < 1500)
  {
    int size = Udp.parsePacket();
    if (size >= NTP_PACKET_SIZE)
    {
    Serial.println("Received NTP Response\r\n");

    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, extract 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, which is
//  NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;
//  now convert NTP time into everyday time (Unix time starts on Jan 1 1970. In seconds, that's 2208988800)
    unsigned long CET = secsSince1900 - 2208988800UL + (timeZone*3600UL);
    return CET;
    }
  }

  Serial.println("No NTP Response :-(\r\n");
  return 0; // return 0 if unable to get the time
}

// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
  // 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();
}

void syncedTime(void)
{

//this code works but uses up more memory
//sprintf(dateBuffer,"[%02u:%02u:%02u / %02u-%02u-%04u]\r\n\n",hour(),minute(),second(),day(),month(),year());
//Serial.print(dateBuffer);  

//alternative code uses less memory
  Serial.print('[');
  if (hour() < 10)
  {
  // In the first 9 hours of each day, we'll want a leading '0'
  Serial.print('0');
  }
  Serial.print(hour());
  Serial.print(":");
  if (minute() < 10)
  {
  // In the first 9 minutes of each hour, we'll want a leading '0'
  Serial.print('0');
  }
  Serial.print(minute());
  Serial.print(":");
  if (second() < 10)
  {
  // In the first 9 seconds of each minute, we'll want a leading '0'
  Serial.print('0');
  }
  Serial.print(second());
  Serial.print(" / ");
  if (day() < 10)
  {
  // In the first 9 days of each month, we'll want a leading '0'
  Serial.print('0');
  }
  Serial.print(day());
  Serial.print("-");
  if (month() < 10)
  {
  // In the first 9 months of each year, we'll want a leading '0'
  Serial.print('0');
  }
  Serial.print(month());
  Serial.print("-");
  Serial.print(year());  
  Serial.println("]\r\n");
}

@Delta_G

The thought proces was that I wanted to make sure that each time a predefined period had elapsed, a given function was called only once. My approach obviously didn't work, but I have now solved my problem by employing the solution suggested in another thread (https://forum.arduino.cc/index.php?topic=337512.0).

Anyway, thanks for helping!

if (millis () - target_time >= updateInterval)
  {
    target_time += updateInterval ;   // changes scheduled time exactly, no slippage will happen

    uploadTemps();

}