Problem using static ip

Hello everybody

I'm having a problem that I can't figure out why.

I have this sketch here for ESP32 that I connect to the network with a static IP and call an NTPC library (GitHub - arduino-libraries/NTPClient: Connect to a NTP server) to get the time and it works very well:

// Load Wi-Fi library
#include <WiFi.h>
#include <ESP32Time.h>
#include <NTPClient.h>
#include <Timestamps.h>

// Replace with your network credentials
const char* ssid     = "WIFI_T";
const char* password = "redacted";

// Set web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// Set your Static IP address
IPAddress local_IP(192, 168, 1, 184);
// Set your Gateway IP address
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 0, 0);
IPAddress primaryDNS(8, 8, 8, 8);   //optional
IPAddress secondaryDNS(8, 8, 4, 4); //optional


WiFiClient wifiClient;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
ESP32Time rtc;


void setup() {
  Serial.begin(115200);
  
  // Configures static IP address
  if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
    Serial.println("STA Failed to configure");
  }
  
  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("Conectado");
    NTPCIniciar();
    Serial.println("Define DATA");
    defineData();
  }
  server.begin();
}

void loop(){

}
void NTPCIniciar()
{
  //INICIALIZA O NTPC CLIENT PARA PEGAR DATA E HORA
  timeClient.begin();
  // Set offset time in seconds to adjust for your timezone, for example:
  // GMT +1 = 3600
  // GMT +8 = 28800
  // GMT -1 = -3600
  // GMT 0 = 0
  timeClient.setTimeOffset(-10800 /*CONFIGURADO PARA O FUSO HORÁRIO NO BRASIL*/);
}

void defineData() {
  char ano2[5];
  char mes2[3];
  char dia2[3];
  char hora2[3];
  char minuto2[3];
  char segundo2[3];
  char dataHora2[21];
  int anoInt2;
  int mesInt2;
  int diaInt2;
  int horaInt2;
  int minInt2;
  int segInt2;
  String formattedDate;
  String dayStamp;
  String timeStamp;
  if (!timeClient.update()) {
    Serial.println("Update");
    timeClient.forceUpdate();
  }
  // The formattedDate comes with the following format:
  // 2018-05-28T16:00:13Z
  // We need to extract date and time
  Serial.println("TIMESTAMP");
  unsigned long timeStamp2 = timeClient.getEpochTime();
  Serial.println(timeStamp2);
  formattedDate = timeClient.getFormattedDate();
  Serial.println(formattedDate);

  // Extract date
  int splitT = formattedDate.indexOf("T");
  dayStamp = formattedDate.substring(0, splitT);
  Serial.println("DATE: ");
  Serial.println(dayStamp);

  // Extract time
  timeStamp = formattedDate.substring(splitT + 1, formattedDate.length() - 1);
  Serial.println("HOUR: ");
  Serial.println(timeStamp);
  formattedDate.toCharArray(dataHora2, sizeof(dataHora2));
  for (int i = 0; i < 4; i++)
  {
    ano2[i] = dataHora2[i];
  }
  for (int i = 0; i < 2; i++)
  {
    mes2[i] = dataHora2[i + 5];
    dia2[i] = dataHora2[i + 8];
    hora2[i] = dataHora2[i + 11];
    minuto2[i] = dataHora2[i + 14];
    segundo2[i] = dataHora2[i + 17];
  }
  anoInt2 = atol(ano2);
  mesInt2 = atol(mes2);
  diaInt2 = atol(dia2);
  horaInt2 = atol(hora2);
  minInt2 = atol(minuto2);
  segInt2 = atol(segundo2);

  rtc.setTime(segInt2, minInt2, horaInt2, diaInt2, mesInt2, anoInt2);
}

Output:

14:35:56.586 -> WiFi connected.
14:35:56.586 -> IP address:
14:35:56.586 -> 192.168.1.184
14:35:56.586 -> Conectado
14:35:56.586 -> Define DATA
14:35:56.865 -> TIMESTAMP
14:35:56.865 -> 1671456956
14:35:56.865 -> 2022-12-19T13:35:56Z
14:35:56.865 -> DATE:
14:35:56.865 -> 2022-12-19
14:35:56.865 -> HOUR:
14:35:56.865 -> 13:35:56

