Why is my clock loosing time - FAST

I’ve recently added a temperature monitor to my clock but it seems to have slowed my clock down…almost that 1 second on the clock is taking 2 seconds!! - I though I may have a delay somewhere but it seems not…unless I can’t see the wood for the trees!
Can you experts take a look to see as to why my clock is slow.
Thanks

//5-9-20 added 2 x 7 segment LED and 2 x temp sensors


#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <LedControl.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Ticker.h>
#include <LedControl.h>
#include <Wire.h>

LedControl lc=LedControl(12,14,2,2);  // GPIO pins DIN=12 CLK=14 CS=2 

// GPIO where the DS18B20 is connected to
const int oneWireBus = 4;    //first DS18B20 (GPIO4-D2)
const int oneWireBus2 = 5;   // seconf DS18B20 (GPIO5-D1)    
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
OneWire oneWire2(oneWireBus2);
// Pass our oneWire reference to Dallas Temperature sensor 
DallasTemperature sensors(&oneWire);
DallasTemperature sensors2(&oneWire2);
// Temperature value
float temp;
float temp2;




//#include <TM1637Display.h>

//#define CLK D3  //0
//#define DIO D2  //4
#define time_zone 3600*10

//TM1637Display display(CLK, DIO);

char ssid[] = "WiFi-86F4";  //  your network SSID (name)
char pass[] = "75831431";       // your network password

int ldr = A0;
int ldr_value = 0;

unsigned long epoch;
int hh;
int mm;
int ss;
int hhd;
int force_update = 1;
bool showdot = false;
uint32_t ts, ts1, ts2, ts3, ts4;
unsigned int localPort = 2390;

int ip = 0;
String IP_of_Server[5]    = {"122.155.169.213", "129.6.15.28", "158.108.212.149", "203.158.118.2", "129.250.35.250"};
IPAddress timeServer;
const int NTP_PACKET_SIZE = 48;
byte packetBuffer[ NTP_PACKET_SIZE];
WiFiUDP udp;

unsigned long sendNTPpacket(IPAddress& address)
{
  Serial.println("sending NTP packet...");
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  packetBuffer[0] = 0b11100011;
  packetBuffer[1] = 0;
  packetBuffer[2] = 6;
  packetBuffer[3] = 0xEC;
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
  udp.beginPacket(address, 123);
  udp.write(packetBuffer, NTP_PACKET_SIZE);
  udp.endPacket();
}

void NTP_get(void)
{
  sendNTPpacket(timeServer);
  delay(1000);
  int cb = udp.parsePacket();
  if (!cb) {
    force_update = 1;
  }
  else {
    force_update = 0;
    udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    unsigned long secsSince1900 = highWord << 16 | lowWord;
    const unsigned long seventyYears = 2208988800UL;
    epoch = secsSince1900 - seventyYears + time_zone;
  }
}

void setup() {

 //we have already set the number of devices when we created the LedControl
  int devices=lc.getDeviceCount();
  //we have to init all devices in a loop
  for(int address=0;address<devices;address++) {
    /*The MAX72XX is in power-saving mode on startup*/
    lc.shutdown(address,false);
    /* Set the brightness to a medium values */
    lc.setIntensity(address,8);
    /* and clear the display */
    lc.clearDisplay(address);
  }

  sensors.begin();
  sensors2.begin();
  Serial.begin(115200);
  Serial.println();



  Serial.begin(115200);
  pinMode(2, OUTPUT);
  digitalWrite(2, LOW);  // ssid not connect
  pinMode(5, OUTPUT);
  digitalWrite(5, HIGH);

  pinMode(16,INPUT);


  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  
  Serial.println("Starting UDP");
  udp.begin(localPort);
  Serial.print("Local port: ");
  Serial.println(udp.localPort());

  //Get package from NTP
  while (force_update == 1) {
    if (ip >= 5) ip = 0;
    timeServer.fromString(IP_of_Server[ip]);
    Serial.println(timeServer);
    ip += 1;
    NTP_get();
  }

  delay(100);



  hh = (epoch % 86400L) / 3600;
  mm = (epoch % 3600) / 60;
  ss = (epoch % 60);


  


  ts = ts1 = ts2 = ts3 = ts4 = millis();
  digitalWrite(2, HIGH);  //SSID connect ready

}

