Stumped by "while" loop

I am writing code to control an old-fashioned electromechanical clock dial and in particular to synchronise it to an external time reference. I am using a DCF77 library to synchronise the time from TimeLib and all that seems to work fine. Without going into unnecessary detail, in the setup phase the code waits for the library to sync up, and then I could start to impulse the dial every 30 seconds. However to make the setting more straightforward I need to wait until the internal time is at the "top of the hour" before starting to impulse. To do this I am trying to use this code snippet as the last few lines of void setup{}.

`{
   ;
 }
 while ((minute() != 0) && (second() != 0));
 Serial.print(hour());
 Serial.print(":");
 Serial.print(minute());
 Serial.print(":");  
 Serial.println(second());`
 

So in the "do" block it basically does nothing whilst reading the time from the library, and I want it to continue to do this until both minute and second are zero, i.e. XX:00:00, after which the while loop exits, the exit time is printed, and setup ends. When I run this however I get a typical output like this:
sync time:
16:38:08.140 -> 1:2:21
16:38:47.142 -> 1:3:0

The sync time is printed by previous code when sync is acquired - this is at 1:2:21 in this example. I would expect the while loop to exit at 2:0:0 or 57 minutes later than it actually does. I guess that it's a bit eccentric to just have a ";" in the "do" code, but the behaviour is essentially similar if I for example just print a single character or have a delay plus a single character.

I'm baffled! Help please!

while ((minute() != 0) && (second() != 0));

Will the value of minute() or second() be updated when the code is in this while loop ?

Please post your full sketch

Bob, thanks for your quick response.

Yes, you can see from my sample output that the while loop enters at 1:2:21 and exits at 1:3:0, 39 seconds later, so it is getting updates

There is a previous while loop in the code:

while(timeStatus()== timeNotSet) 
  { 
     // wait until the time is set by the sync provider     
     Serial.println(".");
     delay(2000);
  }

in which another parameter from the library is fetched and the loop exits when its value changes.

What particular aspects of the whole sketch would be helpful? This is the complete setup code which is where the problem is.

#include <DCF77.h>       //https://github.com/thijse/Arduino-Libraries/downloads
#include <TimeLib.h>        //http://www.arduino.cc/playground/Code/Time

#define DCF_PIN 2           // Connection pin to DCF 77 device
#define DCF_INTERRUPT 0    // Interrupt number associated with pin
#define DialPin 4         // To drive dial use D4

time_t prevDisplay = 0;          // when the digital clock was displayed
//time_t time;
DCF77 DCF = DCF77(DCF_PIN,DCF_INTERRUPT);
unsigned long ClockSec = 0;
unsigned long GPSec = 0;
int oldhour = 0;
int oldminute = 0;
int oldsecond = 0;
int S; //switch variable

void setup() 
{
  Serial.begin(9600); 
  pinMode(DialPin, OUTPUT);
  
  DCF.Start();
  setSyncInterval(30);
  setSyncProvider(getDCFTime);
  // It is also possible to directly use DCF.getTime, but this function gives a bit of feedback
  //setSyncProvider(DCF.getTime);

  Serial.println("Waiting for DCF77 time ... ");
  Serial.println("It will take at least 2 minutes until a first update can be processed.");
  while(timeStatus()== timeNotSet) 
  { 
     // wait until the time is set by the sync provider     
     Serial.println(".");
     delay(2000);
  }
  Serial.println("sync time:");
  Serial.print(hour());
  Serial.print(":");
  Serial.print(minute());
  Serial.print(":");  
  Serial.println(second());
  
  do
  {
    ;
  }
  while ((minute() > 0) && (second() > 0));
  Serial.print(hour());
  Serial.print(":");
  Serial.print(minute());
  Serial.print(":");  
  Serial.println(second());
}

This is the complete setup code which is where the problem is.

What do you see if you print the values of minute() and second() within the loop ?

Good question! Let's see...

Your setup code is testing for > 0, not != 0.

Correct, I changed it to see if that was the problem. Since minute and second are both positive integers between 0 and 59, they should be equivalent - indeed give the same results!

Here is the output wehn printing the times inside the loop every 800ms. (Note that therefore there are a few duplicates.)
Xsync time:
17:43:10.574 -> 2:7:28
17:43:10.574 -> 7:28
17:43:11.326 -> 7:28
17:43:12.121 -> 7:29
17:43:12.964 -> 7:30
17:43:13.758 -> 7:31
17:43:14.556 -> 7:32
17:43:15.351 -> 7:32
17:43:16.145 -> 7:33
17:43:16.943 -> 7:34
17:43:17.737 -> 7:35
17:43:18.532 -> 7:36
17:43:19.329 -> 7:36
17:43:20.124 -> 7:37
17:43:20.966 -> 7:38
17:43:21.764 -> 7:39
17:43:22.562 -> 7:40
17:43:23.361 -> 7:40
17:43:24.157 -> 7:41
17:43:24.955 -> 7:42
17:43:25.753 -> 7:43
17:43:26.548 -> 7:44
17:43:27.344 -> 7:44
17:43:28.141 -> 7:45
17:43:28.937 -> 7:46
17:43:29.736 -> 7:47
17:43:30.531 -> 7:48
17:43:31.374 -> 7:48
17:43:32.175 -> 7:49
17:43:32.971 -> 7:50
17:43:33.767 -> 7:51
17:43:34.564 -> 7:52
17:43:35.362 -> 7:52
17:43:36.157 -> 7:53
17:43:36.952 -> 7:54
17:43:37.751 -> 7:55
17:43:38.545 -> 7:56
17:43:39.344 -> 7:56
17:43:40.143 -> 7:57
17:43:40.939 -> 7:58
17:43:41.735 -> 7:59 <<<<===and at this point it exits and prints:
17:43:42.579 -> 2:8:0
17:43:42.579 -> 8::0 <<<<<===and this is the first impulse generated by loop()
17:44:10.513 -> X8::30
So it looks like the time values are updating but the exit condition is not being met correctly.

Oops. I think.

Yes of course - Delta_G has nailed it. Many thanks to all for your quick responses - amazing forum.

Added 38 minutes later - that fixed it!

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