However, I decided to put a Wifimanager library (GitHub - tzapu/WiFiManager: ESP8266 WiFi Connection manager with web captive portal) to facilitate the connection:

// Load Wi-Fi library
#include <WiFi.h>
#include <ESP32Time.h>
#include <NTPClient.h>
#include <Timestamps.h>
#include <ESP_WiFiManager.h>
#include <EEPROM.h>
#include <WebServer.h>

// Set web server port number to 80
WebServer server(80);
// Variable to store the HTTP request
String header;
WiFiClient wifiClient;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
ESP32Time rtc;

#define PIN_LED       2
#define ESP_getChipId()   ((uint32_t)ESP.getEfuseMac())
// SSID and PW for Config Portal
String ssid = "ESP_" + String(ESP_getChipId(), HEX);
const char* password = "your_password";
// SSID and PW for your Router
String Router_SSID;
String Router_Pass;
// Indicates whether ESP has WiFi credentials saved from previous session
bool initialConfig = false;
// Use true for dynamic DHCP IP, false to use static IP and  you have to change the IP accordingly to your network
#define USE_DHCP_IP     false
IPAddress stationIP   = IPAddress(192, 168, 1, 184 /*0, 0, 0, 0*/);
IPAddress gatewayIP   = IPAddress(192, 168, 1, 1 /*192, 168, 2, 1*/);
IPAddress netMask     = IPAddress(255, 255, 0, 0);
IPAddress dns1IP      = IPAddress(8, 8, 8, 8);
IPAddress dns2IP      = IPAddress(8, 8, 4, 4);

bool shouldSaveConfig = false;

void heartBeatPrint(void)
{
  static int num = 1;

  if (WiFi.status() == WL_CONNECTED)
    Serial.print("H");        // H means connected to WiFi
  else
    Serial.print("F");        // F means not connected to WiFi

  if (num == 80)
  {
    Serial.println();
    num = 1;
  }
  else if (num++ % 10 == 0)
  {
    Serial.print(" ");
  }
}

void check_status() {
  // is configuration portal requested?
  Serial.println("\nConfiguration portal requested.");
  digitalWrite(PIN_LED, HIGH); // turn the LED on by making the voltage LOW to tell us we are in configuration mode.

  //Local intialization. Once its business is done, there is no need to keep it around
  ESP_WiFiManager ESP_wifiManager;

  ESP_wifiManager.setSaveConfigCallback(saveConfigCallback);

  //Check if there is stored WiFi router/password credentials.
  //If not found, device will remain in configuration mode until switched off via webserver.
  Serial.print("Opening configuration portal. ");
  Router_SSID = ESP_wifiManager.WiFi_SSID();
  if (Router_SSID != "")
  {
    ESP_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout.
    Serial.println("Got stored Credentials. Timeout 120s");
  }
  else
    Serial.println("No stored Credentials. No timeout");

  ESP_wifiManager.setMinimumSignalQuality(-1);
  // Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
  ESP_wifiManager.setSTAStaticIPConfig(stationIP, gatewayIP, netMask, dns1IP, dns2IP);

  //it starts an access point
  //and goes into a blocking loop awaiting configuration
  if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password))
  {
    Serial.println("Not connected to WiFi but continuing anyway.");
  }
  else
  {
    //if you get here you have connected to the WiFi
    Serial.println("connected...yeey :)");
    Serial.print("Local IP: ");
    Serial.println(WiFi.localIP());
  }


  digitalWrite(PIN_LED, LOW); // Turn led off as we are not in configuration mode.

  static ulong checkstatus_timeout = 0;
#define HEARTBEAT_INTERVAL    10000L
  // Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
  if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0))
  {
    heartBeatPrint();
    checkstatus_timeout = millis() + HEARTBEAT_INTERVAL;
  }
  Serial.println("Reiniciando");
  ESP.restart();
}

