hallo,
ich bräuchte mal kurz Hilfe beim Erstellen einer Hilfs-Lib.
Ich habe folgenden Code, der so funktioniert wie er ist; ich würde aber gern den ntp-Teil in eine Hilfs-Lib verpacken (udptools.h im Unterverzeichnis udptools vom libraries-Ordner)


Code:
/*  Beispiel 
 *  "WLAN CLient mit OLED/Seriell Ausgabe"
 *  Ref.: http://www.instructables.com/id/Quick-Start-to-Nodemcu-ESP8266-on-Arduino-IDE/ 
 *  
 */

#include <SSD1306.h>
// Initialisiert das OLED Display 
SSD1306  display(0x3c, D4, D5);



#include <ESP8266WiFi.h>
// WLAN Router 
const char* ssid = "WLANssid";
const char* password = "WLANpassword";

IPAddress ip(192,168,2,117);     //Feste IP des neuen Servers, frei wählbar
IPAddress gateway(192,168,2,1);  //Gatway (IP Router eintragen)
IPAddress subnet(255,255,255,0); //Subnet Maske eintragen

WiFiServer   server(80);


#include <TimeLib.h> 
time_t prevDisplay = 0; 
String  timestr = "00:00:00" ;
String  datestr = "01.01.1990";


// NTP Servers:
IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov
// IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov
// IPAddress timeServer(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov

const int timeZone = 0;     // auto mode vian utp (CEST)
//const int timeZone =  1;  // Central European Time
//const int timeZone = -5;  // Eastern Standard Time (USA)
//const int timeZone = -4;  // Eastern Daylight Time (USA)
//const int timeZone = -8;  // Pacific Standard Time (USA)
//const int timeZone = -7;  // Pacific Daylight Time (USA)


#include <WiFiUdp.h>
#include <Timezone.h>
WiFiUDP Udp;
unsigned int localPort = 8888;  // local port to listen for UDP packets

//Timezone
//Central European Time (Frankfurt, Paris)
TimeChangeRule CEST = { "CEST", Last, Sun, Mar, 2, 120 };     //Central European Summer Time
TimeChangeRule CET = { "CET ", Last, Sun, Oct, 3, 60 };       //Central European Standard Time
Timezone CE(CEST, CET);
TimeChangeRule *tcr;        //pointer to the time change rule, use to get the TZ abbrev
time_t utc, local;



#include <DHT.h>
 
//Definitionen fuer DHT11
#define   DHT_TYPE  DHT11   // Sensortyp definieren DHT11 
const int DHT_PIN = D2;     // Datenleitung des Sensors an GPIO4=D2 des iot Bricks  <<<< GEÄNDERT !!! <<<<
char tempc[20];
char humid[20]; 
DHT dht(DHT_PIN, DHT_TYPE); // Variable vom Typ DHT definieren



int   led7 = D7; // GPIO13=D7
int   led8 = D8; // GPIO15=D8




