Problem with time oled display

hello, i'm having a problem displaying the time on my oled screen : every 7 seconds, it jumps 2 seconds instead of one
here is my code :

#include <TimeLib.h>
#define TIME_HEADER  "T"
#define TIME_REQUEST  7 

#include <Wire.h>
#include <Adafruit_GFX.h> 
#include <Adafruit_SSD1306.h>
 
#define SCREEN_WIDTH 128 
#define SCREEN_HEIGHT 64 

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

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

  setSyncProvider(requestSync); 
  Serial.println("input unix time");
  Serial.println("ex : T1416479045");

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed")); 
    for(;;);
  }
} 
   
void loop(){
  printText();
  delay(100); 
  
  if (Serial.available()) {
    processSyncMessage();
  }
  if (timeStatus()!= timeNotSet) {
    digitalClockDisplay();  
  }
  delay(1000);
  display.display();
}


void printText(){
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  //display.println(digitalClockDisplay());
}
   

void digitalClockDisplay(){
  // fonction affichage du temps
  display.print(hour());
  printDigits(minute());
  printDigits(second());
  display.println();
}

void printDigits(int digits){
  display.print(":");
  if(digits < 10)
    display.print('0');
  display.print(digits);
}

void processSyncMessage() {
  unsigned long pctime;
  const unsigned long DEFAULT_TIME = 946681200;

  if(Serial.find(TIME_HEADER)) {
     pctime = Serial.parseInt();
     if( pctime >= DEFAULT_TIME) {
       setTime(pctime);
       }
  }
}

time_t requestSync() {
  Serial.write(TIME_REQUEST);  
  return 0;
}```

You have a total of 1100mS of delay in loop, that along with the time it takes to update the display is causing your problem.

Do not use delay in loop, instead test to see if the value of second() has changed, and if so then update the display.

so does that mean i have to remove the delays?

Yes, you do.

Start here:
Using millis for timing
Demonstration for several things at the same time
Finite state machine tutorial

1 Like

You have to remove the delays, but you don't have to start using millis(), or finite state machines. Not yet, anyway. As PerryBebbington @david_2018 said, just update when your code detects second() change.

i tried it and it works fine now, thank you try i'll read your links later :wink:

@PaulRB
You beat me to it, I was going to edit my post to be more helpful. It was @david_2018 who suggested only updating the display when the seconds change, not me!

@galixou
You need an extra variable, maybe lastSecond, where you store the value of second last time around loop, you test it using something like this:

if (lastSecond != second()) {
lastSecond = second();
// Print the time here
}

ok i see what you mean

As a rule of thumb you only need to update a display at the most 5 times a second, if that, because no one can read the changes any faster. Also, only update it when something has changed and needs to be updated.

void digitalClockDisplay(){
  // fonction affichage du temps
  char buffer[10];
  sprintf( buffer, "%2d:%02d:%02d", hour(), minute(), second());
  display.println(buffer);
}

A bit shorter for you. printDigits() no longer needed.

Sorry @david_2018. My mind is going. I can feel it, Dave. I can feel it...

1 Like