void loop() {

int devices=lc.getDeviceCount();

    // New temperature readings
    sensors.requestTemperatures();
    sensors2.requestTemperatures();  
    // Temperature in Celsius degrees
    temp = sensors.getTempCByIndex(0);
    temp2 = sensors2.getTempCByIndex(0);
    // Temperature in Fahrenheit degrees
    //temp = sensors.getTempFByIndex(0);

float temperature = sensors.getTempCByIndex(0);
int temp=sensors.getTempCByIndex(0);
  int unit=temp%10 +0.00;  // CALIBRATION + or - value here 
  int tens=temp/10;
  float rem=temperature-temp;
  int temp1=rem*100;
  int tens1=temp1/10;
  int unit1=temp1%10;
  lc.setDigit(1,3,tens,false);
  lc.setDigit(1,2,unit,true);
  lc.setDigit(1,1,tens1,false);
  lc.setChar(1,0,'c',false);

  float humidity = sensors2.getTempCByIndex(0); // NOT actually humitiy but actually temp - the only way I know how to make it work!!
  int temp2=sensors2.getTempCByIndex(0);
  
   unit=temp2%10 -0.0;  // CALIBRATION + or - value here 
   tens=temp2/10;
   rem=humidity-temp2;
   temp1=rem*100;
   tens1=temp1/10;
   unit1=temp1%10;
  lc.setDigit(1,7,tens,false); // note the 0 at the start. this is for the 1st max7219 display
  lc.setDigit(1,6,unit,true);
  lc.setDigit(1,5,tens1,false);
  lc.setChar(1,4,'c',false);

 






if ((digitalRead(16) == 1 ))
{
  hh =((epoch % 86400L) / 3600) +1;
}






  ts = millis();

  if (WiFi.status() == WL_CONNECTED) {

    /////////////////////////check time every 1 Hr.////////////////////////////////
    if ((WiFi.status() == WL_CONNECTED) && (ts - ts3 >= 3600000) && (force_update == 0)) {
      NTP_get();
      ts3 = millis();
    }

  }

  if ( ts - ts1 >= 1000 ) {

    epoch++; //Add a second

    hh = (epoch % 86400L) / 3600;
    mm = (epoch % 3600) / 60;
    ss = (epoch % 60);



    ts1 += 1000; // increment counter by 1 every 1sec

  }

  if ( ts - ts4 >= 500 ) {

    //display.dotShow(showdot = !showdot);
    ts4 = millis();

  }

  if ( ts - ts2 >= 5 ) {

  lc.setDigit(0,0,ss%10,false);
  lc.setDigit(0,1,ss/10,false);
  lc.setDigit(0,3,mm%10,false);  
  lc.setDigit(0,4,mm/10,false);
  lc.setDigit(0,6,hh%10,false);
  lc.setDigit(0,7,hh/10,false);

  }
  

  }
  1. You are measuring and displaying temperature on every iteration of loop
  2. You never set ts2 so you display the time on every iteration of loop (not every 5ms)

My guess is there is a delay in sensor library. Write a simple program to test it:
Print millis() start value to serial
Measure temperatures
Print millis() stop value to serial

reading onewire-sensors needs 700 to 800 milliseconds.
So if you want to keep your software RTC precise use a timer-interrupt or increase the timing-interval to a vlaue that is bigger than the time it needs to run down all the code in your main-loop (2 seconds)

best regards Stefan

I found three delays in your code, try opening it in IDE and use Ctl F to search for the word delay.

StefanL38:
reading onewire-sensors needs 700 to 800 milliseconds.

That is correct. Also the most popular one wire library uses blocking code that freezes the program for that period of time. There is a non-blocking sensor library (which I can't point to because it's been years since I used it).

aarg:
That is correct. Also the most popular one wire library uses blocking code that freezes the program for that period of time. There is a non-blocking sensor library (which I can't point to because it's been years since I used it).

Hi aarg,
very interesting. I did a "gearch" (short for google-search) immediately.
Can you confirm that it is this one

best regards Stefan

This one:

/*
 * DHT11, DHT21, and DHT22 non-blocking library.
 * Based on Adafruit Industries' DHT driver library.
 *
 * (C) 2015 Ole Wolf <wolf@blazingangles.com>
 *

I got it from Github, that’s all I know…

One way to keep from falling behind is to change:

  if ( ts - ts1 >= 1000 ) {

to:

  while ( ts - ts1 >= 1000 ) {

That way it can catch up if it has fallen behind more than one second. With the 'if' it will only catch up by 1 second per loop, no matter how far behind it has gotten.