void dashboard(int mode) {
  if(mode==1) {
       display.clear();
       
       String cx_oled = "WiFi connected: " + (String)WiFi.RSSI() + " dBm";
       display.drawString( 0, 0, cx_oled );    
       String gw_oled= "Gateway: " + (String)WiFi.gatewayIP()[0] + "." + (String)WiFi.gatewayIP()[1] 
                            + "."  + (String)WiFi.gatewayIP()[2] + "." + (String)WiFi.gatewayIP()[3];
       display.drawString(0,10, gw_oled);       
       // Print the IP address
       String lip_oled = "Svr: http://" + (String)WiFi.localIP()[0] + "." + (String)WiFi.localIP()[1] 
                             + "." + (String)WiFi.localIP()[2] + "." + (String)WiFi.localIP()[3] + "/";
       display.drawString( 0,20, lip_oled); 
       display.drawString( 0,40, timestr+"   "+datestr);   
       display.drawString( 0,50, tempc);  display.drawString(50,50, "Feuchte: "+(String)humid);         
       display.display();  
  }  
}



 
void setup() {
  int progress = 0;
  
  Serial.begin(115200);
  delay(10);

  display.init();
  if (digitalRead(D0)==LOW) { display.flipScreenVertically(); }
  display.setFont(ArialMT_Plain_10);
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.clear();
  display.drawString(0, 0, "OLED TEST OK");
  display.display();

  pinMode(D0, INPUT_PULLUP);
  pinMode(D1, INPUT_PULLUP);
  pinMode(D3, INPUT_PULLUP);
 
  pinMode(led7, OUTPUT);
  digitalWrite(led7, LOW);
  pinMode(led8, OUTPUT);
  digitalWrite(led8, LOW);
 
  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
 
  WiFi.begin(ssid, password);
  WiFi.config(ip, gateway, subnet);   // feste IP
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");       
    display.clear();
    display.drawString(5, 20, "WiFi connecting...");
    display.drawProgressBar(0, 32, 120, 10, progress);
    display.display();
    progress+=2;
  }
  display.drawString(5, 20, "WiFi connecting...");
  display.drawProgressBar(0, 32, 120, 10, 100);
  display.display();
  delay(500); 
  
  Serial.println("");  
  Serial.print("WiFi connected: ");
  Serial.println(WiFi.gatewayIP());
   
  // Start the server
  server.begin();
  Serial.println("Server started");
   
  // Print the IP address
  Serial.print("Use this URL to connect: ");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");

  // Start UDP
  Serial.println("Starting UDP");
  Udp.begin(localPort);
  Serial.print("Local port: ");
  Serial.println(Udp.localPort());
  Serial.println("waiting for sync");
 
  setSyncProvider(getNtpTime);
  
  dashboard(1); 
}


 
void loop() {
  static unsigned long tms=0, tndp=0;
  volatile static int valD7=-1, valD8=-1;
  
  // OLED update WiFi signal 
  if ( millis() - tms > 1000 ) {
     
     tms=millis();

     float t = dht.readTemperature();  //Temperatur auslesen (Celsius)
     delay(1);
     if (not(isnan(t)))
     {
        sprintDouble(tempc,t,2);  //Temperatur mit 2 Nachkommastellen in String konvertieren
        strcat(tempc," °C");      //String mit °C ergänzen
     }
     else
     {
        Serial.print("No Temperature Sensor. ");
     }
     delay(1);
     float h = dht.readHumidity();    //Feuchtigkeit auslesen (Prozent)
     delay(1);
     if (not(isnan(h)))
     {
        sprintDouble(humid,h,0);  //Feuchtigkeit ohne Nachkommastelle in String konvertieren
        strcat(humid," %");       //String mit %-Zeichen ergänzen
     }
     else
     {
        Serial.print("No Humidity Sensor. ");
     }
     Serial.println(tempc);     
     Serial.println(humid); 

     if ( millis() - tndp > 10000 ) {
        if (timeStatus() != timeNotSet) {
           local = CE.toLocal(now(), &tcr);
            
           if (now() != prevDisplay) { //update the display only if time has changed              
              prevDisplay = now();
              
              digitalClockDisplay();  
           }
        }   
     }
     Serial.println(timestr+"   "+datestr);
     
     dashboard(1);
  }

  

  
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  
   
  // Read the first line of the request
  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();
 
  // Match the request
  //valD7=LOW;
  if (request.indexOf("/LED7=ON") != -1)  { 
    digitalWrite(led7, HIGH);  
    valD7 = HIGH;
  }
  if (request.indexOf("/LED7=OFF") != -1)  {
    digitalWrite(led7, LOW);
    valD7 = LOW;
  }

  //valD8=LOW;
  if (request.indexOf("/LED8=ON") != -1)  {
    digitalWrite(led8, HIGH);
    valD8 = HIGH;
  }
  if (request.indexOf("/LED8=OFF") != -1)  {
    digitalWrite(led8, LOW);
    valD8 = LOW;
  }
 
 
  // Return the response


  
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println(""); //  do not forget this one
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");
  
  client.println("<head>");

  // autom. Aktualisierung alle 30 sec.
  client.println("<meta http-equiv=\"refresh\" content=\"30; URL=http://192.168.2.117\">");  
  // utf-8 für "°" Zeichen
  client.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"); 

  client.println("<title>Haus-Ueberwachung</title>");
  
  client.println("</head>"); 
  
  client.println("<body>");
  
  client.println("<h1> HaWe Haus-Ueberwachung </h1>");

  client.println("<h2>"+timestr+"   "+datestr+"</h2>");
  
  client.println("<br><br>");
  
  client.print("Led D7 is now: "); 
  if(valD7 == HIGH) { client.print("On    "); } 
  else {  client.print("Off    ");  }
  
  client.println("<a href=\" /LED7=ON\"\"><button>Turn On </button></a>");
  client.println("<a href=\" /LED7=OFF\"\"><button>Turn Off </button></a><br />");  
  
  client.println("<br><br>");
  
  client.print("Led D8 is now: "); 
  if(valD8 == HIGH) { client.print("On    "); } 
  else {  client.print("Off    ");  }
  client.println("<a href=\" /LED8=ON\"\"><button>Turn On </button></a>");
  client.println("<a href=\" /LED8=OFF\"\"><button>Turn Off </button></a><br />"); 

  client.println("<br><br>");
   
  client.println("<h2>Temperat.: "+(String)tempc+"</h2>");
  client.println("<h2>Feuchtigk.: "+(String)humid+"</h2>");
  
  client.println("<body>");
  
  client.println("</html>");
 
  delay(1);
  Serial.println("Client disonnected");
  Serial.println("");
 
}






 
void sprintDouble( char *str, double val, byte precision)
{
  char st2[16];
  unsigned long frac;
  unsigned long mult = 1;
  int mant= int(val);
  byte padding = precision -1;
  byte sgn=0;
 
  sprintf(str,"");
  if (val < 0)  sprintf(str,"-");
  mant=abs(mant);
  sprintf(st2,"%d",mant); //prints the int part
  strcat(str,st2); 
 
  if( precision > 0) {
    strcat(str,".");
 
    while(precision--)
      mult *=10;
 
    if (val >= 0)
      frac = (val - int(val)) * mult;
    else
      frac = (int(val)- val ) * mult;
    unsigned long frac1 = frac;
    int cnt=precision;
    // while( frac1 /= 10 )
    while( frac1 = frac1 / 10 & cnt--  ) 
      padding--;
    while(  padding--)  strcat(str,"0");
    sprintf(st2,"%ld",frac);
 
    strcat(str,st2);
  }
}