void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}
void connectWifi() {
  Serial.println("\nStarting ConfigOnSwitch on " + String(ARDUINO_BOARD));
  unsigned long startedAt = millis();
  //Local intialization. Once its business is done, there is no need to keep it around
  // Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
  //ESP_WiFiManager ESP_wifiManager;
  // Use this to personalize DHCP hostname (RFC952 conformed)
  ESP_WiFiManager ESP_wifiManager("ConfigOnSwitch");
  ESP_wifiManager.setDebugOutput(true);
  // Use only to erase stored WiFi Credentials
  //resetSettings();
  //ESP_wifiManager.resetSettings();

  //set custom ip for portal
  //ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 100, 1), IPAddress(192, 168, 100, 1), IPAddress(255, 255, 255, 0));
  ESP_wifiManager.setMinimumSignalQuality(-1);
  // We can't use WiFi.SSID() in ESP32as it's only valid after connected.
  // SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
  // Have to create a new function to store in EEPROM/SPIFFS for this purpose
  Router_SSID = ESP_wifiManager.WiFi_SSID();
  Router_Pass = ESP_wifiManager.WiFi_Pass();
  //Remove this line if you do not want to see WiFi password printed
  Serial.println("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
  // SSID to uppercase
  ssid.toUpperCase();
  if (Router_SSID == "")
  {
    Serial.println("Open Config Portal without Timeout: No stored Credentials.");

    digitalWrite(PIN_LED, HIGH); // Turn led on as we are in configuration mode.

    //it starts an access point
    //and goes into a blocking loop awaiting configuration
    if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password))
      Serial.println("Not connected to WiFi but continuing anyway.");
    else
      Serial.println("WiFi connected...yeey :)");
  }

  digitalWrite(PIN_LED, LOW); // Turn led off as we are not in configuration mode.

#define WIFI_CONNECT_TIMEOUT        30000L
#define WHILE_LOOP_DELAY            200L
#define WHILE_LOOP_STEPS            (WIFI_CONNECT_TIMEOUT / ( 3 * WHILE_LOOP_DELAY ))

  startedAt = millis();

  while ( (WiFi.status() != WL_CONNECTED) && (millis() - startedAt < WIFI_CONNECT_TIMEOUT ) )
  {
    WiFi.mode(WIFI_STA);
    WiFi.persistent (true);

    // We start by connecting to a WiFi network

    Serial.print("Connecting to ");
    Serial.println(Router_SSID);

    WiFi.config(stationIP, gatewayIP, netMask);
    //WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);

    WiFi.begin(Router_SSID.c_str(), Router_Pass.c_str());

    int i = 0;
    while ((!WiFi.status() || WiFi.status() >= WL_DISCONNECTED) && i++ < WHILE_LOOP_STEPS)
    {
      delay(WHILE_LOOP_DELAY);
    }
  }

  Serial.print("After waiting ");
  Serial.print((millis() - startedAt) / 1000);
  Serial.println(" secs more in setup(), connection result is ");

  if (WiFi.status() == WL_CONNECTED)
  {
    Serial.print("connected. Local IP: ");
    Serial.println(WiFi.localIP());

  }
}

void streamTimeoutCallback(bool timeout)
{
  if (timeout) {
    //Stream timeout occurred
    Serial.println("Stream timeout, resume streaming...");
  }
}


void setup() {
  Serial.begin(115200);
  if (digitalRead(0) == LOW)
  {
    Serial.println("Modo AP...");
    check_status();
  }
  connectWifi();
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("WiFi connected.");
    NTPCIniciar();
    Serial.println("Define DATA");
    defineData();
  }
  server.begin();
}

void loop(){

}
void NTPCIniciar()
{
  //INICIALIZA O NTPC CLIENT PARA PEGAR DATA E HORA
  timeClient.begin();
  // Set offset time in seconds to adjust for your timezone, for example:
  // GMT +1 = 3600
  // GMT +8 = 28800
  // GMT -1 = -3600
  // GMT 0 = 0
  timeClient.setTimeOffset(-10800 /*CONFIGURADO PARA O FUSO HORÁRIO NO BRASIL*/);
}