void digitalClockDisplay(){
  char buf[10];
  
  // digital clock display of the time
  timestr ="";
  sprintf(buf, "%02d:", (int)hour(local));
  timestr+=buf;
  //Serial.print(hour());
  sprintf(buf, "%02d:", (int)minute(local));
  timestr+=buf;
  //printDigits(minute());
  //Serial.print(minute());
  sprintf(buf, "%02d", (int)minute(local));  
  //printDigits(second());
  sprintf(buf, "%02d", (int)second(local));
  timestr+=buf;
  //Serial.println(timestr);

  datestr="";
  sprintf(buf, "%02d.", (int)day(local));
  datestr+=buf;
  //Serial.print(day());
  //Serial.print(".");
  sprintf(buf, "%02d.", (int)month(local));
  datestr+=buf;
  //Serial.print(month());
  //Serial.print(".");
  sprintf(buf, "%4d", (int)year(local));
  datestr+=buf;
  //Serial.print(year()); 
  //Serial.println(); 
  //Serial.println(timestr+"   "+datestr);
  //Serial.println(); 
  
}





/*-------- 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("Receive NTP Response");
      Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
      unsigned long secsSince1900;
      // convert four bytes starting at location 40 to a long integer
      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      utc = secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;  // timezone=0 for auto sync (CEST)
      return utc;
    }
  }
  Serial.println("No NTP Response :-(");
  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();
}

Ich habe versucht, den unteren Teil (ab Sektion "/*-------- NTP code ----------*/") in diese Lib zu verschieben, samt eigener #includes, dann klappt aber nichts mehr.
Die Fehlermeldungen vom Arduino-Compiler meldet noch nicht mal einen "richtigen" Fehler, nur einen
"exit status 1
Fehler beim Kompilieren für das Board NodeMCU 1.0 (ESP-12E Module)."
- welchen Teil muss ich wieder in das Hauptfile verschieben oder doppelt aufführen oder komplett zurückverschieben?


Code:
// NTP Servers:
IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov
// IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov
// IPAddress timeServer(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov

const int timeZone = 0;     // auto mode (CEST)
//const int timeZone =  1;  // Central European Time
//const int timeZone = -5;  // Eastern Standard Time (USA)
//const int timeZone = -4;  // Eastern Daylight Time (USA)
//const int timeZone = -8;  // Pacific Standard Time (USA)
//const int timeZone = -7;  // Pacific Daylight Time (USA)


#include <WiFiUdp.h>
#include <Timezone.h>
WiFiUDP Udp;
unsigned int localPort = 8888;  // local port to listen for UDP packets

//Timezone
//Central European Time (Frankfurt, Paris)
TimeChangeRule CEST = { "CEST", Last, Sun, Mar, 2, 120 };     //Central European Summer Time
TimeChangeRule CET = { "CET ", Last, Sun, Oct, 3, 60 };       //Central European Standard Time
Timezone CE(CEST, CET);
TimeChangeRule *tcr;        //pointer to the time change rule, use to get the TZ abbrev
time_t utc, local;



/*-------- 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("Receive NTP Response");
      Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
      unsigned long secsSince1900;
      // convert four bytes starting at location 40 to a long integer
      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      utc = secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;  // timezone=0 for auto sync (CEST)
      return utc;
    }
  }
  Serial.println("No NTP Response :-(");
  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();
}