void defineData() {
  char ano2[5];
  char mes2[3];
  char dia2[3];
  char hora2[3];
  char minuto2[3];
  char segundo2[3];
  char dataHora2[21];
  int anoInt2;
  int mesInt2;
  int diaInt2;
  int horaInt2;
  int minInt2;
  int segInt2;
  String formattedDate;
  String dayStamp;
  String timeStamp;
  if (!timeClient.update()) {
    Serial.println("Update");
    timeClient.forceUpdate();
  }
  // The formattedDate comes with the following format:
  // 2018-05-28T16:00:13Z
  // We need to extract date and time
  Serial.println("TIMESTAMP");
  unsigned long timeStamp2 = timeClient.getEpochTime();
  Serial.println(timeStamp2);
  formattedDate = timeClient.getFormattedDate();
  Serial.println(formattedDate);

  // Extract date
  int splitT = formattedDate.indexOf("T");
  dayStamp = formattedDate.substring(0, splitT);
  Serial.println("DATE: ");
  Serial.println(dayStamp);

  // Extract time
  timeStamp = formattedDate.substring(splitT + 1, formattedDate.length() - 1);
  Serial.println("HOUR: ");
  Serial.println(timeStamp);
  formattedDate.toCharArray(dataHora2, sizeof(dataHora2));
  for (int i = 0; i < 4; i++)
  {
    ano2[i] = dataHora2[i];
  }
  for (int i = 0; i < 2; i++)
  {
    mes2[i] = dataHora2[i + 5];
    dia2[i] = dataHora2[i + 8];
    hora2[i] = dataHora2[i + 11];
    minuto2[i] = dataHora2[i + 14];
    segundo2[i] = dataHora2[i + 17];
  }
  anoInt2 = atol(ano2);
  mesInt2 = atol(mes2);
  diaInt2 = atol(dia2);
  horaInt2 = atol(hora2);
  minInt2 = atol(minuto2);
  segInt2 = atol(segundo2);

  rtc.setTime(segInt2, minInt2, horaInt2, diaInt2, mesInt2, anoInt2);
}


When I put it, setting exactly the same IP and network values, it generates this output:

14:35:02.332 -> After waiting 2 secs more in setup(), connection result is 
14:35:02.332 -> connected. Local IP: 192.168.1.184
14:35:02.332 -> WiFi connected.
14:35:02.332 -> Define DATA
14:35:03.356 -> Update
14:35:04.378 -> TIMESTAMP
14:35:04.378 -> 4294956500
14:35:04.378 -> 2106-02-07T03:28:20Z
14:35:04.378 -> DATE: 
14:35:04.378 -> 2106-02-07
14:35:04.378 -> HOUR: 
14:35:04.378 -> 03:28:20

Dates change completely, it seems NTPC can't get the updated date.

Would anyone know how to help me with this?
I can't find what it could be.

Thank you!

I can use my Home-WiFi-router as the NTP-server
and this code to synchronise through the time-information that is delivered with the WiFi anyway.
not a full sketch but the important parts

#include <time.h>                   // time() ctime()
time_t now;                         // this is the epoch
tm myTimeInfo;                      // the structure tm holds time information in a more convient way

const char* ntpServer = "fritz.box";
const long  gmtOffset_sec = 0;
const int   daylightOffset_sec = 7200;

void synchroniseWith_NTP_Time() {
  Serial.print("configTime uses ntpServer ");
  Serial.println(ntpServer);
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  Serial.print("synchronising time");
  
  while (myTimeInfo.tm_year + 1900 < 2000 ) {
    time(&now);                       // read the current time
    localtime_r(&now, &myTimeInfo);
    BlinkHeartBeatLED(OnBoard_LED, 100);
    delay(100);
    Serial.print(".");
  }
  Serial.print("\n time synchronsized \n");
  showTime();    
}

void showTime() {
  time(&now);                       // read the current time
  localtime_r(&now, &myTimeInfo);           // update the structure tm with the current time
  Serial.print("year:");
  Serial.print(myTimeInfo.tm_year + 1900);  // years since 1900
  Serial.print("\tmonth:");
  Serial.print(myTimeInfo.tm_mon + 1);      // January = 0 (!)
  Serial.print("\tday:");
  Serial.print(myTimeInfo.tm_mday);         // day of month
  Serial.print("\thour:");
  Serial.print(myTimeInfo.tm_hour);         // hours since midnight  0-23
  Serial.print("\tmin:");
  Serial.print(myTimeInfo.tm_min);          // minutes after the hour  0-59
  Serial.print("\tsec:");
  Serial.print(myTimeInfo.tm_sec);          // seconds after the minute  0-61*
  Serial.print("\twday");
  Serial.print(myTimeInfo.tm_wday);         // days since Sunday 0-6
  if (myTimeInfo.tm_isdst == 1)             // Daylight Saving Time flag
    Serial.print("\tDST");
  else
    Serial.print("\tstandard");
    
  Serial.println();
}

best regards Stefan

1 Like

And here a complete demo-code

#include <WiFi.h>

unsigned long MyTestTimer = 0;                   // variables MUST be of type unsigned long
const byte    OnBoard_LED = 2;


const char *ssid     = "";
const char *password = "";

// a lot of home-wlan-routers can be used as a NTP-server too
const char* ntpServer = "fritz.box"; 
const long  gmtOffset_sec = 0;
const int   daylightOffset_sec = 7200;

#include <time.h>                   // time() ctime()
time_t now;                         // this is the epoch
tm myTimeInfo;                      // the structure tm holds time information in a more convient way

void showTime() {
  time(&now);                       // read the current time
  localtime_r(&now, &myTimeInfo);           // update the structure tm with the current time
  Serial.print("year:");
  Serial.print(myTimeInfo.tm_year + 1900);  // years since 1900
  Serial.print("\tmonth:");
  Serial.print(myTimeInfo.tm_mon + 1);      // January = 0 (!)
  Serial.print("\tday:");
  Serial.print(myTimeInfo.tm_mday);         // day of month
  Serial.print("\thour:");
  Serial.print(myTimeInfo.tm_hour);         // hours since midnight  0-23
  Serial.print("\tmin:");
  Serial.print(myTimeInfo.tm_min);          // minutes after the hour  0-59
  Serial.print("\tsec:");
  Serial.print(myTimeInfo.tm_sec);          // seconds after the minute  0-61*
  Serial.print("\twday");
  Serial.print(myTimeInfo.tm_wday);         // days since Sunday 0-6
  if (myTimeInfo.tm_isdst == 1)             // Daylight Saving Time flag
    Serial.print("\tDST");
  else
    Serial.print("\tstandard");
    
  Serial.println();
}

void connectToWifi() {
  Serial.print("Connecting to "); 
  Serial.println(ssid);

  WiFi.persistent(false);
  WiFi.mode(WIFI_STA);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    BlinkHeartBeatLED(OnBoard_LED, 333);
    delay(332);
    Serial.print(".");
  }
  Serial.print("\n connected.");
  Serial.println(WiFi.localIP() );

}

void synchroniseWith_NTP_Time() {
  Serial.print("configTime uses ntpServer ");
  Serial.println(ntpServer);
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  Serial.print("synchronising time");
  
  while (myTimeInfo.tm_year + 1900 < 2000 ) {
    time(&now);                       // read the current time
    localtime_r(&now, &myTimeInfo);
    BlinkHeartBeatLED(OnBoard_LED, 100);
    delay(100);
    Serial.print(".");
  }
  Serial.print("\n time synchronsized \n");
  showTime();    
}


void PrintFileNameDateTime() {
  Serial.println( F("Code running comes from file ") );
  Serial.println(__FILE__);
  Serial.print( F("  compiled ") );
  Serial.print(__DATE__);
  Serial.print( F(" ") );
  Serial.println(__TIME__);  
}

boolean TimePeriodIsOver (unsigned long &periodStartTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();  
  if ( currentMillis - periodStartTime >= TimePeriod )
  {
    periodStartTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  } 
  else return false;            // not expired
}


void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);
  
  if ( TimePeriodIsOver(MyBlinkTimer,BlinkPeriod) ) {
    digitalWrite(IO_Pin,!digitalRead(IO_Pin) ); 
  }
}


void setup() {
  Serial.begin(115200);
  Serial.println("\n Setup-Start \n");
  PrintFileNameDateTime();
  
  connectToWifi();
  synchroniseWith_NTP_Time();
}

void loop() {
  BlinkHeartBeatLED(OnBoard_LED,100);

  if ( TimePeriodIsOver(MyTestTimer,1000) ) {
    showTime();    
  }  
}

best regards Stefan

1 Like

Apparently if I change in connectWifi() this:

 WiFi.config(stationIP, gatewayIP, netMask);
 //WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);

for that:

 //WiFi.config(stationIP, gatewayIP, netMask);
 WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);

It works.
I don't really know why, but it works.

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